再此之前需要了解节表(假设我们都理解了)
以一个程序为例:
如上图所示一个正长的程序运行后是这样的,我们想对该程序做点手脚,在弹出该页面之前,先弹出我们给他指定的东西。
最终实现结果:
首先弹出我们指定的页面,然后在弹出正常页面。
首先我们知道pe结构式分块的,在块与块之前是有空隙的,而我们可以在此做手脚。
首先先计算出我们要插入数据的硬编码大小。(这里我们要插入的是一个messagebox函数,他带有4个参参数)对应的硬编码分别是:push 6a call e8 jmp e9
call+ 我们设定的地址
jmp+跳转回oep地址
call,jmp后均加个字节硬编码
计算
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地址!
对应的硬编码为:
首先查看一下该程序的区段:我们就在.text阶段进行操作。
进行操作之前首先我们要先判断该节区空间够不够用。
真实数据大小:viruralsize 0x19722
文件中对齐后大小:sizeofrvadata 0x1a000
判断空间是否还够:做差 8de 可以注入
.text在文件种的区域范围:1000-1b000
插入数据的部分
目标地址( 0x7684b730)=call下一条指令的地址(0x00416cbd)+call后边的硬编码
call后硬编码:7643 0ff3
jmp后:目标地址(oep4183d7)=jmp(41a742)+jmp后硬编码
jmp后编码 :FFFFdc95
修改oep:1a730
然后保存退出即可。