壹、前言
本文主要讲述如何通过新增区块来修改PE32+的二进制固件引导文件。
贰、相关知识
PE32+是PE文件的64位版本。PE文件就是指Windows里的DLL与EXE文件,PE的意思就是 Portable Executable,即可移植的执行体。PE文件总的来说是由DOS文件头、DOS加载模块、PE文件头、区段表与区段5部分构成。
DOS MZ Header
DOS文件头,亦称为DOS MZ文件头,大小为0x40h字节。它是一段以关键字MZ为开头的数据,偏移量0x 3Ch处包含着PE文件头的起始位置信息。
DOS Stub
DOS stub是以一段“This program cannot be runin DOS mode”为标志,当运行环境不匹配时则弹出这句话,对于WIN32位的操作系统来讲,存在的意义不大,完全可以删除。位于DOS头和PE头之间,大小为0xA0h字节。
PE Header(PE文件标志+标准PE头+PE扩展头)
PE header就是着重研究PE文件头,是一段以关键字“PE”为开头的数据。可以根据DOS MZ Header中0x3Ch偏移处两个字大小的数据定位到PE文件的位置。也可以根据PE头的标志“0x4550h”,对应点ASCII码为“PE00”来确定PE文件头的位置。
PE Header分为三部分:
-
PE标志“0x00004550”或ASCII码“PE00”,大小为0x04h个字节;
-
标准PE头,大小为0x14h字节,在PE头开始偏移为0x20h,大小为0x02h字节为整个PE头的大小;
-
PE扩展头,大小为0x00F0h-0x14h-0x04h。PE扩展头比标准PE头含有更多的信息。文件执行的入口地址,文件被系统装入内存后的默认基地址,以及磁盘和内存中对齐单位等信息均可以在此结构中找到。对结构中的某系数据进行改动可以会造成PE文件的加载或运行失败。
Section Table
PE头紧接着就是Section table,也即区段表,也称为节表,这是一段记录着整个文件中区段的大小与位置信息表。它是由很多的节表项组成,每个节表项纪录了PE中与某个特定的节有关的信息,如节的属性,节的大小,在文件内存中的起始位置等。节表后面就是各个节的内容。每个节表项大小为0x28h字节。
叁、修改过程
首先,在PE头偏移为0x06h处,大小为0x02h字节。将原始大小增加1,表示新增一个Section。如图所示:
其次,在文件末尾添加增加一个新的空间,并插入HelloWorld代码。记下插入位置和插入空间的大小。本文中两者的大小分别为0x14AAF0h,0x200h。如图所示:
同时,定位到相对PE头偏移0x50h,大小为0x04字节处,相应地改变SizeOfImage的大小。本实验中为增加0x200h。如图反色部分所示,由0x001AB000h改为0x001AB200h:
然后通过PE头的大小,定位到PE头结束的位置。已知每个节表项大小为0x28h字节和节表项数(区块数)就可以去顶Section头部的结束位置,而通常在Section头部结束到Section数据部分开始间会有一些空间,找到Section头部的最后然后加入一个新的头部。本实验中已知个节表项大小为0x28h字节和节表项数(区块数)为0x000Ah,所以Section头部的结束位置,也即新Section的插入位置为0x350h,伪造的新的Section头部如下所示:
对于新增加的区块RVA的确定方法如下所示:
-
确定最后一个区块的RVA和区块的大小SizeOfRawdata。由上图可知,最后一个区块RVA为0x001A9000h,SizeOfRawdata大小为0x00001C00h。
-
计算新增加区块的RVA。注意到Section对齐的数据是0x1000h,最后一个Section的边界是0x001A9000h+0x00001C00h=0x001AAC00h。则新增加的Section的RVA为0x001AB000h
接着修改PE头内的SizeOfCode(相对于PE头偏移0x1Ch处,占0x04字节),SizeOfInitialishedData(相对于PE头偏移0x20h处,占0x04字节)(可以不用修改的这里.)和SizeOfImage(相对于PE头偏移0x50h处,占0x04字节)三个字段,分别加上新增加区块的大小(在本实验中位0x200h)。如图所示:
最后将修改后的二进制固件引导文件替换原来的二进制文件并重启。
修改成功!
本文作者:whitecell-lab _D_D_
转载请保留作者与出处。
本文始发于微信公众号(WhiteCellClub):二进制科普系列之:如何修改固件引导文件
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论