学习shellcode程序设计时,在我们提取了shellcode以后,可以简单的实现其隐藏运行。
一、shellcode的运行
下面的这段代码,是简略的过程。
#include<windows.h>
unsigned char ShellCode[] = "\x55\x8B\xEC\x33\xFF\x57\x83\xEC\x08...."; //其余省略
int main()
{
((void(*)(void)) &ShellCode)();
return 0;
}
其中的((void(*)(void)) &ShellCode)();这句代码是实现shellcode运行的主体代码,比较不好理解,转变为汇编代码可以清晰的了解VC中加载运行ShellCode的原理。
lea eax,ShellCode //先把ShellCode字符串的地址传给eax
jmp eax //跳到eax处执行ShellCode
如果直接跳过去的话,ShellCode执行完后会没有返回的地方,运行完后会报错,所以可将jmp换成call:
lea eax,ShellCode
call eax
二、shellcode的隐藏
不过上面的代码在运行的时候会出现虚拟DOS窗口,要实现隐藏运行,只需要在预编译部分加入如下代码,设置连接器选项
#pragma comment(linker,"/subsystem:windows /entry:mainCRTStartup");
因为操作系统装载了应用程序,完成初始化工作以后将会转到程序的入口点执行。程序的默认入口点是由连接程序设置的,不同的连接器选择的入口函数也不尽相同。在VC下,连接器对控制台程序设置的入口函数是mainCRTStartup,然后由mainCRTStartup调用我们编写的main函数;对图形用户界面(GUI)程序设置的入口函数是 WinMainCRTStartup,然后由WinMainCRTStartup 调用我们编写的 WinMain 函数。
具体设置哪个入口点是由连接器的“/subsystem:”选项参数确定的,它告诉操作系统如何运行编译生成的.EXE文件。我们主要关注下面两个参数:
CONSOLE——win32 字符模式应用程序,运行时产生类似dos窗口的控制台窗口。如果应用程序的主函数为main或wmain,在默认情况下该应用程序就是一个控制台应用程序。
WINDOWS——该类型的应用程序不产生console窗口,窗口由用户自己创建,简而言之就是一个标准的win32 application,其入口地址为winmain或wwinmain的地址。如果在应用程序中定义的主函数为winmain或wwinmain,在默认情况下该应用程序就是一个win32 application 。