9.注入技术

一、前言

dll文件我们知道,它是不能自己运行的,只能被加载到其它进程中去执行代码。

而利用这个特性,我们就能够使用dll来完成注入操作,方法的原理为:

  1. 将我们的代码写在一个dll文件中
  2. 强迫目标进程加载我们的dll文件

一旦我们的dll文件被加载进入了目标进程,那我们自然可以为所欲为了!因为dll与它在一个进程内,你可以任意访问其内部的地址。

如果不用注入,虽然也能实现动态修改,但会更加麻烦:

  1. 使用VirtualQueryExVirtualProtectEx函数查询、修改目标进程内存的权限。
  2. 使用ReadProcressMemoryWriteProcessMemory函数读取、写入目标进程内存中的数据。

由于不在一个进程内,这些函数实际上都是在跨进程操作,并且这种方式想要让目标进程执行自己的代码非常麻烦,一般只会用于小块数据的修改。

而dll不一样,一旦被加载了,是可以执行我们自己的代码的:动态库与静态库

dll文件也有一个入口函数,一旦被加载,就会执行该函数,我们就可以在里面写一些自己的代码来操作该进程。

二、dll注入方式

一般情况下,程序加载dll有以下三种方式:

  1. 进程创建时,会加载其输入表中dll,也就是静态输入
  2. 进程主动调用LoadLibrary加载,也就是动态加载
  3. 通过系统机制要求,比如输入法为什么能在任意程序中使用?这就是系统机制导致的,它允许某些特性功能的模块直接加载到目标进程中。

1.输入表

首先是第一种方式,静态输入,通过修改输入表完成。

当一个进程被创建后,它并不会直接到exe本身去执行代码,首先被执行的是ntdll.dll中的LdrInitializeThunk函数。

这个ntdll.dll是一个非常重要的基础模块,前面也提到过,它并不会依赖于你的可执行文件是否导入,它在进程的创建阶段就会被自动映射到新进程中。

而这个LdrInitializeThunk函数又会调用LdrpInitializeProcess函数对进出做一些必要的初始化功能。

LdrpInitializeProcess函数又会调用LdrpWalkImportDescriptor对输入表进行处理,也就是加载输入表中的模块。

所以只要我们在输入表被处理之前对其进行干预,为输入表增加一个项目,使其指向要加载的目标dll,或者替换原输入表中的DLL并对其函数调用进行转发,那么就能实现加载dll的功能了!

简单起见,这里我自己写一个dll,在vs自动生成的代码中添加一个导出函数、并在被注入的时候弹出一个提示框即可:

image-20231107102257003

然后生成32位的,下面我们的目标就是将这个生成的32位dll注入到前面那个TraceMe32.exe程序中去。

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux