代码节空白区添加代码

在一个可执行文件中插入一段代码,并执行

此文章在一个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调用地址

  1. 使用bp MessageBoxA,为MessageBoxA设置断点

代码节空白区添加代码_寻址_02

  1. 点击"B",即可查看设置的断点,我这里MessageBoxA的开始地址为762639A0

代码节空白区添加代码_#include_03

  1. 可以双击,在反汇编窗口中跟随

代码节空白区添加代码_#include_04

三、查看被插入代码程序的PE信息

此处我使用的是winXPnotepad.exe,其文件对齐和内存对齐并不一致,需要注意

  1. DOS HEADER

    代码节空白区添加代码_windows逆向_05

  2. FILE HEADER

    代码节空白区添加代码_硬编码_06

  3. OPTIONAL HEADER

    代码节空白区添加代码_windows逆向_07

  4. Sections

    代码节空白区添加代码_寻址_08

  5. 需要留意的字段

    Entry Point:		0000739D
    Image Base:			01000000
    Section Alignment:	1000
    File Alignment:		200
    
    Section: 			.text
    Raw Offset:			400
    Virtual Size:		7748
    Virtual Offset:		1000
    

四、计算并插入硬编码

  1. 计算FileBuffer中代码节的结束地址

    Formulas: RawOffset + VirtualSize = 400 + 7748 = 00007B48

    代码节空白区添加代码_寻址_09

  2. 在空白区填充代码的硬编码

    代码节空白区添加代码_硬编码_10

  3. 计算E8后的值

    公式:E8 后的值 = 真正要跳转的地址 - E8下一条指令地址

    ImageBuffer中插入代码的地址:ImageBase + VirtualOffset + VirtualSize = 1000000 + 7748 + 1000 = 01008748

    插入了4个6A 00所以E8的地址为:01008748 + 8 = 01008750

    E8 后的值 = 762639A0 - (01008750 + 5)= 7525B24B

  4. 计算E9后的值

    真正要跳转的地址:ImageBase + EntryPoint = 01000000 + 0000739D = 0100739D

    E9 后的值 = 0100739D- (01008755 + 5)= FFFFEC43

  5. 修改跳转地址

    代码节空白区添加代码_windows逆向_11

  6. 修改EntryPoint

    EntryPoint的寻找方式:ImageBase + EntryPoint,这里没有对齐偏移,所以需要直接给EntryPoint赋上内存对齐偏移

    EntryPoint = 00008748

    代码节空白区添加代码_内存对齐_12

五、结论

另存执行,会在真正的代码执行之前执行插入的代码

代码节空白区添加代码_硬编码_13

  • 插入的位置并不需要紧接节内容结束,可以怎么方便怎么来
  • 留意EntryPoint的寻址方式,在寻址时并不会自动加上对齐,是需要手动加上内存对齐的
  • 地址计算都使用内存对齐大小