zoukankan      html  css  js  c++  java
  • 利用中转输出表制作HijackDll(附工具源码)

    标 题: 【原创】利用中转输出表制作HijackDll(附工具源码)
    作 者: baixinye
    时 间: 2012-08-05,16:48:45
    链 接: http://bbs.pediy.com/showthread.php?t=154269

    众所周知,PE文件中的导出表指向一个IMAGE_EXPORT_DIRECTORY结构,该结构定义如下:

    typedef struct _IMAGE_EXPORT_DIRECTORY {
        DWORD   Characteristics;
        DWORD   TimeDateStamp;
        WORD    MajorVersion;
        WORD    MinorVersion;
        DWORD   Name;
        DWORD   Base;
        DWORD   NumberOfFunctions;
        DWORD   NumberOfNames;
        DWORD   AddressOfFunctions;     // RVA from base of image
        DWORD   AddressOfNames;         // RVA from base of image
        DWORD   AddressOfNameOrdinals;  // RVA from base of image
    } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

    其中AddressOfFunctions指向的是一个RVA数组,而这些RVA在“正常情况”下就是每个导出函数在内存中相对于文件头的偏移,在PE加载到内存中后,经过简单的计算就能得到每个导出函数的实际地址!

    上面说了在“正常情况”下,那么在某些特殊情况下,这些RVA指向的就不是函数地址偏移了,如果一个导出函数的RVA在导出表地址范围内,那么它就是一个中转输出。
    比如说,导出表的VirtualAddress等于0x3000,size等于0x200,如果导出函数的RVA落在0x3000到0x3200之间,这个导出函数就是一个中转输出。

    如果导出函数是一个中转输出,那么此时的RVA指向一个以零结尾的字符串组成的DLL的名称和一个用点分开的输出函数的名称,象“otherdll.exportname”这样,或者是DLL的名称和导出序号,象“otherdll.#19”这样。

    举个实际的例子,Kernel32.dll中的HeapAlloc函数就是一个中转输出,该函数的RVA指向的是一个零结尾的字符串“NTDLL.RtlAllocateHeap”,这表明了该函数被调用或者被其它模块引用时被重定位到NTDLL的RtlAllocateHeap函数中

    ,而Kernel32.dll中不存在该函数的任何代码,见下图所示:




    OK,有了这些基础,我们试想以下,如果把一个目标DLL的导出函数名称以及以序号导出的函数序号获取到,然后在自己写的某个DLL中将这些信息“复制”过来,那么我们自己的DLL文件就有了目标DLL的所有导出函数,如果有应用程序调用我们的DLL的导出函数那么都会重定向到目标DLL中!

    目标DLL(被劫持的DLL)和我们自己的DLL可以在同一个文件夹下,这样中转输出的DLL名要和修改后的被劫持的DLL名一致!后面会举例介绍。
    (也可以劫持不在同一个文件夹下的DLL,这种情况下中转DLL名需要填写为被劫持DLL的绝对路径,比如 C:\windows\system32\lpk),

    为此,我写了一个小工具来辅助我们生成这样的DLL,如图:



    使用方法如下:
    1、提供导出表的DLL后面我们选择需要Hijack的DLL路径
    2、修改导出表的DLL后面选择我们自己写的DLL文件,一般来说我们制作的恶意DLL只关注DllMain部分,所以我们只需要将功能代码写在DllMain处
    3、中转DLL名字后面填写需要Hijack的DLL名,这个地方不要加DLL后缀(也可以填写DLL的绝对路径,比如 C:\windows\system32\lpk)
    4、选择以新增节还是扩大最后一个节的方式插入我们的中转函数信息
    5、点击生成后写入需要生成的dll名

    这样一个包含中转输出的DLL就生成了,我们将它放在需要劫持的DLL的同一个目录下,然后将被劫持的DLL改名为填写的中转DLL名,将生成的中转DLL名改为被劫持的DLL的原来的名字,这样在应用程序显式或者隐式调用被劫持DLL的时候就会加载我们的DLL!

    我们使用两种方法来演示如何使用该方法劫持DLL!

    第一种方法,劫持相同目录下的DLL文件:

    我们用QQ目录下的Common.dll来做这个试验,test.dll是我写的一个很简单的DLL,dllmain中创建了一个线程,线程中弹出一个MessageBox以表示DLL被劫持!

    首先选择QQ\Bin\Common.dll和我们的test.dll,中转输出名填写“Bommon”



    然后生成一个Common.dll的中转Dll,注意不要覆盖了QQ的原始Common.dll,保存到另外一个地方



    最后我们将QQ目录下的原始Common.dll改名为何中转输出名一致的Bommon,最后将我们生成的Common.dll复制到QQ\Bin目录中



    可以看到,我们的HijackDll具备了和目标Dll完全一样的导出信息:



    启动QQ,完美劫持了Common.dll



    第二种方法,劫持系统目录下的DLL文件(或者说在dll搜索路径中的某个dll文件):

    该方法就是将中转DLL名填写为绝对路径,比如我们劫持msimg32.dll,提供导出表我们选择系统目录下的msimg32.dll,需要修改导出表的DLL我们选择测试的test.dll,最重要的中转DLL名字我们填写为:C:\windows\system32\msimg32
    如图:



    然后将生成的msimg32.dll放到QQ\bin下,照样完美劫持!


    使用中转函数名进行DLL劫持方法的优点:
    1、大家可以专心于劫持DLL的功能开发,而不用去费力写导出函数的中转跳转,写好我们的劫持DLL后只需用工具就能把导出信息复制过来
    2、对于某些被劫持的DLL的导出函数地址是一个数据段地址的情况,该方法就不会出错,因为我们只是将地址中转,如果使用以前的DLL劫持方法,必须要将导出函数地址中的这个数据段内容复制过来,而复制多大的数据是一个难点,因为我们不知道被劫持DLL的这个数据段导出地址导出的是一系列数据(结构)还是一个变量!稍有不慎就会出错!
    3、同目录下的DLL劫持只需要将被劫持的DLL文件改个名字,而其它目录下的DLL劫持只需要知道被劫持DLL的路径
    4、如果将程序中的代码用在病毒技术中,则可以实现随机、任意、动态的DLL劫持,比如恶意代码可以在QQ\Bin目录下随机选择某个Dll来进行Dll劫持,只需要动态将DLL输出信息“复制”到恶意的DLL中,然后将被劫持的DLL改个名字即可,或者随机从系统目录中选择需要劫持的DLL复制到目标程序的目录下进行劫持(也可以直接将中转Dll名设置为被劫持Dll所在的路径)!

    该方法的缺点:
    1、劫持其它目录下的DLL文件需要预先知道该DLL文件的绝对路径

    附件为AddExport.exe源码以及用于测试的test.dll文件,AddExport.rar中的代码有个小BUG,修改后的代码上传为:AddExport_fix.rar

  • 相关阅读:
    时空地图TimeGIS 可编辑ArcGIS的Shape矢量文件的地理信息系统
    快手 KSCAD 5.0 矢量图形设计软件
    DWG2SHP DXF2SHP 如何把AutoCAD的DWG,DXF文件转换为Esri ArcGIS的Shape文件
    火了网址
    GIS 网站参考
    快手4.0 (KSCAD)
    用词法分析器Flex过滤日志
    编译器工具 Flex Bison for Windows 简单入门例子
    针对于网络安全领域中基于PCAP流量的数据集
    RBAC权限框架_MVC权限框架
  • 原文地址:https://www.cnblogs.com/FCoding/p/2640989.html
Copyright © 2011-2022 走看看