资料:
struct DOSEXEHEAD_t // DOS 下 EXE 头文件格式
{
unsigned char Mark1; // LINK 签名 0x4D
unsigned char Mark2; // LINK 签名 0x5A
unsigned short VolumeInLastPage; // 见注1
unsigned short CountOfPage; // 见注1
unsigned short CountOfReallocItem; // 重定位表的项数
unsigned short SizeOfHeadInPara; // 以节为单位的 EXE 头大小
unsigned short min_para; // 程序下方所需最小节数
unsigned short max_para; // 程序下方所需最大节数
unsigned short Start_SS; // 入口点 SS, 见注2
unsigned short Start_SP; // 入口点 SP
unsigned short Reserved; // 保留,目前为 0x0000
unsigned short Start_IP; // 入口点 IP
unsigned short Start_CS; // 入口点 CS,见注2
unsigned short FirstReallocPtr; // 首重定位表项距头首部的字节数
};
对于debug版本的可执行文件,通过dump其debug信息,我们可以方便的得到其文件头信息,重定位表,符号表等等信息。
通过IDA我们可以看到模拟加载后对应指令处的线性地址等信息。
有了这些信息我们如何实施重定位表的修改呢?
1)通过IDA查看需要修改处的线性地址,比如1AFB:3E86 call sub_3267
再减去IDA加载起始地址(拖到文件起始处看最小地址,一般为0000:0000或1000:0000两种),例如此文件从1000:0000开始加载,则用1AFB:3E86 - 1000:0000 = 0AFB:3E86 ,这个地址就是我们要在可执行文件中查找的地址。
2)用winhex或者hexworkshop之类十六进制编辑软件,打开此可执行文件,搜索FB0A863E,为何地址变成这样再搜索?因为重定位表中是按照段地址:偏移地址形式存放的重定位地址信息,同时INTEL处理器是小端序处理器。
如果搜到多条匹配,则通过上面给出的DOS文件头信息,定位属于重定位表的那条。
3)抹除此信息。用十六进制编辑软件,将此重定位表信息删除,然后在重定位表末尾大片的0字节处添加对应长度的0字节(一项重定位表信息4个字节)。
4)修改文件头中重定位表項数。删除了几项重定位表,则减去几。比如此处删除一项,此处愿为2310,则修改为2210即可。
5) 这样便可修改1AFB:3E86 call sub_3267 对应处的字节内容。