卡卷网
当前位置:卡卷网 / 每日看点 / 正文

游戏中注入DLL是什么意思,具体怎么实现的?

作者:卡卷网发布时间:2025-01-06 21:18浏览数量:68次评论数量:0次

一、前言

作中,资源分配的对象一般都是针对于进程来讲的,也就是说,必须先要有一个进程,接着才能分配所拥有的大量资源,所以我们的故事,要先从进程说起~

当新启动一个程序,亦或是线程调用CreateProcess来创建新的进程时,一般都有一套标准的作流程:首先,会在用户空间中打开要执行的映像文件,如果找不到,则创建失败,CreateProcess将返回FALSE;在上一步成功之后,会为该进程创建一个内核对象,以及私有空间。

保留一个足够大的空间区域,用于存放该可执行文件,当可执行exe文件被映射到进程的空间中之后,将访问exe文件的一个部分,该部分列出了包含exe文件中的代码要调用的函数的DLL文件,然后,会为每个DLL文件调用LoadLirary函数,以便加载这些DLL文件。

另外,会保留一个足够大的空间区域,用来存放该DLL文件,如果无法在该DLL的首选基上保留一个区域,其原因可能是该区域已经被另一个DLL或exe占用,也可能是因为该区域不够大,此时将设法寻找另一个空间的区域来保留该DLL的内容。

最后,当所有的exe和DLL文件都被映射到进程的空间之后,就可以开始执行exe文件的启动代码了。

对于Windows,加载动态链接库时:

    如果内存中已经有同module名的DLL,除非是DLLredirection或manifest,否则直接就用内存中这个DLL而不再搜索。如果DLL名字属于当前Windows版本的KnownDLL,则必须用KnownDLL。清单见HKEY_LOCAL_MACHINE\\CrentControlSet\Control\SessionManager\KnownDLLs.如果DLL有依赖DLL,作按缺省标准规则根据module名字搜索依赖DLL。即使第一个DLL指定了全路径。

WindowsDesktop应用程序的DLL标准搜索序:

    应用程序所在目录;目录。GetSystemDirectory函数返回该目录。16特目录;Windows目录。使用GetWindowsDirectory函数返回该目录。当前(工作)目录;环境变量PATH中列出的目录。

关于这部分DLL文件,还有很多值得讲讲的内容。

DLL的最初目的,是节约应用程序所需的磁盘和内存空间。在一个传的非共享库中,一部分代码简单地附加到调用的程序上。如果两个程序调用同一个子程序,就会出现两份那段代码。相反,许多应用共享的代码能够切分到一个DLL中,在硬盘上存为一个文件,在内存中使用一个实例(instance)。DLL的广泛应用使得早期的视窗能够在紧张的内存条件下运行。

自从Windows作以来,动态链接库(DLL)就一直作为这个作的重要组成部分所存在。WindowsAPI中的所有函数都包含在DLL中。3个最重要的DLL是Kernel32.dll,它包含用于内存、进程和线程的各个函数;User32.dll,它包含用于执行用户界面任务(如窗口的创建和消息的传送)的各个函数;GDI32.dll,它包含用于画图和显示文本的各个函数。另外还有若干DLL来执行特殊任务,如AdvAPI32.dll包含实现对象安全性,注册表作和事件记录的函数等。

使用DLL的好处也是显而易见的,例如其动态加载的机制可以扩展应用程序的特性,多个进程使用同一个DLL时无需重复在内存中加载,可以减少内存,有助于资源共享,也有助于解决程序的本地化和平台差异等。

二、关于DLL本身

创建DLL常常创建应用程序更容易,因为DLL往往只包含一组应用程序可以使用的自主函数。

在DLL中,通常没有用来处理消息循环或创建窗口的支持代码,因为DLL只是一组源代码模块,每个模块包含了应用程序(可执行文件)或另一个DLL将要调用的一组函数。当所有源代码文件编译后,它们就像应用程序的可执行文件那样被链接程序所链接。

对于一个DLL来说,你必须设定该连链程序的/DLL开关。这个开关使得链接程序能够向产生的DLL文件映像发出稍有不同的信息,这样,作加载程序就能将该文件映像视为一个DLL而不是应用程序。

在应用程序(或另一个DLL)能够调用DLL中的函数之前,DLL文件映像必须被映射到调用进程的空间中。若要进行这项作,可以使用两种方法——加载时的隐含链接或运行期的显式链接。

一旦DLL的文件映像被映射到调用进程的空间中,DLL的函数就可以供进程中运行的所有线程使用。实际上,DLL几乎将失去它作为DLL的全部特征。对于进程中的线程来说,DLL的代码和数据看上去就像恰巧是在进程的空间中的额外代码和数据一样。

当一个线程调用DLL函数时,该DLL函数要查看线程的堆栈,以便检索它传递的参数,并将线程的堆栈用于它需要的任何局部变量。此外,DLL中函数的代码创建的任何对象均由调用线程所拥有,<>而DLL本身从来不拥有任何东西。

例如,如果VirtualAlloc函数被DLL中的一个函数调用,那么将从调用线程的进程空间中保留一个空间的区域,该空间区域将始终处于保留状态,因为并不跟踪DLL中的函数保留该区域的情况。保留区域由进程所拥有,只有在线程调用VirtualFree函数或者进程终止运行时才被释放。

三、DLL注入

作中,每个进程都有它自己的私有空间。

当使用指针来引用内存时,指针的值将引用你自己进程的空间中的一个内存。你的进程不能创建一个其引用属于另一个进程的内存指针。因此,如果你的进程存在一个错误,改写了一个随机上的内存,那么这个错误不会影响另一个进程使用的内存。

是否存在方法可以打破进程的界限,访问另一个进程的空间呢?

答案是肯定的

有许多的方法可以用来将DLL到另一个进程的空间中,以便实现自己的为所欲为(

DLL注入技术,便是其中一种,其主要原理就是强制一个正在运行的进程将攻击者需要注入的dll文件加载到自身进程空间内,进而实现其后续的恶意攻击作。

注意,DLL注入技术本身是可以被用于正当合法用途的,但其同样存在被非法使用的情况。安全软件可以用其来拦截和监视,恶意软件也可以用起来入侵和攻击。如果要防范此类攻击,最一劳永逸的方法自然是取消一切合法非法的DLL注入,但显然这有些困难。

注入的方法有很多,最常见和容易理解的是CreateRemoteThread方法

由于创建的是远程线程,是需要将注入的参数(也就是Dll文件的路径)写入目标进程空间,因此通过WriteProcessMemory来申请内存空间写入DLL路径,接着调用CreateRemoteThread函数来创建一个新的线程,在该线程中调用LoadLirary来导入我们需要注入的DLL文件。

这便成功实现了一次DLL注入攻击,接着便可以展开后续恶意作了。

另一个可能的选择是NtCreateThreadEx或者RtlCreateUserThread(写入shellcode),原理与上段类似,就不写了。

此外,还有APC注入方法,APC中文名称为异步过程调用,APC为链状的数据结构,可以让一个线程在其本应该的执行步骤前执行代码,每个线程都这一个APC链。当线程从等待状态苏醒后,会自动检测自己的APC队列中是否存在APC过程,如果有则继续执行。

所以,只需要将目标进程的线程的APC队列里面添加APC过程,然后促使线程从休眠中恢复就可以实现APC注入。

反射式dll注入,首先将需要注入的dll写入进程内存,然后为该dll添加一个导出函数,利用这个导出函数让其自动的装载dll。注射器是将DLL文件写入目标进程内存。反射装载器实现的就是模拟dll装载器装载dll文件的作。

以前许多游戏的实现,都利用了输入法注入来实现加载特定DLL的行为,以便实现各类非法作

切换输入法时候,输入法器imm32.dll就会加载IME模块,这样就形成了输入法注入的充要条件。由于Ime文件本质上只是个存放在C:\WINDOWS\32目录下的特殊的DLL文件,因此开发者们便可以利用这个特性,在Ime文件中使用LoadLirary()函数来加载待注入的各类非法恶意DLL文件。

如下图中的各类行为,都是所实现的效果,它们,亦或是它们的前辈,必然曾和输入法注入有着藕断丝连的关系。

四、结语

前面内容介绍了一部分的DLL注入攻击方式,其实还有很多奇奇怪怪的注入方法,例如我曾经写过的LSP(LayerServProvider,分层服务提供者)注入等,各位可以自行前往搜索了解~

s://zhihu/question/449614248/answer/1785395934

以上,谢谢~

END

免责声明:本文由卡卷网编辑并发布,但不代表本站的观点和立场,只提供分享给大家。

卡卷网

卡卷网 主页 联系他吧

请记住:卡卷网 Www.Kajuan.Net

欢迎 发表评论:

请填写验证码