新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 C/C++编程思想 』 → VC++下编译出极小的程序 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 6090 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: VC++下编译出极小的程序 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 VC++下编译出极小的程序

    昨天做了个telnet后门程序玩,
    既然是后门嘛,自然是越小越好.可是我的VC9编译一个HelloWorld都有50K+...
    动态链接到MSVCRT90.dll倒是小下来了,但是得背上一个更变态的dll(600多k)
    而这个msvcrt90.dll就是我的vista sp1也不是自带的.更不便于程序的部署.
    最后自己去查了查资料终于编译出体积比较满意的exe,步骤如下:
    1.扔掉CRT.
    CRT提供了大量常用的函数.可说只要C/C++程序基本都会用到它.但是获得了方便的同
    时也增大了不少体积.虽然可以通过动态链接到外部的dll来解决,但是自此就有了对一
    个更大的dll的依赖.所以要减肥,就要先拿CRT开刀.
    在cl的编译参数中加上/MD,再在link中加上/nodefaultlib:msvcrt.lib即可避免链接
    到crt(静态crt的lib文件名我不清楚,所以就先链接成动态的,再去除对应的msvcrt.lib)

    2.重载new,new[],delete,delete[]
    C/C++程序少不了动态分配内存,前面丢掉了CRT,再编译程序会发现反是有内存分配的地方都
    在报错,这是因为我去掉了crt,编译器找不到对应的函数所致.所以要自己写内存分配函数.
    C的malloc和C++的new/new[]都是在当前的堆上分配内存.所以只要照着写一遍就可以了:

    C/C++ codetypedef UINT size_t;
    void *malloc(size_t size)
    {
      return HeapAlloc (GetProcessHeap(),NULL,size);
    }
    void free (void *memblock)
    {
      HeapFree (GetProcessHeap(),NULL,memblock);
    }
    void *realloc(void *memblock,size_t size)
    {
      return HeapReAlloc (GetProcessHeap(),NULL,memblock,size);
    }
    void *operator new(size_t count)
    {
      return malloc (count);
    }
    void *operator new[](size_t count)
    {
      return malloc (count);
    }
    void operator delete(void* _Ptr) throw( )
    {
      free (_Ptr);
    }
    void operator delete[](void* _Ptr) throw( )
    {
      free (_Ptr);
    }


    3.常用函数的替代.
    没了CRT许多常用的函数都无法使用,全部自己重写无疑大大加大了程序的代
    码量,也没多大意义.windows提供了很多常用的函数.都由系统的dll来提供,
    使用它们就不用
    a 字符串处理函数.
      字符串处理函数的替代品很多,kernel32.dll提供了lstr***的函数.完全
    可以满足字符串处理的需要,C的格式化字符串sprintf函数很好用,而user32.dll
    也提供了相应的函数wsprintf/wvsprintf用于替代.没有字符串查找函数有点麻烦
    不过自己写也要不了几行代码,或者干脆用Shlwapi.dll提供的更完整的字符串处理
    库来替代.
    b 命令行输入/输出函数.
      这个...系统还真没提供啥对应的函数,不过好在常用也不是太复杂.用Console API写
    几条常用的getline和puts就足够了.

    4.重新指定入口点.
      如果问VC程序的入口点是什么,估计会有不少人回答是main/WinMain.
    没错.这是使用了标准的CRT的程序的入口点.但是实际的入口函数是CRT内部编写好的.在
    完成库的初始化后再调用main/WinMain.既然移除了CRT,链接器自然就会发出找不到入口
    函数的错误,解决方法很简单,用/entry:指定一个函数就可以了.我仍然用习惯的main.
    但是注意,这个main不能带任何的参数.带了也用不了.

    5.更改节的对齐大小.
    cl编译器默认的对齐大小是4K(4096)这个数值的设定是个问题.有时候会使编译出来的程序无
    法执行.这个只有自己反复的试验了.我将它设置为512(其实还可以更小,但是小于512的程序不能使用upx压缩)程序又小了几K.

    6.给exe加壳.
    使用exe加壳程序给程序加个壳也是减小体积的一个好方法.
    我常用的是upx,如果前面的节对齐的值大于512的话,就可以使用upx进行加壳压缩.
    通常可以压缩至原大小的66%左右.

    7.折中的办法:

    丢掉了CRT,重写一些函数的工作量比较大,而且有些函数自己也写不出来.(比如sin函数,像我这样的
    高数菜鸟拿着就头痛)但确实有时候会用到这些函数.于是就有了以下的折中办法:
    VC6是98年推出的.它的动态链接库版的dll是msvcrt.dll,因为出来的早,这个dll的装机率十分的高.
    (我以前学校的win98se都自带,98后的系统自然不用说了.)使用它基本可以不考虑部署时缺少dll的问题
    所以可以使用这个dll提供的crt函数.要使用它,先得去找个vc6,复制里面的msvcrt.lib,改个名.比如
    vcrt6.lib然后把它添加到链接的库里.编译的时候会有库冲突的提示,直接无视即可.这样既可以使用绝大
    部分的CRT库,又做到了减肥.还不用担心会有找不到库的情况.也不用再重新指定入口点.但是经我试验发现
    这样编译出来的程序还是会比完全丢掉CRT的大上一点,所以只是个折中的办法.

    接下来做下试验:
    写一个简单的程序:


    C/C++ code#include <windows.h>
    #include <stdio.h>
    void main ()
    {
      char* str = new char[250];
      sprintf (str,"当前系统已运行了%d毫秒!",GetTickCount());
      MessageBox (NULL,str,str,MB_ICONINFORMATION);
      delete[] str;
    }

    然后做下编译(VC9的编译器,未更改节对齐值,未做加壳)
    静态CRT:50KB
    动态链接CRT:5.50KB
    使用VC6的动态链接CRT:3.00 KB

    完全不用CRT要做下更改:

    C/C++ code#include <windows.h>
    #pragma comment (lib,"user32.lib")
    #pragma comment (lib,"kernel32.lib")
    void *operator new[] (unsigned int size)
    {
      return HeapAlloc (GetProcessHeap(),NULL,size);
    }
    void operator delete[] (void* memblock)
    {
      HeapFree (GetProcessHeap(),NULL,memblock);
    }
    #define sprintf wsprintf
    void main ()
    {
      char* str = new char[250];
      sprintf (str,"当前系统已运行了%d毫秒!",GetTickCount());
      MessageBox (NULL,str,str,MB_ICONINFORMATION);
      delete[] str;
    }


    编译参数也比较长:
    cl /MD msgbox.cpp /link /nodefaultlib:msvcrt.lib /entry:main
    编译后大小:2.00KB
    加上/align:16编译后大小:960Byte


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/6/30 16:01:00
     
     oldnwind 帅哥哟,离线,有人找我吗?
      
      
      等级:大一新生
      文章:8
      积分:94
      门派:XML.ORG.CN
      注册:2006/4/5

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给oldnwind发送一个短消息 把oldnwind加入好友 查看oldnwind的个人资料 搜索oldnwind在『 C/C++编程思想 』的所有贴子 访问oldnwind的主页 引用回复这个贴子 回复这个贴子 查看oldnwind的博客2
    发贴心情 
    高人,景仰!
    学习中。。。
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/10/5 11:12:00
     
     酸酸果 美女呀,离线,快来找我吧!
      
      
      等级:大一(高数修炼中)
      文章:15
      积分:133
      门派:XML.ORG.CN
      注册:2008/9/4

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给酸酸果发送一个短消息 把酸酸果加入好友 查看酸酸果的个人资料 搜索酸酸果在『 C/C++编程思想 』的所有贴子 引用回复这个贴子 回复这个贴子 查看酸酸果的博客3
    发贴心情 
    和你相比我还是小学生呢

    ----------------------------------------------
    研究XML的相似性计算的相关问题,希望可以和朋友们一起讨论。 http://wangg.ys168.com/ 来看看吧,否则会后悔哦~~

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/10/14 20:16:00
     
     suiyun0234 帅哥哟,离线,有人找我吗?
      
      
      等级:大一(高数修炼中)
      文章:20
      积分:180
      门派:XML.ORG.CN
      注册:2006/8/20

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给suiyun0234发送一个短消息 把suiyun0234加入好友 查看suiyun0234的个人资料 搜索suiyun0234在『 C/C++编程思想 』的所有贴子 引用回复这个贴子 回复这个贴子 查看suiyun0234的博客4
    发贴心情 
    这个很猛,呵呵
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/10/18 21:35:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/28 13:35:51

    本主题贴数4,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    78.125ms