讓vc編譯出的程序減小體積 轉

讓vc編譯出的程序減小體積

 

轉自邪惡八進制

-----------------------------

人們都說vc做出的東西可以小點,現在你打開vc編譯一個Hello World出來!點屬性看下,咦!我沒走眼吧,就一Hello World就160kb真是要人命啊!

呵呵!上面的情況是筆者所遭遇的情況.不過後來了解vc可以通過設置參數來自定義編譯方式.爲什麼文件那麼大!主要是編譯器加入了很多沒必要的代碼(這裏是對我們而言,不過有些代碼還是有利於安全的).好了我們就手動改下編譯器的參數來看看能到多大!

我們主要用到的技巧有:

一,使用release版而不用debug版編譯

使用debug版編譯會生成許多垃圾信息.我們先使用默認的設置進行一下編譯.可以看到編譯後生成的文件有152k之巨.使用release版編譯具體方法是:在"build(編譯)--->Configuration(配置)"中將"Win32 debug"移去,然後再次編譯可以發現文件已經小了很多,才24k.但離我們的目標還很遠呢.

二,設置自己的入口點函數

C或C++程序默認的入口函數是main()或WinMain(),但我們現在不用什麼Main,WinMain.因爲這些都不是直接的入口點,編譯器在產生exe文件的時候,將爲我們生成真正的入口點.下面我們來定義自己的入口函數,具體是把main或WinMain改成其它的名字(如MyFun),打開"Project(工程)--->settings(設置)"選項,選中"link"選項卡,在"Category(分類)"下拉列表中選"output",在" Entry-Point symbol(輸入項-點符號)"中輸入我們剛纔定義的入口函數(MyFun),在源程序中也要做相應修改,然後再編譯.現在是16k了:)

三,更改編譯對齊方式

通常VC在編譯的時候,採用的對齊方式是0x1000,即4096bytes,我們現在將他改成0x200,即512bytes.

在剛纔打開的"link"選項卡,在下面的"Project options(工程選項)"中添加:/align:512(還可以將512設

置的更小如16,32.....).注意兩個參數之間有個空格. 3k了^_^用32試試 1.84k好~~~用16 1.79k天哪!

再把程序的數據段和代碼段放在一起,添加:/merge.data=.text /merge:.rdata=.text 1.76k Go on!

另外,如果要是用到MFC函數的程序,可在"Project(工程)--->settings(設置)"裏面的"通用(General)"選項卡中在"Microsoft Foundation Classes"中選擇使用一個MFC的dll(Use MFC in a Share Dll)也會使文件大小縮小很多.現在我們的超小後門編譯好了,試下能用否. ok 沒問題哦

大家注意到程序運行時會產生一個cmd窗口,要讓他沒有就好了.這也好辦.

回到VC++中,在"Project(工程)--->settings(設置)"選項,選中"link"選項卡,在下面的"Project options(工程選項)"有/subsystem:console選項,表示程序是控制檯程序,雙擊運行是會有一個cmd窗口,把console改爲windows就沒有窗口了.:),運行一下 沒有窗口哦 但有進程 連接一下試試

ok 沒問題 這樣我們的超小1.76k telnet小後門就成功了 不被查殺哦 ^_^

// 編譯器 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,都會引入

#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)   //vc2017 x64不支持,只支持x86

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")();

MessageBox(0,0,0,0);

// 注意此時的堆棧是不平衡的.

// 但是通過ExitProcess()退出自身,就不用去考慮平衡了.

ExitProcess(0);

}

微軟C/C++ 編譯器選項

-優化-

/O1

最小化空間

/Op[-]

改善浮點數一致性

/O2

最大化速度

/Os

優選代碼空間

/Oa

假設沒有別名

/Ot

優選代碼速度

/Ob<n>

內聯展開(默認 n=0)

/Ow

假設交叉函數別名

/Od

禁用優化(默認值)

/Ox

最大化選項。(/Ogityb2 /Gs)

/Og

啓用全局優化

/Oy[-]

啓用框架指針省略

/Oi

啓用內部函數

-代碼生成-

/G3

爲 80386 進行優化

/GH

啓用 _pexit 函數調用

/G4

爲 80486 進行優化

/GR[-]

啓用 C++ RTTI

/G5

爲 Pentium 進行優化

/GX[-]

啓用 C++ EH(與 /EHsc 相同)

/G6

爲 PPro、P-II、P-III 進行優化

/EHs

啓用 C++ EH(無 SEH 異常)

/GB

爲混合模型進行優化(默認)

/EHa

啓用 C++ EH(w/ SEH 異常)

/Gd

__cdecl 調用約定

/EHc

外部“C”默認爲 nothrow

/Gr

__fastcall 調用約定

/GT

生成纖維安全 TLS 訪問

/Gz

__stdcall 調用約定

/Gm[-]

啓用最小重新生成

/GA

爲 Windows 應用程序進行優化

/GL[-]

啓用鏈接時代碼生成

/Gf

啓用字符串池

/QIfdiv[-]

啓用 Pentium FDIV 修復

/GF

啓用只讀字符串池

/QI0f[-]

啓用 Pentium 0x0f 修復

/Gy

分隔鏈接器函數

/QIfist[-]

使用 FIST 而不是 ftol()

/GZ

啓用堆棧檢查 (/RTCs)

/RTC1

啓用快速檢查 (/RTCsu)

/Ge

對所有函數強制堆棧檢查

/RTCc

轉換爲較小的類型檢查

/Gs[num]

控制堆棧檢查調用

/RTCs

堆棧幀運行時檢查

/GS

啓用安全檢查

/RTCu

未初始化的本地用法檢查

/Gh

啓用 _penter 函數調用

/clr[:noAssembly]

爲公共語言運行時庫編譯noAssembly - 不產生程序集

-輸出文件-

/Fa[file]

命名程序集列表文件

/Fo<file>

命名對象文件

/FA[sc]

配置程序集列表

/Fp<file>

命名預編譯頭文件

/Fd[file]

命名 .PDB 文件

/Fr[file]

命名源瀏覽器文件

/Fe<file>

命名可執行文件

/FR[file]

命名擴展 .SBR 文件

/Fm[file]

命名映射文件

-預處理器-

/AI<dir>

添加到程序集搜索路徑

/Fx

將插入的代碼合併到文件

/FU<file>

強制使用程序集/模塊

/FI<file>

命名強制包含文件

/C

不抽出註釋

/U<name>

移除預定義宏

/D<name>{=|#}<text>

定義宏

/u

移除所有預定義宏

/E

預處理到 stdout

/I<dir>

添加到包含搜索路徑

/EP

預處理到 stdout,沒有 #line

/X

忽略“標準位置”

/P

預處理到文件

-語言-

/Zi

啓用調試信息

/Zl

忽略 .OBJ 中的默認庫名

/ZI

啓用“編輯並繼續”調試信息

/Zg

生成函數原型

/Z7

啓用舊式調試信息

/Zs

只進行語法檢查

/Zd

僅有行號調試信息

/vd{0|1}

禁用/啓用 vtordisp

/Zp[n]

在 n 字節邊界上包裝結構

/vm<x>

指向成員的指針類型

/Za

禁用擴展(暗指 /Op)

/noBool

禁用“bool”關鍵字

/Ze

啓用擴展(默認)

/Zc:arg1[,arg2]

C++ 語言一致性,這裏的參數可以是:forScope - 對範圍規則強制使用標準 C++;wchar_t - wchar_t 是本機類型,不是 typedef

- 雜項 -

@<file>

選項響應文件

/wo<n>

發出一次警告 n

/?, /help

打印此幫助消息

/w<l><n>

爲 n 設置警告等級 1-4

/c

只編譯,不鏈接

/W<n>

設置警告等級(默認 n=1)

/H<num>

最大外部名稱長度

/Wall

啓用所有警告

/J

默認 char 類型是 unsigned

/Wp64

啓用 64 位端口定位警告

/nologo

取消顯示版權消息

/WX

將警告視爲錯誤

/showIncludes

顯示包含文件名

/WL

啓用單行診斷

/Tc<source file>

將文件編譯爲 .c

/Yc[file]

創建 .PCH 文件

/Tp<source file>

將文件編譯爲 .cpp

/Yd

將調試信息放在每個 .OBJ 中

/TC

將所有文件編譯爲 .c

/Yl[sym]

爲調試庫插入 .PCH 引用

/TP

將所有文件編譯爲 .cpp

/Yu[file]

使用 .PCH 文件

/V<string>

設置版本字符串

/YX[file]

自動 .PCH

/w

禁用所有警告

/Y-

禁用所有 PCH 選項

/wd<n>

禁用警告 n

/Zm<n>

最大內存分配(默認爲 %)

/we<n>

將警告 n 視爲錯誤

-鏈接-

/MD

與 MSVCRT.LIB 鏈接

/MDd

與 MSVCRTD.LIB 調試庫鏈接

/ML

與 LIBC.LIB 鏈接

/MLd

與 LIBCD.LIB 調試庫鏈接

/MT

與 LIBCMT.LIB 鏈接

/MTd

與 LIBCMTD.LIB 調試庫鏈接

/LD

創建 .DLL

/F<num>

設置堆棧大小

/LDd

創建 .DLL 調試庫

/link

[鏈接器選項和庫]

附錄二(更詳細信息,可查閱MSDN)

Visual C# .NET 編譯器選項

- 輸出文件 -

/out:<文件>

輸出文件名(默認值:包含主類的文件或第一個文件的基名稱)

/target:exe

生成控制檯可執行文件(默認) (縮寫: /t:exe)

/target:winexe

生成 Windows 可執行文件 (縮寫: /t:winexe)

/target:library

生成庫 (縮寫: /t:library)

/target:module

生成能添加到其他程序集的模塊 (縮寫: /t:module)

/define:<符號列表>

定義條件編譯符號 (縮寫: /d)

/doc:<文件>

要生成的 XML 文檔文件

- 輸入文件 -

/recurse:<通配符>

根據通配符規範,包括當前目錄和子目錄下的所有文件

/reference:<文件列表>

從指定的程序集文件引用元數據 (縮寫: /r)

/addmodule:<文件列表>

將指定的模塊鏈接到此程序集中

- 資源 -

/win32res:<文件>

指定 Win32 資源文件 (.res)

/win32icon:<文件>

使用該圖標輸出

/resource:<資源信息>

嵌入指定的資源 (縮寫: /res)

/linkresource:<資源信息>

將指定的資源鏈接到此程序集中 (縮寫: /linkres)

- 代碼生成 -

/debug[+|-]

發出調試信息

/debug:{full|pdbonly}

指定調試類型(“full”是默認類型,可以將調試程序附加到正在運行的程序)

/optimize[+|-]

啓用優化 (縮寫: /o)

/incremental[+|-]

啓用增量編譯 (縮寫: /incr)

- 錯誤和警告 -

/warnaserror[+|-]

將警告視爲錯誤

/warn:<n>

設置警告等級 (0-4) (縮寫: /w)

/nowarn:<警告列表>

禁用特定的警告消息

- 語言 -

/checked[+|-]

生成溢出檢查

/unsafe[+|-]

允許“不安全”代碼

- 雜項 -

@<文件>

讀取響應文件以獲得更多選項

/help

顯示此用法信息 (縮寫: /?)

/nologo

取消編譯器版權信息

/noconfig

不要自動包含 CSC.RSP 文件

- 高級 -

/baseaddress:<地址>

要生成的庫的基址

/bugreport:<文件>

創建一個“錯誤報告”文件

/codepage:<n>

指定打開源文件時要使用的代碼頁

/utf8output

UTF-8 編碼的輸出編譯器消息

/main:<類型>

指定包含入口點的類型(忽略所有其他可能的入口點) (縮寫: /m)

/fullpaths

編譯器生成完全限定路徑

/filealign:<n>

指定用於輸出文件節的對齊方式

/nostdlib[+|-]

不引用標準庫 (mscorlib.dll)

/lib:<文件列表>

指定要在其中搜索引用的附加目錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章