ShellCode的调试方法和常见问题的解决方法
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”。