想要再空白区添加代码,首先我们需要清晰一下我们需要做的步骤。

1.查找本机MessageBoxA地址
2.打开OD调试工具拖入要添加的exe程序。
3.在命令中输入 : (输入后按下回车键)
4.找任意一段空白区添加上代码 (最好是添加到 空白区开始预留一行的位置,便于以后再添加更多代码节约空间)
5.计算E8跳转的地址
6.修改OEP (程序入口的点)

预备知识

汇编指令 硬编码
call E8 00 00 00 00
jmp E9 00 00 00 00
push 6A 00

1.查找本机MessageBoxA地址

1.打开OD调试工具拖入要添加的exe程序。
讲你想要修改的exe程序拖入od调试工具中,这里我们需要注意该exe程序必须有user32.dll,否则没有我们要添加的代码–MessageA函数的地址。
在这里插入图片描述

2.在命令中输入 : (输入后按下回车键)

bp MessageBoxA

在这里插入图片描述
如此一来,我们就成功在MessageA函数的地址下了断点。点击断点的窗口即可查看我们设置好的断点。
在这里插入图片描述

开始添加代码

1.接下来就该添加我们想要添加的代码了,随便找一个空白位置,然后我们计算call后的值,
call后的值=调用函数的地址-message函数的地址-5(call命令本身所占的内存大小),现在调用函数的地址是在问价中的地址,而不是在内存中的地址,所以首先我们需要找到程序载入内存的基地址ImageBase,在扩展PE头的第 28 个字节后面的 4 个字节表示的 ImageBase ( 程序基地址 ),如下图
在这里插入图片描述
(1表示扩展pe头,2表示标准pe头),所以当前调用函数的地址为我们在文件中添加call指令的地址加上imagebase的值,所以call后的值=MessageBoxA的地址 - 当前调用函数的地址 - 5
此时计算好地址后,查看对应的硬编码,首先是三个push:6A 00 6A 00 6A 00 6A 00 然后是call 指令 E8,然后写如我们计算好的地址,记得小端存储。
代码我们已经写好了,那么我们现在应该想想怎么使程序到这个地址来执行我们添加的代码,我们可以修改程序的入口函数eop,(在扩展PE头的第 16 个字节后面的 4 个字节),如下图
在这里插入图片描述
(1程序入口:0x401170(相对于程序基地址)2,扩展PE头的开始)
把程序拖入OD,程序第一次停止的的地址就是程序入口
在这里插入图片描述

所以只要修改程序入口地址,把程序入口改为调用函数的地址,然后在调用后再返回到真正的程序入口,就可以在程序执行前执行我们想调用的函数

修改程序入口为0x600

在这里插入图片描述

现在就9可以达到在程序执行前调用MessgaBoxA函数的效果,但是要执行完这个函数后,再返回到真正的程序入口,不然程序不能够正常运行,于是又要在我们要调用的函数后面再制造一个返回到真正程序入口处的机器码
这里就在用到jmp这个指令,表示直接跳转到某个指定的地址

先看一下jmp要如何使用

在这里插入图片描述

这里jmp的使用方法其实和call的规律一样只是开头的 E8 变成了 E9

在这里插入图片描述

所以E9后面的值应该是

jmp后的值 = 程序入口的地址 - 当前的地址 - 5 = 0x401170 - 0x40060D - 5 = 0x0B5E

当前的地址应该是0x40060D

所以修改后就是这样的
在这里插入图片描述

此时把程序另存为message_test.exe, 运行出现了我们预期的效果
在这里插入图片描述

源程序的代码是很简单,但是要注意要有MessageBoxA函数

不然在最开始没有user32dll,我也不知道为什么,但如果是正常的程序都会有user32dll(因为一般的程序都有窗口)

我是用下面的代码做的实验

// messge.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
int main(int argc, char* argv[])
{
printf("nothing...");
MessageBox(0,"这是已有的弹框","提示",0);
Sleep(60000);

//printf("Hello World!\n");
return 0;

}

简单介绍一点点PE文件头结构

DOS头部分:

DOS MZ 文件头 (64字节):
前 64 个字节,最后 8 个字节表示 PE 文件头的开始位置, DOS 块结束前的位置,绿色箭头指向PE文件头的开始
在这里插入图片描述

DOS 块 (不确定):
链接器可插入数据

PE文件头:

PE文件标识 (4字节):
50 45 00 00

标准 PE 头 (20字节):

扩展 PE 头

(32位 224 [0xE0] , 64 位 240 [0xF0] ):

  第 36 个字节开始的后 4 个字节表示 硬盘 中文件对齐的字节数大小,
  前 4 个字节表示 内存 中文件对齐的字节数大小,
  第 60 个字节开始的四个字节表示整个文件头的大小( DOS 部分+ PE 文件头),一定是对齐字节数的整数倍
  第 16 个字节后面的 4 个字节表示程序入口(相对 ImageBase )
  第 28 个字节后面面的 4 个字节表示的 ImageBase ( 程序基地址 )

图片与部分内容转载于https://blog.csdn.net/m0_49490199/article/details/111657821