/*
Author: void#ph4nt0m.org
*/
//
编译器 cl.exe(Visual C++ 6.0)
//
没有做任何优化情况下,编译大小为:16K
//
编译优化后: 1K (用16进制编辑器把尾部的0x00去掉: 712bytes)
#include
<
windows.h
>
#pragma comment(lib,
"
kernel32.lib
"
)
//
作用: 指定节对齐为512字节
#pragma comment(linker,
"
/align:512
"
)
//
作用: 合并节
//
将.data节和.rdata节合并到.text节(代码节)
#pragma comment(linker,
"
/merge:.data=.text
"
)
#pragma comment(linker,
"
/merge:.rdata=.text
"
)
//
作用: 指定子系统为windows (和优化无关)
//
vc编译器默认是console,会有个黑糊糊的CMD窗口,不好看.用windows就好了
#pragma comment(linker,
"
/subsystem:windows
"
)
//
作用: 指定入口函数
//
子系统为windows的默认入口点WinMain和console的默认入口点main,都会引入一段启动stub代码,指定入口函数可去掉之.
#pragma comment(linker,
"
/ENTRY:main
"
)
//
int WinMain(HINSTANCE current, HINSTANCE prev, LPSTR cmdline, int showcmd)
//
作用: 去掉函数的栈帧代码,纯属吹毛求疵:-)
//
即函数开头的push ebp / mov ebp, esp和结尾的pop ebp / retn
__declspec(naked)
void
main()
{
//
调用wmp. 这是按套路出牌的方法.
//
typedef VOID (__stdcall *fnRunDllW)(HWND, HINSTANCE, LPCWSTR, DWORD);
//
((fnRunDllW)GetProcAddress(LoadLibrary("msdxm.ocx"), "RunDllW"))(0,0,0,0);
//
不按套路出牌,不压入RunDllW的函数参数,直接调用.
GetProcAddress(LoadLibrary(
"
msdxm.ocx
"
),
"
RunDllW
"
)();
//
注意此时的堆栈是不平衡的.
//
但是通过ExitProcess()退出自身,就不用去考虑平衡了.
ExitProcess(
0
);
}