[DLL注入的方法]静态修改PE输入表法

1.三种DLL加载时机:

  • 进程创建加载输入表中的DLL(静态输入)
  • 通过调用LoadLibrary主动加载(动态加载)
  • 系统预设加载

  通过干预输入表处理过程加载目标dll

1.静态修改PE输入表法(测试程序 Notepad.exe)

  • 准备工作:自行编写一个MsgDLL,到处一个函数Msg();
#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        CreateThread(NULL, 0, ThreadShow, NULL, 0, NULL);
    }

    return TRUE;
}

DWORD WINAPI ThreadShow(LPVOID lpParameter)
{
    char szPath[MAX_PATH] = { 0 };
    char szBuf[1024] = { 0 };
    //获取宿主进程的路径
    GetModuleFileName(NULL, (LPWSTR)szPath, MAX_PATH);
    sprintf(szBuf, "DLL已经注入到进程:%s\t[pid =%d]\n", szPath, GetCurrentProcessId());
    //以三种方式显示自己的存在
        //1.
    MessageBox(NULL, (LPWSTR)szBuf, "DLL存在", MB_OK);

    //2.
    printf("%s\n", szBuf);
    //3.
    OutputDebugString((LPWSTR)szBuf);
    return 0;
}                

参数意义:

①hModule参数:指向DLL本身的实例句柄;

②ul_reason_for_call参数:指明了DLL被调用的原因,可以有以下4个取值:

1. DLL_PROCESS_ATTACH:
当DLL被进程 <<第一次>> 调用时,导致DllMain函数被调用,

同时ul_reason_for_call的值为DLL_PROCESS_ATTACH,

如果同一个进程后来再次调用此DLL时,操作系统只会增加DLL的使用次数,

不会再用DLL_PROCESS_ATTACH调用DLL的DllMain函数。

2.DLL_PROCESS_DETACH:
当DLL被从进程的地址空间解除映射时,系统调用了它的DllMain,传递的ul_reason_for_call值是DLL_PROCESS_DETACH。
★如果进程的终结是因为调用了TerminateProcess,系统就不会用DLL_PROCESS_DETACH来调用DLL的DllMain函数。这就意味着DLL在进程结束前没有机会执行任何清理工作。

3.DLL_THREAD_ATTACH:
当进程创建一线程时,系统查看当前映射到进程地址空间中的所有DLL文件映像,

并用值DLL_THREAD_ATTACH调用DLL的DllMain函数。

新创建的线程负责执行这次的DLL的DllMain函数,

只有当所有的DLL都处理完这一通知后,系统才允许线程开始执行它的线程函数。

4.DLL_THREAD_DETACH:
如果线程调用了ExitThread来结束线程(线程函数返回时,系统也会自动调用ExitThread),

系统查看当前映射到进程空间中的所有DLL文件映像,

并用DLL_THREAD_DETACH来调用DllMain函数,

通知所有的DLL去执行线程级的清理工作。
★注意:如果线程的结束是因为系统中的一个线程调用了TerminateThread,

系统就不会用值DLL_THREAD_DETACH来调用所有DLL的DllMain函数。

③lpReserved参数:保留

  • 第二步:判断是否还有足够的空间存储我们的导出函数  -----》(PE格式知识)

    •  )如果空间不足,那么我们则需要采取扩大节或者新增节来进行位置存储;
    • Notepad无法存储我们的导出函数,那么我这里采取扩大最后一个节的方法

根据PE格式可以看到再数据目录项中的导入表RVA为00007604

那么我们这里讲RVA转成FOA文件偏移 :0x7604 -0x1000(Virtual Address) + 0x400 (Raw Address) =0x6a04     ---》PE知识,看不懂重学PE

然后用16进制软件打开notepad,我这里使用的是010 editor:

首先我们可以看到一个导入表的结构为20字节也就是16h,输入表中,每20个字节(一个Image_Import_Directory)对应一个动态链接库Dll的调用数据:

并且导入表是连续的,直到它以一组0x14大小的全0的结束标记来结束

定位到0x6a04,如图所示,后面则是0x14大小的结束标记

接下来,我们将最后一个节区进行扩充:

将原有导入表搬入新地址(直接复制粘贴到新地址):

粘贴好后,在原有导入表区域构建新的OriginalFirstThunk、name和FirstThunk结构(注意我们粘贴后把原有导入表区域清零,腾出空间,做我们自己的结构)

首先清零

然后构建我们的OriginalFirstThunk、name和FirstThunk结构

在PE文件被加载前 ,OriginalFirstThunk和FirstThunk都是指向IMPORT_BY_NAME

根据结构我们可以知道:

  DLLName                     RawOffset =0x6A14          RVA= 0x6A14  -0x400(Raw Address)+0x1000(Virtual Address)  =0x7614

  IMPORT_BY_NAME    RawOffset =0x6A20          RVA= 0x6A20     -0x400(Raw Address)+0x1000(Virtual Address)  =0x7620

在手动填写数据的时候一定要注意字节顺序问题:

然后根据刚填充的两个结构和Name的偏移,填写新的导入表结构

OriginalFirstThunk :RawOffset =0x6a04            RVA =0x6a04  -0x400(Raw Address)+0x1000(Virtual Address)    =0x7604

FirstThunk:RawOffset =0x6a0c          RVA =   0x6a0c -0x400(Raw Address)+0x1000(Virtual Address)   =0x7620

DLLName                     RawOffset =0x6A14          RVA= 0x6A14  -0x400(Raw Address)+0x1000(Virtual Address)  =0x7614

修改完成后,我们修正PE文件头信息:

  •   输入表目录指向位置
  •   FirstThunk -》可写属性

首先修正输入表目录指向位置:

在010中定位到导入表的RVA :

将它原本指向的值修改成我们新替换的位置也就是最后一节的位置:

内存偏移 = 0XB000 +0X8000 =0X13000

文件偏移 = 0x8400+0x8000=0x10400

由于使用了原来导入表数组的位置存放FirstThunk,而它原来的位置的RVA是0X7604,根据各节的起始位置和偏移量,可以确定该节属于text节,而该节原来的属性是0X60000020,写属性定义如下

# define IMAGE_SCN_MEM_WRITE      0x800000000  //节是可写的

0x 60000020+0x80000000 =0xE0000020

然后把新节属性就是原属性加上这个值也就是0xE0000020

至此我们的修改工作全部完成,保存修改结果

接下来运行修改后的NotePad,结果MessageBox没有弹出来!

这里是因为IMAGE_IMPORT_DESCRIPTOR中定义的TimeDateStamp为0xFFFFFFFF也就是-1,表示改输入项是原来预先Bound的,如果系统检测发现预绑定是有效的,那么就不会再去处理输入表加载了,所以我们只需把0x1B0到0x1B8 内容清零再次保存即可

可以看到确实加载了我们的MsgDll.dll

原文地址:https://www.cnblogs.com/hanhandaren/p/11447317.html

时间: 2024-08-29 22:43:03

[DLL注入的方法]静态修改PE输入表法的相关文章

[转]Dll注入经典方法完整版

Pnig0s1992:算是复习了,最经典的教科书式的Dll注入. 总结一下基本的注入过程,分注入和卸载 注入Dll: 1,OpenProcess获得要注入进程的句柄 2,VirtualAllocEx在远程进程中开辟出一段内存,长度为strlen(dllname)+1; 3,WriteProcessMemory将Dll的名字写入第二步开辟出的内存中. 4,CreateRemoteThread将LoadLibraryA作为线程函数,参数为Dll的名称,创建新线程 5,CloseHandle关闭线程句

&lt;ReversingEngineering&gt;关于windows32位系统下的dll注入技术经验汇

上个学期把自己闷在图书馆一直在看关于逆向工程技术方面的书,从入门到初级,现在也敢说自己一条腿已经迈进了这片知识的大门里,因为该博客刚开通先将一些经验记录下来,也是留给自己一方面做个参照. <逆向工程核心原理>((韩)李承远 )<Reversing:逆向工程揭密(电子工业出版社)><黑客反汇编揭密>((俄)卡巴斯基 ) dll注入技术是一门逆向工程中非常基础非常初步的技术,也是打开大门的钥匙,逆向破解的前提条件.API勾取 ,Rootkit进程隐藏都需要dll注入为先决条

Windows系统的dll注入

声明:这篇博客原为本人在CSDN上发布的,但是CSDN这个网站违背了本人的分享和开源精神,另外CSDN的广告满天飞.审核重重(所有的下载必须使用CSDN下载,而下载需要积分,这严重违背本人的无私分享精神.开源精神.),即使审核通过也会不定时进行重新审核,CSDN的这些操作严重影响了本人的博客管理.因此,本着无私分享精神.开源精神.轻松使用原则,本人摒弃了CSDN,并将博文重新编辑并发布在博客园网站上,而原博文作删除处理! 一.什么是dll注入 在Windows操作系统中,运行的每一个进程都生活在

获取PE文件的输入表信息

输入表是PE文件结构中不可或缺的部分,输入表也称之为"导入表". 要想了解输入表,首先还得先从DLL文件入手.日常生活中我们会看见一些大型软件有很多的DLL格式的文件,这些文件中有很多的导入函数,这些函数不会直接被执行.当一个程序(EXE)运行时,导入函数是被程序调用执行的,其执行的代码是不在主程序(EXE)中的一小部分函数,其真正的代码却在DLL文件中.这时我们就会想,那么EXE主程序是如何找到这些需要导入的函数呢,这就要归结于“输入表”了,输入表就相当于EXE文件与DLL文件沟通的

反病毒攻防研究第011篇:DLL注入(下)——无DLL的注入

一.前言 一般来说,想要将自己编写的程序注入到其它进程中,是必须要使用DLL文件的,这种方法已经在上一篇文章中讨论过了.但是事实上,可以不依赖于DLL文件来实现注入的.只不过这种方法不具有通用性,没有DLL注入那样灵活,因为它需要把代码写入"注入程序"中,一旦想要注入的内容发生了变化,就需要重写整个"注入程序".而不像DLL注入那样,只要修改DLL程序即可.即便如此,无DLL进行注入的方式,也是一种值得讨论的方法. 二.无DLL注入的基本原理 在注入与卸载方面,无论

DLL注入之注册表

0x00 唠叨 编写本系列文章纯属为了系统学习DLL注入的方法,所以很多方法可能已经过时,希望各位看官勿喷.当然若有更好的方法,希望不腻赐教.若本文有任何错的地方,也希望各位指正.谢谢! 0x01 适用平台 windows NT/2000/XP/2003 0x02 原理 通过修改注册表键值:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs.将需要注入的DLL的绝对路径添加到该键

Dll注入方法之二

有了第一种方法,我们不难举一反三,由于原理是只需要我们的执行函数被写入到目标进程,所有相关的变量也在目标函数里,那么我们的函数就能被正确执行(前提是没有互相调用我们注入的函数,否则需要做地址处理.这也是为什么整个可执行文件注入时,要做很多重定位).这里,我们进一步尝试,将LoadLibrary放在一个函数里,在同一个函数里,我们再调用一个MessageBox(这里只是一个测试,以后你可以调用任何你的函数,但必须要对地址进行处理). 步骤一和步骤二:请参考Dll注入方法之一. 步骤三:书写需要被注

纯静态界面中(html)中通过js调用dll中的方法从数据库中读取数据

最近接到一个离职员工的任务,一个搭好框架的ERP系统,看了两天,说一下看到的东西,整个项目目录中我没发现一个.aspx后缀的文件,全是静态HTML文件,之后发现他用的jquery简直看的头疼,不过大概能看懂,发现一个可能大家会感兴趣的东西,他在静态界面中通过js对象就直接调DLL中的方法从数据库中得到数据并通过js加载出来,当时我就瞎了,他的大概过程是: 建立了多个js对象(数据库中一张表对应一个),并为这个对象添加了很多与DLL中对应的方法,比如DLL中有一个对用户表修改用户密码的操作,那他j

安全之路 —— 利用远程线程注入的方法(使用DLL)实现穿墙与隐藏进程

简介 大多数后门或病毒要想初步实现隐藏进程,即不被像任务管理器这样典型的RING3级进程管理器找到过于明显的不明进程,其中比较著名的方法就是通过远程线程注入的方法注入将恶意进程的DLL文件注入系统认可的正常进程,你会发现任务管理器以及找不到独立出现的恶意进程项了.反向连接型后门采用这种技术,注入防火墙认可的进程(例如大部分系统进程,像explorer.exe就很常见)还能够获得一定的穿墙效果. 进程注入虽然已经是将近10年前的技术了,但是今天出现的很多新型黑客技术大多数还是基于这类老技术演变而来