一种Reflective DLL注入后的DLL卸载处理

2024-03-25 21:28

本文主要是介绍一种Reflective DLL注入后的DLL卸载处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概念

Reflective DLL injection,即反射型DLL注入,是一种库注入技术,其中采用反射编程的概念来执行将库从内存加载到主机进程中的操作。因此,该库负责通过实现最小的可移植可执行(PE)文件加载器来加载自身。然后,它可以通过与主机系统和进程的最小交互来控制它将如何加载并与主机交互。
反射DLL注入是一种允许攻击者从内存注入,而不是从磁盘文件将DLL注入目标进程的技术。

概述

假设我们在主机进程中执行代码,并且我们希望注入的库已写入主机进程中内存的任意位置,反射 DLL 注入的工作原理如下:

  • 执行通过 CreateRemoteThread() 或小型引导 shellcode 传递到库的 ReflectiveLoader 函数,该函数是库导出表中的导出函数。
  • 由于库的图像当前存在于内存中的任意位置,ReflectiveLoader 将首先计算其自己的图像在内存中的当前位置,以便能够解析其自己的标头以供稍后使用。
  • 然后ReflectiveLoader将解析主机进程kernel32.dll导出表,以计算加载程序所需的三个函数的地址,即LoadLibraryA、GetProcAddress和VirtualAlloc。
  • ReflectiveLoader 现在将分配一个连续的内存区域,它将继续加载自己的图像。该位置并不重要,因为加载程序稍后会正确地重新定位图像。
  • 库的标头和节被加载到内存中的新位置。
  • 然后 ReflectiveLoader 将处理新加载的图像导入表副本,加载任何其他库并解析它们各自的导入函数地址。
  • 然后 ReflectiveLoader 将处理新加载的图像重定位表副本。
  • 然后 ReflectiveLoader 将使用 DLL_PROCESS_ATTACH 调用其新加载的图像的入口点函数 DllMain。该库现已成功加载到内存中。
  • 最后,ReflectiveLoader 将返回执行到调用它的初始引导 shellcode,或者如果通过 CreateRemoteThread 调用它,则线程将终止。
    参考代码:Reflective DLL Injection

需求

在某些业务场景下,希望在被注入进程退出时进行一些额外的操作。一般情况下,在一个进程中,通过LoadLibrary或者通过CreateRemoteThread方式LoadLibrary的DLL,在进程退出时都会调用DLL的DLL_PROCESS_DETACH方法,这样可以在此时做一些清理工作。
通过反射注入的DLL,因为在内存中自己实现对DLL的映射加载,没有调用系统API LoadLibrary函数,导致进程退出时,注入的DLL中的DLL_PROCESS_DETACH不会触发,无法实现后期的清理动作。
大致流程

方案

当调用LoadLibrary加载DLL时,基本流程如下:
在这里插入图片描述
Peb->Ldr->InInitializationOrderModuleList记录了加载后的DLL相关信息,包含DLL的DllMain方法,即:EntryPoint方法,最后触发DLL中的DLL_PROCESS_ATTACH。

当调用FreeLibrary时,基本流程如下:
在这里插入图片描述
这里,通过遍历InInitializationOrderModuleList链表,当卸载某一系统dll时,Hook掉它的EntryPoint方法,即可实现在进程退出时进行后期的清理工作

		pListHeader = &pLdr->InInitializationOrderModuleList;pListEntry = (PLIST_ENTRY64)pListHeader->Flink;for (;;){if ( pListEntry == pListHeader ){break;}ldrDataTable = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY64, InInitializationOrderModuleList);if ( _wcsicmp((PWCHAR)ldrDataTable->BaseDllName.Buffer, L"kernel32.dll") == 0 ){// Found itldrDataTable->EntryPoint = (ULONG64)DllMainDummy;break;}pListEntry = (PLIST_ENTRY64)pListEntry->Flink;}
BOOL APIENTRY DllMainDummy( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{WCHAR Name[MAX_PATH] = {0};GetModuleFileNameW(hModule, Name, MAX_PATH);switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:wprintf(L"DllMainDummy: Hooked DLL_PROCESS_ATTACH, %ws \r\n", Name);break;case DLL_PROCESS_DETACH:wprintf(L"DllMainDummy: Hooked DLL_PROCESS_DETACH, %ws \r\n", Name);FreeLibrary(hModule);break;}return TRUE;
}

此时,当进程退出时,就会卸载kernel32.dll,调用kernel32.dll中的DLL_PROCESS_DETACH分支,此时的kernel32.dll中EntryPoint已经被Hook掉了,就会触发我们的DllMainDummy方法。

这篇关于一种Reflective DLL注入后的DLL卸载处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/846292

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

Thymeleaf:生成静态文件及异常处理java.lang.NoClassDefFoundError: ognl/PropertyAccessor

我们需要引入包: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>sp

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

一种改进的red5集群方案的应用、基于Red5服务器集群负载均衡调度算法研究

转自: 一种改进的red5集群方案的应用: http://wenku.baidu.com/link?url=jYQ1wNwHVBqJ-5XCYq0PRligp6Y5q6BYXyISUsF56My8DP8dc9CZ4pZvpPz1abxJn8fojMrL0IyfmMHStpvkotqC1RWlRMGnzVL1X4IPOa_  基于Red5服务器集群负载均衡调度算法研究 http://ww

明明的随机数处理问题分析与解决方案

明明的随机数处理问题分析与解决方案 引言问题描述解决方案数据结构设计具体步骤伪代码C语言实现详细解释读取输入去重操作排序操作输出结果复杂度分析 引言 明明生成了N个1到500之间的随机整数,我们需要对这些整数进行处理,删去重复的数字,然后进行排序并输出结果。本文将详细讲解如何通过算法、数据结构以及C语言来解决这个问题。我们将会使用数组和哈希表来实现去重操作,再利用排序算法对结果

PHP防止SQL注入详解及防范

SQL 注入是PHP应用中最常见的漏洞之一。事实上令人惊奇的是,开发者要同时犯两个错误才会引发一个SQL注入漏洞。 一个是没有对输入的数据进行过滤(过滤输入),还有一个是没有对发送到数据库的数据进行转义(转义输出)。这两个重要的步骤缺一不可,需要同时加以特别关注以减少程序错误。 对于攻击者来说,进行SQL注入攻击需要思考和试验,对数据库方案进行有根有据的推理非常有必要(当然假设攻击者看不到你的

PHP防止SQL注入的方法(2)

如果用户输入的是直接插入到一个SQL语句中的查询,应用程序会很容易受到SQL注入,例如下面的例子: $unsafe_variable = $_POST['user_input'];mysql_query("INSERT INTO table (column) VALUES ('" . $unsafe_variable . "')"); 这是因为用户可以输入类似VALUE”); DROP TA

PHP防止SQL注入的方法(1)

(1)mysql_real_escape_string – 转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集 使用方法如下: $sql = "select count(*) as ctr from users where username ='".mysql_real_escape_string($username)."' and password='". mysql_r