手动在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 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。