zoukankan      html  css  js  c++  java
  • 【转载】vc编译exe的体积最小优化

    原文地址:http://www.2cto.com/kf/200908/40970.html

    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 没问题哦

    // 编译器 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)
    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 

  • 相关阅读:
    逆序对
    【模板】树状数组 1
    【模板】树状数组2
    发射站
    质量检测
    【模板】ST表
    winform ComBox绑定数据
    JavaScript CheckBox实现全选和部分选择
    webbrowser内容滚动(javascript内容无缝滚动)
    double? int?
  • 原文地址:https://www.cnblogs.com/doudongchun/p/3699662.html
Copyright © 2011-2022 走看看