`
jandroid
  • 浏览: 1904769 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

DLL是如何运做的?

 
阅读更多
一、从DLL技术说起

要了解DLL木马,就必须知道这个“DLL”是什么意思,所以,让我们追溯到几年前,DOS系统大行其道的日子里。在那时候,写程序是一件繁琐的事情,因为每个程序的代码都是独立的,有时候为了实现一个功能,就要为此写很多代码,后来随着编程技术发展,程序员们把很多常用的代码集合(通用代码)放进一个独立的文件里,并把这个文件称为“库”(Library),在写程序的时候,把这个库文件加入编译器,就能使用这个库包含的所有功能而不必自己再去写一大堆代码,这个技术被称为“静态链接”(StaticLink)。静态链接技术让劳累的程序员松了口气,一切似乎都很美好。可是事实证明,美好的事物不会存在太久,因为静态链接就像一个粗鲁的推销员,不管你想不想要宣传单,他都全部塞到你的手上来。写一个程序只想用到一个库文件包含的某个图形效果,就因为这个,你不得不把这个库文件携带的所有的图形效果都加入程序,留着它们当花瓶摆设,这倒没什么重要,可是这些花瓶却把道路都阻塞了——静态链接技术让最终的程序成了大块头,因为编译器把整个库文件也算进去了。

时代在发展,静态链接技术由于天生的弊端,不能满足程序员的愿望,人们开始寻找一种更好的方法来解决代码重复的难题。后来,Windows系统出现了,时代的分水岭终于出现。Windows系统使用一种新的链接技术,这种被称为“动态链接”(DynamicLink)的新技术同样也是使用库文件,微软称它们为“动态链接库”——DynamicLinkLibrary,DLL的名字就是这样来的。动态链接本身和静态链接没什么区别,也是把通用代码写进一些独立文件里,但是在编译方面,微软绕了个圈子,并没有采取把库文件加进程序的方法,而是把库文件做成已经编译好的程序文件,给它们开个交换数据的接口,程序员写程序的时候,一旦要使用某个库文件的一个功能函数,系统就把这个库文件调入内存,连接上这个程序占有的任务进程,然后执行程序要用的功能函数,并把结果返回给程序显示出来,在我们看来,就像是程序自己带有的功能一样。完成需要的功能后,这个DLL停止运行,整个调用过程结束。微软让这些库文件能被多个程序调用,实现了比较完美的共享,程序员无论要写什么程序,只要在代码里加入对相关DLL的调用声明就能使用它的全部功能。最重要的是,DLL绝对不会让你多拿一个花瓶,你要什么它就给你什么,你不要的东西它才不会给你。这样,写出来的程序就不能再携带一大堆垃圾了——绝对不会让你把吃剩的东西带回家,否则罚款,这是自助餐。

DLL技术的诞生,使编写程序变成一件简单的事情,Windows为我们提供了几千个函数接口,足以满足大多数程序员的需要。而且,Windows系统自身就是由几千个DLL文件组成,这些DLL相互扶持,组成了强大的Windows系统。如果Windows使用静态链接技术,它的体积会有多大?我不敢想。

二、应用程序接口API

上面我们对DLL技术做了个大概分析,在里面我提到了“接口”,这又是什么呢?因为DLL不能像静态库文件那样塞进程序里,所以,如何让程序知道实现功能的代码和文件成了问题,微软就为DLL技术做了标准规范,让一个DLL文件像奶酪一样开了许多小洞,每个洞口都注明里面存放的功能的名字,程序只要根据标准规范找到相关洞口就可以取得它要的美味了,这个洞口就是“应用程序接口”(ApplicationProgrammingInterface),每个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木马多,写得多了自己都烦躁……



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

http://support.microsoft.com/default.aspx?scid=kb;zh-cn;815065

微软对DLL的定义和说明:
概要
本文说明什么是动态链接库(DLL)以及在使用DLL时可能发生的各种问题。

然后,本文说明在开发您自己的DLL时应该考虑的一些高级问题。在说明什么是DLL的过程中,本文将说明动态链接方法、DLL依赖性、DLL入口点、导出DLL函数以及DLL故障排除工具。

本文最后将从较高的层次对DLL与Microsoft.NETFramework程序集作一比较。


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

动态链接库(DynamicLinkLibrary,缩写为DLL)是一个作为共享函数库的可执行文件,它使进程可以调用不属于本身可执行代码中的函数。函数的可执行代码位于一个独立的动态链接库文件中,这样可以节省内存和磁盘的存储空间,同时使程序更易于升级。
分享到:
评论

相关推荐

    RING3反外挂系统vc6.0版(dll版特征码+数据共享)

    没有采用驱动技术,而是采用了大众化的动态链接库技术(DLL),兼容性强,可在xp 、win7、 win8 等操作系统上运作。 功能如下: 1、启动线程检测 网速主流和非主流内存搜索工具的检测(比如金山游侠、ce等) 2、启动...

    【原创-实例】DLL文件的调用(DLL启动器)-MCCS开发团队制作

    一个关于外部DLL调用的实例,调用的是DLL里的方法,很多新手对于这一块有很多问题,这个简洁的实例可以让你马上明白类的使用! 只要一个积分,算是支持一下团队的运作吧!!!

    TCtrl.dll v1.05

    Demo_2:FormatEdit控件回调校验函数的信息浏览器,有助于了解控件的内部运作机制。 Demo_3:一个基于TCtrl.dll的实用小程序,可以帮你批量设置文件的时间戳,支持通配符 “*”、“?”及子目录查找。当发布软件时...

    iec61850功能库

    IEC61850标准是电力系统自动化领域唯一的全球通用标准。...文件包含IEC61850相关的多个DLL,iec61850.dll,iec61850dotnet.dll,nunit.framework.dll,前两个是必须的在工程中引用第二个,即可使用相关的接口功能

    完整体检系统

    该系统完全符合医院的信息化需求并通过了医院的实际运作检验,不仅操作灵活、维护方便、功能强大,并实现了与国内多家医疗软件公司的HIS及LIS系统的相对接

    QtKvaser:在Qt中使用Kvaser canlib32.dll的演示应用程序

    这个怎么运作 这个小型演示应用程序是在一个晚上制作的,基于先前使用不同品牌界面的尝试而失败。 您可以连接并搭乘公交车。 接收所有消息,并使用输入字段发送一些消息。 二进制文件 bin文件夹中提供了Windows的已...

    WebPrinter:适用于所有网络浏览器的打印机

    这个怎么运作? 核心是本地的http监听。让网页javascript将数据发送到本地http服务。 当本地服务收到命令时,它将处理该命令。 它是什么? 它使用C#语言Asp.net Mvc自托管! 我们知道katana项目,是的,它是asp...

    IEC61850源码vb.net实例,客户端、服务端、登录等操作源码。

    IEC61850源码vb.net实例,客户端、服务端、登录等操作源码。非常好的资源,新手可以认真研究一下。里面的模块直接可以用。里面包含了有iec61850dotnet.dll。欢迎加入智能变电站的工程运作标准化。

    WINDOWS系统文件详解

    所谓的系统文件一般指的是与Windows有密切关系的,系统正常运作所离不开的文件。这些文件绝大多数位于System32目 录下(X:\Windows\System32\) 以及系统文件备份目录DllCache下(X:\Windows\System32\Dllcache\)...

    简单易用的脚本编程工具 AutoIt 3.3.12.0 中文免费版.zip

    AutoIt 目前最新是v3版本,这是一个使用类似BASIC脚本...最重要的是,AutoIt 将继续是免费的 – 但是如果您打算支持我们花在此工程的时间,金钱以及所作努力和网站主机运作的话,那么您可以到AutoIt 的主页上进行捐赠。

    winapi-hooking-demo:小示例如何使用导入地址表(IAT)挂钩winapi函数

    这是如何运作的? 从Windows动态库(DLL)导出的函数存储在可移植可执行(PE)标头中,然后直接映射到进程内存。 然后,当某些代码想要调用这些函数时,通常可以通过调用函数来查询该表。 由于此表只是存储在进程...

    IEC61850 Standard.zip

    IEC61850标准是电力系统自动化领域唯一的全球通用标准。它通过标准的实现,实现了智能变电站的工程运作标准化。使得智能变电站的工程实施变得规范、统一和透明。iec 61850系列标准,包括1-10系列,共15个标准。

    iec61850动态库

    IEC61850标准是电力系统自动化领域唯一的全球通用标准。...文件包含IEC61850相关的多个DLL,iec61850.dll,iec61850dotnet.dll,nunit.framework.dll,前两个是必须的在工程中引用第二个,即可使用相关的接口功能

    z-engine:PHP引擎直接API

    这个怎么运作? 如您所知,PHP 7.4版包含一个名为的新功能。 它允许在纯PHP中加载共享库(.dll或.so),调用C函数以及访问C数据结构,而无需深入了解Zend扩展API,也无需学习第三种“中间”知识。 “ 语。 Z-...

    Delphi深度编程技术

    5.2.4 DLL实例:动态DLL中的窗体 5.3 DLL的调用 5.3.1 静态调用 5.3.2 动态调用 5.4 DLL的入口函数和出口函数 5.4.1 进程/线程的初始化和例程的终止 5.4.2 DLL入口/出口示例 5.5 利用DLL创建插件程序 ...

    《Delphi 深度编程及其项目应用开发》PDF书及代码

    7.2.1 多层应用系统的结构 7.2.2 存取数据的运作原理 7.2.3 更新数据的运作原理 7.3 容错处理和负载平衡 7.4 Active Form 第8章 Socket编程 8.1 WinSock基础 8.1.1 TCP、UDP和IP协议 8.1.2 套接字(Socket) 8.1.3 ...

    SocksOverRDP:Socks544a对远程桌面协议终端服务的代理支持Citrix XenApp XenDesktop

    RDP上的袜子/ Citrix上的袜子 该工具将SOCKS代理功能添加到...这是如何运作的? 如果DLL已正确注册,则每次启动时,它将由mstsc.exe(远程桌面客户端)或Citrix Receiver加载。当服务器可执行文件在服务器端运行时,

    webcontrols

    你只需指示LISTBOX 在服务器里运作并代你进行管理就可以了。更为方便的是,你只需设定好程序,LISTBOX就会按指令依次显示选定的项目。 也许在这个新的 controls中最有趣的莫过于 DataGrid。Datagrid是一个多列的数据...

    音频隐写_audacity_win_V2.1.0.0_setup.1442397077.exe.7z

    可在Mac OS X、Microsoft Windows、GNU/Linux和其它操作系统上运作。Audacity在2004年7月获选为SourceForge .net当月最佳推荐项目,2007年7月选多媒体类的SourceForge .net 2007 Community Choice Awards 。

    win10专业版ttf16.ocx缺失处理.rar

    亲测win10专业版可行,其他版本未尝试。

Global site tag (gtag.js) - Google Analytics