一:OD中找出函数执行地址:
在这里我们先来简单了解一下MessageBox函数:
1.MessageBox()函数:
MessageBox函数的功能是弹出一个标准的Windows对话框;它不是C函数库的标准函数,而是一个API,我们可以用C语言调用API函数。可以理解为:我们在C中使用MessageBox函数就可以表示调用系统提供的API函数–MessageBoxA。
该函数包含在头文件<windows.h>中。
2.OD中找出函数执行的起始地址:
我们在OD命令窗口中输入:
bp MessageBoxA;
就可以得到该函数执行的起始地址,我们需要牢记这个地址,这对于在节空白区添加代码是非常重要的。
需要特别注意的是:
我们找到的这个地址只是在当前计算机的当前运行状态下的地址,每一台计算机的该地址都不一样,计算机关机重启的时候这个地址也会发生变化!
二.E8(call)和E9(jmp)计算公式:
call的硬编码:E8
需要注意的是:E8后面会跟着四个字节的数据,表示转换后的偏移(通过这五个字节数据就可以执行想让程序执行的函数)
jmp的硬编码:E9
与call的硬编码一样,它后面同样会跟着四个字节的数据,表示转换后的偏移(通过这五个字节我们可以实现:程序执行完我们添加进去的代码后回到正常执行的地址)
计算E8和E9的公式:
这里需要计算的是E8和E9后面跟着的四个字节数据,我们用X来表示
我们先来给大家给出一个公式:
函数真正执行的地址 = E8后面一条指令的地址 + X(E8后面跟着的四个字节数据)
那么我们就可以得到:
X=程序真正执行的地址 —E8后面一条指令的地址
而我们知道E8(E9)后面跟着四个字节数据,那么E8(E9)后面一条指令的地址就应该是E8(E9)的地址+5(E8(E9)本身占据一字节)
那么我们就得到了E8(E9)的计算公式:
X = 程序真正执行的地址—(E8(E9)的地址 + 5)
这里给出我自己的理解:这里的X就是相对E8(E9)指令的偏移,我感觉这样的话会更好理解,当然如果大家有更好的理解或者是X的本质可以在文章后面评论,我会非常虚心地接受。
需要特别注意的是:这里的X是指磁盘文件拉伸后的地址,不是FileBuffer地址!
三.节空白区添加代码(手动)
在这里给出手动添加代码的实现步骤(通过Windows16进制编辑器完成)
1.先将我们想要程序执行的函数编译。
2.通过反汇编,查找函数硬编码,并且计算大小,如果有参数,参数入栈的硬编码也需要算在其中。
3.通过IDA,OD或者X64dbg找到该函数执行时的地址,并且牢记。
4.在空白区添加代码,最起码要保证该节的空白区能存放地下这些硬编码(计算机只能认识0和1,我们要在节空白区添加代码,必须添加硬编码,高级语言代码计算机是不能理解的),我们可以通过之前编译好的PE头部信息提取程序来寻找节空白区,也可以通过PETool来寻找一个能存放得下该函数硬编码的空白区。
5,通过16进制编辑器找到该节空白区,在空白区写入压入参数的硬编码,完成之后写入E8和计算好的X
6.通过通过之前编译好的PE头部信息提取程序来寻找可选PE头部结构中的AddressOfEnterPoint,将其改为我们写入的压栈的首地址
7.通过AddressOfEnterPoint和E9的地址算出E9后跟的X,并将其写入E9之后
需要特别注意的是,在这里我们计算E8或者E9的地址时,一定要在ImageBase的基础上来计算,因为程序执行时都是基于ImageBase的,否则计算出来的地址会出现错误!
完成这些操作后,我们就可以保存,当再次打开文件时,我们会发现我们自己写的函数已经执行。
这里是手动向节空白区添加代码,之后我会用C语言写出自动将想要的代码添加到节空白区的程序,希望大家多多关注!如果大家发现文章中有错误请指出,我会非常虚心得与大家共同学习。