本节内容
EXE格式的PE文件中,基址重定位表对运行没有影响,实际上将其删除后文件仍可正常运行,本节在于删除示例程序reloc.exe的.reloc节区并完成PE格式相关字段的修正使得删除后文件仍可正常运行。
(PS:基址重定位表对于DLL/SYS形式的可执行文件来说几乎是必须的,不可作为本节的实例文件)
正文
删除节区的步骤
1⃣️:NOP填充节区头IMAGE_SECTION_HEADER(使之无效,因此不会出现PE装载器装载时出现PE不合法的情况)
2⃣️:删除整个节区内容
3⃣️:修正节区数(节区头数量决定,由于NOP掉了一个因此-1),修正Image size(删除了节区的内容,注意节区大小对齐问题)
PS:目前不清楚步骤的看完后文估计能有很好的了解。
_IMAGE_SECTION_HEADER
节区头的结构体是_IMAGE_SECTION_HEADER
1 | typedef struct _IMAGE_SECTION_HEADER { |
文件在PEView中:
可见.reloc节区头信息起始地址(RVA)= 0x270到节区头结构体最后一个成员characteristic起始地址(RVA)为0x294,由于characteristic成员值占4byte,故节区头的大小是28(294-270+4)。
另外删除节区是在文件中删除以及修改文件的,因此需要计算出相应的信息在文件中的偏移,这个过程需要用到的是目标节区头中的Pointer to Raw data字段,记录的是节区起始文件偏移。这里是0xC000
NULL覆盖.reloc节区头信息
删除节区.reloc的内容
上文提到IMAGE_SECTION_HEADER中字段Pointer To Raw Data可知节区起始文件偏移是0xC000,这里由于节区.reloc是PE文件的最后一个节区,因此删除从此处开始到文件末的内容
工具也提示了会改变文件大小,因此后续需要做的工作是修改相应的字段保持PE格式的完整
修改NumberOfSections
1 | typedef struct _IMAGE_FILE_HEADER { |
需要修改的是==节区数 -1==, 即对应位置要修正5个节区为4个节区,下图在IMAGE_FILE_HEADER中的NumberOfSection字段在文件偏移为0xDE
完成节区数修改
修改SizeOfImage
删除节区内容后的PE文件会变小,需要修正PE文件中的相应字段,使得PE装载器在装载的过程中没有出现差错。
从上文提到的.reloc节区信息中得到该节区的vitual size为0xE40,但由于存在节区对齐的机制,相应的节区大小会做对齐处理,具体对齐格式在IMAGE_OPTIONAL_HEADER中有字段进行记录:
1 | typedef struct _IMAGE_OPTIONAL_HEADER { |
这也是为什么我们在看到节区信息时看到的vitual size是0xE40而Raw Size是0x1000的原因
故需要将==IMAGE_OPTIONAL_HEADER的size of image成员==的值减去 0x1000 进行修改,
该字段值在文件偏移是0x128修改前:
修改后:
将文件进行保存,看是否可以正常启动,可以则说明删除没有伤害到其他运行必要的数据(p s: .bak是修改前的,可以看到文件大小缩小了4KB,且程序可以正常运行,修改成功)