标题：DLL木马
DLL 木马揭秘
相信经常玩木马的朋友们都会知道一些木马的特性，也会有自己最喜爱的木马，不过，很多朋友依然不知道近年兴起的“DLL木马”为何物。什么是“DLL木马”呢？它与一般的木马有什么不同？一、从DLL技术说起要了解DLL木马，就必须知道这个“DLL[1]”是什么意思，所以，让我们追溯到几年前，DOS系统大行其道的日子里。在那时候，写程序是一件繁琐的事情，因为每个程序的代码都是独立的，有时候为了实现一个功能，就要为此写很多代码，后来随着编程技术发展，程序员们把很多常用的代码集合（通用代码）放进一个独立的文件里，并把这个文件称为“库”（Library），在写程序的时候，把这个库文件加入编译器，就能使用这个库包含的所有功能而不必自己再去写一大堆代码，这个技术被称为“静态链接”（Static Link）。静态链接技术让劳累的程序员松了口气，一切似乎都很美好。可是事实证明，美好的事物不会存在太久，因为静态链接就像一个粗鲁的推销员，不管你想不想要宣传单，他都全部塞到你的手上来。写一个程序只想用到一个库文件包含的某个图形效果，就因为这个，你不得不把这个库文件携带的所有的图形效果都加入程序，留着它们当花瓶摆设，这倒没什么重要，可是这些花瓶却把道路都阻塞了——静态链接技术让最终的程序成了大块头，因为编译器把整个库文件也算进去了。二、静态链接技术时代在发展，静态链接技术由于天生的弊端，不能满足程序员的愿望，人们开始寻找一种更好的方法来解决代码重复的难题。后来，Windows系统出现了，时代的分水岭终于出现。Windows系统使用一种新的链接技术，这种被称为“动态链接”（Dynamic Link）的新技术同样也是使用库文件，微软称它们为“动态链接库”——Dynamic Link Library，DLL的名字就是这样来的。动态链接本身和静态链接没什么区别，也是把通用代码写进一些独立文件里，但是在编译方面，微软绕了个圈子，并没有采取把库文件加进程序的方法，而是把库文件做成已经编译好的程序文件，给它们开个交换数据的接口，程序员写程序的时候，一旦要使用某个库文件的一个功能函数，系统就把这个库文件调入内存，连接上这个程序占有的任务进程，然后执行程序要用的功能函数，并把结果返回给程序显示出来，在我们看来，就像是程序自己带有的功能一样。完成需要的功能后，这个DLL停止运行，整个调用过程结束。微软让这些库文件能被多个程序调用，实现了比较完美的共享，程序员无论要写什么程序，只要在代码里加入对相关DLL的调用声明就能使用它的全部功能。最重要的是，DLL绝对不会让你多拿一个花瓶，你要什么它就给你什么，你不要的东西它才不会给你。这样，写出来的程序就不能再携带一大堆垃圾了——绝对不会让你把吃剩的东西带回家，否则罚款，这是自助餐。 
DLL技术的诞生，使编写程序变成一件简单的事情，Windows为我们提供了几千个函数接口，足以满足大多数程序员的需要。而且，Windows系统自身就是由几千个DLL文件组成，这些DLL相互扶持，组成了强大的Windows系统。如果Windows使用静态链接技术，它的体积会有多大？我不敢想。三、应用程序接口API上面我们对DLL技术做了个大概分析，在里面我提到了“接口”，这又是什么呢？因为DLL不能像静态库文件那样塞进程序里，所以，如何让程序知道实现功能的代码和文件成了问题，微软就为DLL技术做了标准规范，让一个DLL文件像奶酪一样开了许多小洞，每个洞口都注明里面存放的功能的名字，程序只要根据标准规范找到相关洞口就可以取得它要的美味了，这个洞口就是“应用程序接口”（Application Programming Interface），每个DLL带的接口都不相同，尽最大可能的减少了代码的重复。用Steven的一句话：API就是一个工具箱，你根据需要取出螺丝刀、扳手，用完后再把它们放回原处。在Windows里，最基本的3个DLL文件是kernel32.dll、user32.dll、gdi32.dll。它们共同构成了基本的系统框架。四、DLL与木马DLL是编译好的代码，与一般程序没什么大差别，只是它不能独立运行，需要程序调用。那么，DLL与木马能扯上什么关系呢？如果你学过编程并且写过DLL，就会发现，其实DLL的代码和其他程序几乎没什么两样，仅仅是接口和启动模式不同，只要改动一下代码入口，DLL就变成一个独立的程序了。当然，DLL文件是没有程序逻辑的，这里并不是说DLL=EXE，不过，依然可以把DLL看做缺少了main入口的EXE，DLL带的各个功能函数可以看作一个程序的几个函数模块。DLL木马就是把一个实现了木马功能的代码，加上一些特殊代码写成DLL文件，导出相关的API，在别人看来，这只是一个普通的DLL，但是这个DLL却携带了完整的木马功能，这就是DLL木马的概念。也许有人会问，既然同样的代码就可以实现木马功能，那么直接做程序就可以，为什么还要多此一举写成DLL呢？这是为了隐藏，因为DLL运行时是直接挂在调用它的程序的进程里的，并不会另外产生进程，所以相对于传统EXE木马来说，它很难被查到。五、DLL的运行虽然DLL不能自己运行，可是Windows在加载DLL的时候，需要一个入口函数，就如同EXE的main一样，否则系统无法引用DLL。所以根据编写规范，Windows必须查找并执行DLL里的一个函数DllMain作为加载DLL的依据，这个函数不作为API导出，而是内部函数。DllMain函数使DLL得以保留在内存里，有的DLL里面没有DllMain函数，可是依然能使用，这是因为Windows在找不到DllMain的时候，会从其它运行库中找一个不做任何操作的缺省DllMain函数启动这个DLL使它能被载入，并不是说DLL可以放弃DllMain函数。
DLL木马技术分析
到了这里，您也许会想，既然DLL木马有那么多好处，以后写木马都采用DLL方式不就好了吗？话虽然是这么说没错，但是DLL木马并不是一些人想象的那么容易写的。要写一个能用的DLL木马，你需要了解更多知识。1.木马的主体千万别把木马模块写得真的像个API库一样，这不是开发WINAPI。DLL木马可以导出几个辅助函数，但是必须有一个过程负责主要执行代码，否则这个DLL只能是一堆零碎API函数，别提工作了。 
如果涉及一些通用代码，可以在DLL里写一些内部函数，供自己的代码使用，而不是把所有代码都开放成接口，这样它自己本身都难调用了，更不可能发挥作用。 
DLL木马的标准执行入口为DllMain，所以必须在DllMain里写好DLL木马运行的代码，或者指向DLL木马的执行模块。2.动态嵌入技术Windows中，每个进程都有自己的私有内存空间，别的进程是不允许对这个私人领地进行操作的，但是，实际上我们仍然可以利用种种方法进入并操作进程的私有内存，这就是动态嵌入，它是将自己的代码嵌入正在运行的进程中的技术。动态嵌入有很多种，最常见的是钩子、API以及远程线程技术，现在的大多数DLL木马都采用远程线程技术把自己挂在一个正常系统进程中。其实动态嵌入并不少见，罗技的MouseWare驱动就挂着每一个系统进程-_- 
远程线程技术就是通过在另一个进程中创建远程线程（RemoteThread）的方法进入那个进程的内存地址空间。在DLL木马的范畴里，这个技术也叫做“注入”，当载体在那个被注入的进程里创建了远程线程并命令它加载DLL时，木马就挂上去执行了，没有新进程产生，要想让木马停止惟有让挂接这个木马DLL的进程退出运行。但是，很多时候我们只能束手无策——它和Explorer.exe挂在一起了，你确定要关闭Windows吗？3.木马的启动有人也许会迫不及待的说，直接把这个DLL加入系统启动项目不就可以了。答案是NO，前面说过，DLL不能独立运行，所以无法在启动项目里直接启动它。要想让木马跑起来，就需要一个EXE使用动态嵌入技术让DLL搭上其他正常进程的车，让被嵌入的进程调用这个DLL的DllMain函数，激发木马运行，最后启动木马的EXE结束运行，木马启动完毕。 
启动DLL木马的EXE是个重要角色，它被称为Loader，如果没有Loader，DLL木马就是破烂一堆，因此，一个算得上成熟的DLL木马会想办法保护它的Loader不会那么容易被毁灭。记得狼狈为奸的故事吗？DLL木马就是爬在狼Loader上的狈。 
Loader可以是多种多样的，Windows的rundll32.exe也被一些DLL木马用来做了Loader，这种木马一般不带动态嵌入技术，它直接挂着rundll32进程运行，用rundll32的方法（rundll32.exe [DLL名],[函数] [参数]）像调用API一样去引用这个DLL的启动函数激发木马模块开始执行，即使你杀了rundll32，木马本体还是在的，一个最常见的例子就是3721中文实名，虽然它不是木马。 
注册表的AppInit_DLLs键也被一些木马用来启动自己，如求职信病毒。利用注册表启动，就是让系统执行DllMain来达到启动木马的目的。因为它是kernel调入的，对这个DLL的稳定性有很大要求，稍有错误就会导致系统崩溃，所以很少看到这种木马。 
有一些更复杂点的DLL木马通过svchost.exe启动，这种DLL木马必须写成NT-Service，入口函数是ServiceMain，一般很少见，但是这种木马的隐蔽性也不错，而且Loader有保障。4.其它到这里大家也应该对DLL木马有个了解了，是不是很想写一个？别急，不知道大家想过没有，既然DLL木马这么好，为什么到现在能找到的DLL木马寥寥无几？现在让我来泼冷水，最重要的原因只有一个：由于DLL木马挂着系统进程运行，如果它本身写得不好，例如没有防止运行错误的代码或者没有严格规范用户的输入，DLL就会出错崩溃。别紧张，一般的EXE也是这样完蛋的，但是DLL崩溃会导致它挂着的程序跟着遭殃，别忘记它挂接的是系统进程哦，结局就是……惨不忍睹。所以写一个能公布的DLL木马，在排错检查方面做的工作要比一般的EXE木马多，写得多了自己都烦躁……
DLL木马的发现和查杀
经常看看启动项有没有多出莫名其妙的项目，这是Loader的所在，只要杀了狼，狈就不能再狂了。而DLL木马本体比较难发现，需要你有一定编程知识和分析能力，在Loader里查找DLL名称，或者从进程里看多挂接了什么陌生的DLL，可是对新手来说……总之就是比较难啊比较难，所以，最简单的方法：杀毒软件和防火墙（不是万能药，切忌长期服用）。