手动在exe中添加shellcode
思路
-
首先理清思路,添加shellcode的原理是什么。添加shellcode就是在 节里面没有用到的空白区域 添加入自己的shellcode,然后将程序入口点 OEP 修改到添加的shellcode的起始位置,在执行完shellcode之后再
JMP跳回原来程序的入口点。 -
在这里我们的目标是添加一个弹出MessageBox的shellcode,其代码为
MessageBox(0, 0, 0, 0),执行效果为
准备工作
-
首先我们要进行一些准备工作。在每一台机器上
MessageBox这个函数的地址都是不同的,我们要先找到这个函数的地址。在VC6.0中写如下代码1 2 3 4 5 6 7 8#include <windows.h> #include <stdio.h> int main() { MessageBox(0, 0, 0, 0); return 0; }然后在MessageBox处打上断点,进入反汇编,F11跟入,可找到
MessageBox所在的地址为 77D507EA 。
或者也可以用代码找到MessageBox的地址,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16#include <stdio.h> #include <iostream> #include <windows.h> typedef void (*MYPROC)(LPTSTR); int main() { HINSTANCE LibAddr; MYPROC procAddr; LibAddr = LoadLibrary("user32"); printf("动态库及地址 = 0x%x\n", (int)LibAddr); procAddr = (MYPROC)GetProcAddress(LibAddr, "MessageBoxA"); printf("函数相对地址 = 0x%x\n", (int)procAddr); getchar(); return 0; }同样可以得到其相对地址。

开始添加shellcode
- 得到
MessageBox地址之后开始准备添加shellcode。先用PETOOLS查出其ImageBase、文件对齐和文件入口点OEP,如下,则其入口点为86E0,ImageBase为40000,文件对齐为1000

-
然后在节表信息中找到某个节是否有多余的空间

这里可以得到307E0-31000这一段区域应该是没有被使用的,于是打开 WinHex ,按
Alt + G跳转到31000位置
发现一大片空白区。随意选择一处添加入我们的shellcode
-
我们添加的shellcode首先要
push 0执行4次,将MessageBox的4个参数压入栈中。其对应硬编码为6a 00 6a 00 6a 00 6a 00。然后要CALL调用MessageBox函数,调用完之后再JMP跳转到原来函数的入口点OEP使程序能正常运行。这里CALL的硬编码是E8,JMP的硬编码是E9,因此先填入E8 00 00 00 00 E9 00 00 00 00。 -
接下来开始算
CALL和JMP后面跟着的参数。其计算方法为
则通过
(ImageBase + CALL指令后一条指令的地址) + X = 77D507EA算出应该填在E8后面的参数。其中77D507EA是我们之前得到的MessageBox的地址。
算出得E8后面应跟
7791F8FD,将其填到E8后面。这里注意要将计算器设置为DWORD(双字)而根据公式,E9后面跟的参数为
X = 程序入口点OEP - E9这条指令后一条指令的地址。之前已经查得程序入口点OEP为86E0
而E9后一条指令的地址为
30EF2,则用计算器算得
E9后面应填
FFFFD 77EE将其填入, shellcode编写完成

将程序入口点OEP改到添加的shellcode上
接下来是最后一步,将程序原来的入口点改到添加的shellcode ( 30EE0 )上面,如下

修改完成后添加shellcode的工作结束了,接下来保存到原文件,双击便可执行我们添加的shellcode-弹出 MessageBox

- 原文作者:小钟
- 原文链接:https://smallzhong.github.io/post/%E6%89%8B%E5%8A%A8%E5%9C%A8exe%E4%B8%AD%E6%B7%BB%E5%8A%A0shellcode/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。