ShellCode的调试方法,我这里总结了四种方法,其实原理都一样,就是通过几种指令的组合,把EIP改为shellcode的地址,然后跳到shellcode去执行,再调试shellcode。代码如下:
//ShellCodeDebug.cpp : Defines the entry point for the console application. // #include "stdafx.h" unsigned char shellcode[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\xd9\xeb\x9b\xd9\x74\x24\xf4\x31\xd2\xb2\x77\x31\xc9\x64\x8b" "\x……" // 放上你自己的shellcode开始调试吧 "\xfc\xac\x84\xc0\x74\x07\xc1\xcf\x0d\x01\xc7\xeb\xf4\x3b\x7c" "\x90\x90\x90\x90\x90\x90\x90\x90"; int _tmain(int argc, _TCHAR* argv[]) { int nMethod = 4; switch(nMethod) { case 1: { // 1、方法一,使用push ret指令序列 __asm { leaeax, shellcode pusheax // ShellCode地址入栈 ret // 这里会直接返回到shellcode去执行 } } break; case 2: { // 2、方法二,直接使用call指令 __asm { leaeax, shellcode calleax // 直接去call这个地址 } } break; case 3: { // 3、方法三,强制转换为一个函数指针再调用 ((void(*)(void)) &shellcode)(); } case 4: { // 4、方法四,使用jmp指令 __asm { leaeax, shellcode jmpeax } } break; default: break; } return 0; }
1、问题:在使用VS系列编译器编译时,有些shellcode编译时生成的中间文件会被杀软杀掉(里面含有恶意特征),要注意,编译器可能提示中间文件不存在(类似:fatal error C1083: Cannot open compiler intermediate file:'C:\DOCUME~1\MAGICT~1\LOCALS~1\Temp\_CL_7e69353ain': No such file or directory)。
解决方法:暂时关闭安全软件的实时监控,等调试完了再打开实时监控。
2、问题:有时候单步调试一段shellcode会异常,但是直接运行又没问题(具体原因我也不是很清楚,可能是寄存器环境之类的,一般出这种问题的shellcode,在异常前会有fnstenv指令,而且尝试过在异常前加上cc断点,直接双击运行中断之后,把调试器附加上去会发现,单步会异常的指令,在这样运行的情况又是正常的)。
解决方法:ShellCode一般不会特别长,既然单步会出异常,就直接找到关键(一般是call指令)地方下断,然后再调试,譬如调用系统API,调用关键算法。
3、问题:如果开了全局DEP,调试会出现异常,因为ShellCode并不在代码段上面。
解决方法:你可以把buf申请在堆上,并且修改是否可执行权限,不过我建议还是关了DEP再调试吧,简单。
4.问题:像js里面的shellcode可能是类似这样”%uebd9%ud99b%u2474”的一些指令,这种要想放到C程序里面去调试怎么办?
解决方法:js的shellcode一般都是使用这种宽字节存储的,自己写个小程序转成C里面的16进制写法就可以了,像上面可以转成”\xd9\xeb\x9b\xd9\x74\x24”。
原文来自:http://blog.csdn.net/magictong/article/details/7768026