我先写了一个小程序 Test.exe。
注意:由于我用的是控制台程序没有导入user32.dll所以我用的直接添加ShellCode是不行的,要么在ShellCode中导入user32.dll要么在程序中Load一下,如果没有以下测试不成功。
//Test.exe源代码 #include <stdio.h> #include <windows.h> int main(int argc, char* argv[]) { LoadLibrary("kernel32.dll"); LoadLibrary("user32.dll"); MessageBox(NULL,"http://cnblogs/ONDragon","ONDragon",0); printf("Test\n"); return 0; }
用UE打开,添加我们要添加的ShellCode(弹出另一个MessageBox)。
push 0x0 6A 00 push 0x0 6A 00 push 0x0 6A 00 push 0x0 6A 00 call 771BEA11 E8 XXXX
解释: call 771BEA11 这个地址是我本机MessageBox的地址,连地址都不会找,那么先自己查查在学这个吧(还有后面的OEP查找什么的),有些小复杂对于新手。
E8 是Call的硬编码,6A 00 是 push 0x00 的硬编码。
因为MessageBox需要4个参数,处于简单化,我们就给它push4个0,只是简单化。
我们要做的就是在程序中添加这个硬编码指令,那么在哪里添加呢?我们大概学过PE结构了,我们只要找到一个节的空白位置添加即可。
我们只要把上面的硬编码添加到程序中即可,但是也不是直接添加的,需要一个转换。
要跳转的地址 ?= ?E8下一条指令的地址 + XXXX。(E9同理,下面会遇到)!!!
XXXX ?= ?要跳转的地址 ? – ?E8下一条指令的地址。(E9同理,下面会遇到)!!!
比如我们要跳转的地址是MessageBox的地址771BEA11,我们不能直接写E8(call)771BEA11,需要上公式转换,要跳的地址就是(771BEA11) – E8的下一条指令的地址。
例子:
我们在文件偏移为5940的地址添加我们的ShellCode。
6A 00 ?6A 00 ?6A 00 ?6A 00(注意大小端格式)
XXXX(就是将要填入E8 后面的值) =?771BEA11 – 0040594D(E8的下一条指令的地址)。
还要注意,一定是减去?0040594D,是内存地址RVA不是文件偏移。
但是程序运行起来不会自己跑到这个位置运行代码,所以要让程序自己打开时到这里运行代码,所以要修改OEP。
这样程序就会跑到我们的ShellCode处执行我们的代码,但是,为了不让被发现程序被修改了,得让它执行完我们的代码后,再去正常执行自己的代码,所以我们还要跳回去正常的入口OEP。
所以我们用E9(jmp 的硬编码)程序执行完我们的代码要无条件跳转到正常入口OEP,所以XXXX = 正常OEP – E9下一条指令的地址 = 401071 -?405952 = FFFFB71F。
然后保存运行即可,会先弹出我们的ShellCode。OK。
总结
- 注意不适合新手。
- 注意要仔细,要LoadLibrary(“user32.dll”);只针对控制台程序。
- 注意大小端格式。
- 注意E8(E9)后面地址的转换。
- 注意添加代码地址是(内存中的地址)RVA。
- 还是学学PE才行。
转载请注明:即刻安全 » 任意程序添加ShellCode