預設連結會引入龐大的 CRT 啟動代碼與函數庫。透過 /NODEFAULTLIB 排除所有預設庫,改用 Windows API 直接替代 CRT 函數,並合併區段、對齊到 16 位元組,可將簡單程式壓縮至 1.5KB 以下。
/NODEFAULTLIB
/ENTRY:WinMain
/FILEALIGN:16
/ALIGN:16
/OPT:REF
/OPT:ICF
/OPT:NOWIN98
/MERGE:.rdata=.data
/MERGE:.text=.data
/MERGE:.reloc=.data
#ifndef _DEBUG
#pragma comment(linker, "/NODEFAULTLIB")
#pragma comment(linker, "/ENTRY:WinMain")
#pragma comment(linker, "/FILEALIGN:16")
#pragma comment(linker, "/ALIGN:16")
#pragma comment(linker, "/OPT:REF")
#pragma comment(linker, "/OPT:ICF")
#pragma comment(linker, "/OPT:NOWIN98")
#pragma comment(linker, "/MERGE:.rdata=.data")
#pragma comment(linker, "/MERGE:.text=.data")
#pragma comment(linker, "/MERGE:.reloc=.data")
#endif
| CRT 函數 | Win32 API 替代 |
|---|---|
| malloc/free | HeapAlloc/HeapFree |
| strcpy/strcat/strlen | lstrcpy/lstrcat/lstrlen |
| strcmp/strcmpi | lstrcmp/lstrcmpi |
| memcpy/memset/memmove | CopyMemory/FillMemory/MoveMemory |
| sprintf/vsprintf | wsprintf/wvsprintf |
| toupper/tolower | CharUpper/CharLower |
| isalpha/isdigit 等 | IsCharAlpha/IsCharAlphaNumeric 等 |
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
MessageBox(NULL, L"Hello, Tiny World!", L"1.5KB EXE", MB_OK);
return 0;
}
Microsoft 提供的精簡 CRT,僅含常用函數,體積極小。
/DEFAULTLIB:LIBCTINY.LIB /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.libDLL 入口點 DllMainCRTStartup 也需 CRT,同樣用 LIBCTINY 解決。
#ifndef _DEBUG
#pragma comment(linker, "/DEFAULTLIB:kernel32.lib")
#pragma comment(linker, "/DEFAULTLIB:LIBCTINY.LIB")
#pragma comment(linker, "/NODEFAULTLIB:libc.lib")
#pragma comment(linker, "/NODEFAULTLIB:libcmt.lib")
#pragma comment(linker, "/FILEALIGN:16")
#pragma comment(linker, "/ALIGN:16")
#pragma comment(linker, "/OPT:NOWIN98")
#pragma comment(linker, "/MERGE:.rdata=.data")
#pragma comment(linker, "/MERGE:.text=.data")
#pragma comment(linker, "/MERGE:.reloc=.data")
#endif
BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return TRUE; }
extern "C" __declspec(dllexport) BOOL __stdcall ExpHook() {
return FALSE; // 僅導出一個測試函數
}
| 類型 | 基礎大小 | 壓縮手段 | 預期大小 |
|---|---|---|---|
| MFC 靜態連結 | ~300KB | UPX/ASPACK 壓縮殼 | ~150KB (50%) |
| ATL 靜態連結 | ~80KB | UPX + 移除 CRT | 20-40KB |
| COM 元件 | 視介面數 | ATL + 壓縮殼 | 20-40KB |