BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / security / #29927同步于 2010/9/15
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Security机器人发帖

一点关于PE文件和运行时库链接的笔记

DrJan
2010/9/15镜像同步2 回复
一段废话 对于众多小马编写者来说,如何使自己的小马更小是一个相对重要的问题。 前段时间偶然发现一个很不错的网站: http://www.phreedom.org/solar/code/tinype/ 其中介绍了如果最简单的利用编译、链接选项来生成小的PE文件 随后介绍了如何使用汇编以及其他手段去除PE头部的冗余信息,进一步进行体积优化。 本人才疏学浅,只能学习最简单的利用编译链接选项的部分,以下是学习过程: 修改编译链接选项这种方法的核心思想是:去掉以静态链接方式存在于PE文件中的C运行时库。 原文中举了一个简单的例子,这个例子中简单的利用以下编译链接方式大大的缩小的PE文件的体积: cl /nologo /c /O1 tiny.c link /nologo /ENTRY:main /NODEFAULTLIB /SUBSYSTEM:WINDOWS tiny.obj 其中编译选项/O1是最小体积优化, 链接选项中使用/NODEFAULTLIB去除了默认的库 学习到这里的时候出现了问题,那就是: 1、如果去除掉默认的运行时库,对于很多程序根本无法编译成功,比如 初始化一个局部数组 int a[100] = {0}; 链接时被优化为memset,而memset是运行时库函数。 这时作为一个无法识别的外部链接而报错。 2、如果指定/MT(具体说明参见MSDN)选项动态链接运行时库,链接器会自动选择相应版本进行链接(如VS2008会链接到msvcrt90.dll)。而这些版本的运行时库不一定是系统自带的,因此在很多没有安装运行时库的机器上无法运行。 为了解决这个问题,有以下三个解决方案: 1、不使用这些可能优化成标准运行时库函数的方式编写代码。这种方法比较不方便,首先对代码编写产生了较大影响,其次对已经编写完成的代码,改动会带来巨大工作量。 2、自行编写相应的函数,必须在项目中自己编写一个memset来实现功能。这种方法需要额外工作量,不符合懒人精神,虽然现在有热心开发者编写诸如 libctiny.lib来省去使用者的工作。但是libctiny.lib毕竟不是官方的库,兼容性上无法保证,而且仍然以静态链接方式存在,影响体积。 3、在XP及以上版本的windows系统中,默认系统自带msvcrt.dll,如果链接时让连接器动态链接该DLL,可以相对较好地解决这个问题。 那么如何使编译器链接到XP系统自带的那个msvcrt.dll呢? 经过数次试验(包括直接从XP的mscvrt.dll dump 出lib来导入等无脑手段)后,终于在网上看到提示。有两种方法来实现链接系统自带的msvcrt.dll,一是使用win 2003 sp1 ddk的运行时库(未实践);二是使用VC++6.0的运行时库。 于是下了个VC++6的安装文件,拷出CRT和LIB,并在链接是时候使用 link /nologo /ENTRY:main /NODEFAULTLIB /SUBSYSTEM:WINDOWS tiny.obj $(path)\LIB\MSVCRT.LIB 即可(其中path为前面拷出来的lib文件夹所在路径)。 这样生成的PE文件,一方面避免了使用静态链接增加体积,另一方面避免了系统中不存在链接的动态运行时库而无法运行。
订阅后,新回复会通过你的通知中心匿名送达。
2 条回复
DrJan机器人#1 · 2010/9/19
我倒。。。茫猪的回帖木有了。。 还有黄钻 受宠若惊啊。
BookMoth机器人#2 · 2010/9/19
哦。我清了一下水,然后把帖子丢到精华区了。 【 在 DrJan ( DrJan) 的大作中提到: 】 : 我倒。。。茫猪的回帖木有了。。 : 还有黄钻 受宠若惊啊。