目录
工具:RadAsm,010 Editor,LordPE。
源码 .386
.model flat,stdcall
option casemap:none
include msvcrt.inc
includelib msvcrt.lib
.data
szText db 'welcome', 0ah, 00h
szPause db 'pause', 00h
.code
main:
push offset szText
call crt_printf
add esp, 4
push offset szPause
call crt_system
add esp, 4
ret
end main
end
输出一句“welcome”,然后执行system(pause)
。
运行
然后。用010Editor打开,开启重定位。
关于这两个属性,文件头中的IMAGE_FILE_RELOCS_STRIPPED
是去除重定位信息的意思,可选头中的IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
是动态基址的意思,前者置0,不去除信息;后者置1,开启动态基址。
再次用OD加载。
可以看到,加载基址变了,但是两个字符串还有两个函数的地址还是没有变,导致程序不能运行。下面就要添加重定位信息,让它们一块改变。
添加重定位信息要分清楚区段和数据目录表的关系。添加重定位信息要修改的是数据目录表下标为5那一项,不是添加.reloc
区段(而且添加了也没法加载)。区段是规定了属性,真正用来找到重定位信息的是数据目录表。
在PE中找个位置,我选择了700H,然后计算它的RVA。
根据LordPE,700H位于rdata段,RVA==700h-600h+2000h==2100h
。
我们有两个字符串和两个函数需要重定位,也就是4个WORD
,加上两个DWORD
,大小SizeOfBlock == 10H
。数据目录表中的size还要算上结尾两个0,所以是12h.
//
// Based relocation format.
//
typedef struct _IMAGE_BASE_RELOCATION {
DWORD VirtualAddress; //RVA
DWORD SizeOfBlock;
// WORD TypeOffset[1]; //end with [00 00]
} IMAGE_BASE_RELOCATION;
struct {
WORD Offset:12; //lower 12 bit relocation offset
WORD Type:4; //higher 4 bit relocation type value : Based relocation types above
}TypeOffset;
因为我们的程序是32位,所以重定位项的最高位Type
为IMAGE_REL_BASED_HIGHLOW==3
,64位的PE通常为IMAGE_REL_BASED_DIR64==A
。
根据第一张OD加载截图,VirualAddress==1000H
,4个偏移分别为001h, 007h, 00fh, 015h
。
这样,重定位信息就完成了。
00000700: 00 10 00 00 10 00 00 00 01 30 07 30 0F 30 15 30
再次用OD加载看一下。
4个位置的opcode都有了下划线,说明有重定位,运行也没有问题。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课