在一个可执行文件中插入一段代码,并执行
此文章在一个win32程序执行前插入一个MessageBox函数
一、准备需要添加的代码
寻找MessageBox的调用地址
CPP代码:
#include <windows.h>
using namespace std;
int main() {
MessageBox(0,0,0,0);
return 0;
}
硬编码:
6A 00 ;PUSH
6A 00
6A 00
6A 00
E8 00 00 00 00 ;CALL
E9 00 00 00 00 ;JMP
;PUSH的4个0是MessageBox的参数
执行情况:
二、使用OD寻找MessageBox调用地址
- 使用
bp MessageBoxA
,为MessageBoxA
设置断点
- 点击"B",即可查看设置的断点,我这里
MessageBoxA
的开始地址为762639A0
- 可以双击,在反汇编窗口中跟随
三、查看被插入代码程序的PE信息
此处我使用的是
winXP
的notepad.exe
,其文件对齐和内存对齐并不一致,需要注意
-
DOS HEADER
-
FILE HEADER
-
OPTIONAL HEADER
-
Sections
-
需要留意的字段
Entry Point: 0000739D Image Base: 01000000 Section Alignment: 1000 File Alignment: 200 Section: .text Raw Offset: 400 Virtual Size: 7748 Virtual Offset: 1000
四、计算并插入硬编码
-
计算FileBuffer中代码节的结束地址
Formulas:
RawOffset + VirtualSize
=400 + 7748 = 00007B48
-
在空白区填充代码的硬编码
-
计算E8后的值
公式:
E8 后的值 = 真正要跳转的地址 - E8下一条指令地址
ImageBuffer
中插入代码的地址:ImageBase + VirtualOffset + VirtualSize
=1000000 + 7748 + 1000 = 01008748
插入了4个
6A 00
所以E8
的地址为:01008748 + 8 = 01008750
E8 后的值 = 762639A0 - (01008750 + 5)= 7525B24B
-
计算E9后的值
真正要跳转的地址:
ImageBase + EntryPoint = 01000000 + 0000739D = 0100739D
E9 后的值 = 0100739D- (01008755 + 5)= FFFFEC43
-
修改跳转地址
-
修改EntryPoint
EntryPoint的寻找方式:
ImageBase + EntryPoint
,这里没有对齐偏移,所以需要直接给EntryPoint赋上内存对齐偏移EntryPoint = 00008748
五、结论
另存执行,会在真正的代码执行之前执行插入的代码
- 插入的位置并不需要紧接节内容结束,可以怎么方便怎么来
- 留意
EntryPoint
的寻址方式,在寻址时并不会自动加上对齐,是需要手动加上内存
对齐的 - 地址计算都使用内存对齐大小