1.4 ShellCode编写简介

“一般来说,我们把‘想要的程序’称为ShellCode。Shell最先指人机交互界面,而这里的ShellCode不仅仅指交互了,还可以是实现任意功能的代码。”

“ShellCode的编写很深奥,涉及很多方面,在以后的课程中我们会作详细讨论,这里就不多说了。只给个例子。”

“我们‘想要的程序’功能最好是能够开一个DOS窗口,那我们就可以做很多事情,比如下面这个程序。”

#include<windows.h>
int main()
{
    LoadLibrary(“msvcrt.dll”);
    system(“command.com”);
    return 0;
}

“大家看!执行一个command.com就可获得一个DOS窗口,在C库函数里面,语句 system(“command.com”); 将完成我们需要的功能。”

小知识:

Windows不像Unix那样使用系统调用来实现关键函数。Windows通过动态链接库来提供系统函数,就是所谓的Dll。

“system函数由msvcrt.dll(the Microsoft Visual C++ Runtime library)提供,所以要想执行system,必须首先使用 LoadLibrary(“msvcrt.dll”); 装载动态链接库msvcrt.dll,之后才能调用system函数。”

“OK,我们执行,看看效果吧!弹出一个DOS对话框!如图1-6,可以执行dir、copy等命令。”

“乌拉,太神奇了!”大家一片欢腾,都觉得不可思议。

“呵呵,现在我们把程序改为机器码,可能你们过去也看到过,别人的程序中有很多诸如 \x01\xff\x3f\xff 一类的东东,那些就是程序的机器码。也把我们的程序变成机器码吧!”

“可是怎么变呢?”几位女生有些疑惑。

“很简单!”老师说道,“在VC中按F10调试,然后在Debug工具栏中点击最后一个按钮‘Disassemble’,这样就出现了源程序的汇编代码;再在代码窗口上点击鼠标右键,在弹出菜单中选择‘Code Bytes’,这样就出现了机器码,如图1-7!”

“哦,那我们把它抄下来就可以了?”古风高兴的说道,埋头就要写。

“不!”老师阻止到,“其实还要作相关的一些工作之后才能直接抄取机器码,ShellCode的编写将在后面的课程中讲到。”

“哦!”古风耸耸肩,遗憾的说道,“我不怕辛苦,不怕做累人的活。”

“呵呵,以后有机会的,大家先这么认为ShellCode是这样生成的吧,我直接给大家一个开DOS窗口的机器码。”老师在影屏上打出来。

char ShellCode[] = 
{
    0x8B,0xE5, 0x55,0x8B,0xEC,0x83,0xEC,0x0C,0xB8,
    0x63,0x6F,0x6D,0x6D,0x6D,0x6D,0x6F,0x63,0x89,
    0x45,0xF4,0xB8,0x61,0x6E,0x64,0x2E,0x89,0x45,
    0xF8,0xB8,0x63,0x6F,0x6D,0x22,0x89,0x45,0xFC,
    0x33,0xD2, 0x88,0x55,0xFF, 0x8D,0x45,0xF4, 
    0x50, 0xB8,0x24,0x98,0x01,0x78, 0xFF,0xD0 
};

老师说:“接下来,我们把这些背景知识连起来,写一个真正的利用程序!”