目标是在某个EXE代码节空白区手动添加代码弹框
通过DTDebug
或OD
找到当前电脑的MessageBoxA
函数地址:例如我之类的0x75789350
这里添加逻辑是,先CALL
该函数然后JMP
到OEP
地址
观察到CALL
指令的硬编码是E8
;JMP
指令的硬编码是E9
;但是指令后跟随的并不是直接的地址
xxxxxxxxxx
真正要跳转的地址 = E8这条指令的下一行地址 + X
观察到CALL
和JMP
操作数都是4字节地址,因此下一行地址应该是+5,所以得到以下公式
xxxxxxxxxx
X = 要跳转的地址 - (E8的地址 + 5)
另外CALL MessageBox
需要额外的4个参数,如下图硬编码是6A 00
现在思路已经明确,最终需要写入的字节如下(未知地址暂写为00)
xxxxxxxxxx
6A 00 6A 00 6A 00 6A 00 E8 00 00 00 00 E9 00 00 00 00
我的EXE现在的代码节信息如下
计算SizeOfRawData-VirtualSize
得到空白区大小8DE
显然可以成功写入
节的PointerToRawData
是0x1000
,所以在文件中,代码节从0x1A000
开始到0x1B000
结束。于是我们将上文的16个字节写在这里,选择1A730
并不是必须,其他地方也可以,只要在该区域内即可
对于其中的地址,需要计算的是内存中的地址而不是文件的地址,程序默认装入的基地址ImageBase
是0x00400000
,相加得到插入字节的内存偏移是0x0041A730
,在E9
处的偏移是0x0041A73D
通过公式真正要跳转的地址 = E8这条指令的下一行地址 + X
得到X
为7536EC13
于是CALL MessageBox
为E8 13 EC 36 75
PE工具找到程序开始执行的入口地址OEP
为0x000183D7
通过公式真正要跳转的地址 = E9这条指令的下一行地址 + X
得到
X = (0x00400000 + 0x000183D7) - (0X00400000 + 0x0001A742) = 0xFFFFDC95
于是JMP OEP
为E9 95 DC FF FF
现在需要修改OEP
到0x0001A730
(不需要考虑ImageBase
的0x00400000
)
修改完字节后保存到EXE,双击触发