DLL注入的多种方式

注册表注入

在Windows NT/2000/XP/2003操作系统中,当需要加载user32.dll的程序启动时,user32.dll会加载注册表键HLM\Software\Microsoft\WindowsNT\CurrentVersion\Windows\AppInit_DIls下面列出的所有模块。

因此,可以将要注入的模块所在的路径写到AppInit_DIls 键下,待游戏进程启动并将外挂模块带入之后,再删除AppInit_DIls 键的值以清除痕迹,其核心函数如下:

//定义键值

#define DSTKEY "SOFTWARE\\\Microsoft\\\Windows NT\\\CurrentVersion\\\Windows"
//打开主键
RegOpenKeyEx (HKEY LOCAL_ MACHINE,DSTKEY,0,KEY_ ALL_ ACCESS,&hKey) ;//设置AppInit_DLLS 键的值,其中“cDllPath" 为待注人DLL的路径
RegSetValueEx (hKey,"AppInit_DLLs",0,REG SZ,cD11Path,strlen( (char*) cDl1Path) +1) ;

优点:简单,易于实现。

缺点:第一,系统重启后才能实现注入,且对DLL的稳定性要求比较高。建议在虚拟机里使用,如果DLL有问题就会蓝屏。第二,易于被ProcessMonitor之类的用于监测注册表操作的软件发现。

远线程注入

远线程注入的核心思想是利用Windows提供的远线程机制,在目标进程中开启一个加载模块的远线程,使模块被该远线程加载到游戏的地址空间。

远线程使用的关键API有VirtualAllocEx、WriteProcessMemory、CreateRemoteThread和LoadLibrary,它们的声明如下。

LPVOID  WINAPI VirtualAllocEx(
HANDLE  hProcess,                       //远进程句柄
LPVOID  lpAddress,                      //保留页面的内存地址;一般用NULL自动分配
SIZE_T  dwSize,                         //分配内存的大小
DWORD   flAllocationType,
DWORD   flProtect
);BOOL WriteProcessMemory (
HANDLE hProcess,                                 //远进程句柄
LPVOID lpBaseAddress,                         //远进程待写入的地址
LPVOID lpBuffer,                                     //本进程空间需要写入到远进程的地址
DWORD nSize,                                       //lpBuffer所指空间的大小
LPDWORD lpNumberOfBytesWritten     //返回实际写入远进程的字节数
) ;HANDLE CreateRemoteThread (
HANDLE hProcess,                            //远程句柄
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,    //指向在远程进程中执行的函数地址
LPVOID lpParameter,                        //传入参数
DWORD dwCreationFlags,                    //创建线程的其他标志
LPDWORD lpThreadId                         //线程ID。如果为NULL,则不返回
);HMODULE WINAPI LoadLibrary (
_in LPCTSTR lpFileName            //待加模块的文件路径
);

远线程加载流程,步骤如下:

(1)调用VirtualAllocEx函数在远进程空间中分配内存

(2)调用WriteProcessMemory函数将模块的文件路径写入远进程空间。

(3)调用CreateRemoteThread函数开启远进程的LoadLibrary远线程,以加载外挂模块。

该方式比较古老,基本的保护都已防御此法,就不再过多阐述

优点:简单,易实现。

缺点:容易被检测。只要监控本进程对LoadLibrary函数的调用,就可以很好地防御远线程加载。

依赖可信进程注入

为了躲避反外挂系统的扫描或者分析人员的分析,有时候依赖可信任的第三方进程所进行的转注入,可能会取得比较好的效果。因services.exe不易调试、权限高、隐蔽性好,所以通过木马和外挂找services.exe进程是一个明智的选择。

假设本进程为Main.exe, 待注入模块为ZRT.dl, 待注入进程为ZRP.exe,经过以下。

(1) Main.exe调用WriteProcessMemory和CreateRemoteThread函数将ZRT.dll注入services.exe中,然后Main.exe调用Sleep函数等待注入完成

(2)service.exe中的ZRT.dllCreateToolhelp32Sanpshot和Process32Next来遍历进程,如果发现ZRP.exe,就采用远线程或其他方式将ZRT.dll 注人ZRP.exe进程

(3)Main.exe进程睡眠结束

(4) Main.exe调用CreateToolhelp32Sanpshot和Process32Next遍历进程,寻找services.exe进程。找到该进程后,遍历模块,找到ZRT.dll。

(5)Main.exe 调用CreateRemoteThread远线程来调用FreeLibrary,将services.exe中的ZRT.dll从services.exe进程中卸载。

优点:隐蔽性好,不易被分析和发现。

缺点:遍历进程的方法需要改进,可能被假进程欺骗;直接调用API也不好。

APC注入

APC ( Asynchronous Procedure Call,异步过程调用)是在一个特定线程环境下被异步执行的函数,分为用户模式APC和内核模式APC。每个线程都有一个APC队列。在用户模式下,当线程调用SleepEx、WaitForSingleObjectEx等进人“Alterable WaitStatus"状态(可警告的等待状态)的时候,系统就会遍历该线程的APC队列,然后按照先进先出的顺序来执行这些APC。

在用户模式下,微软提供了QueueUserAPC这个API来向-一个线程插入APC。下面是QueueUserAPC的声明。

DWORD WINAPI QueueUserAPC (
_in PAPCFUNC pfnAPC,                       //指向一个APC函数
in HANDLE hThread,                             //将要插入APC的线程句柄
in ULONG PTR dwData                        //APC函数的参数
);

下面为APC注入的代码


// 1.以suspend方式创建待加载的目标进程
if (CreateProcess (sProcName, NULL, NULL, NULL, FALSE, CREATE_ SUSPENDED, NULL, NULL, &st, &pi) )
{
// 2.目标进程地址空间分配待加载的DLL路径空间
lpDllName = VirtualAllocEx (pi.hProcess,NULL, (strlen (sDllName) +1),MEM COMMIT,PAGE READWRITE) ;
// 3.把待加载的DLL路径写人目标进程空间
if (WriteProcessMemory (pi .hProcess,lpD11Name,sD11Name, strlen(sD11Name),NULL) )
{// 4.获取LoadLibrary的地址LPVOID nLoadLibrary= (LPVOID) GetProcAddress (GetModuleHandle        ("kerne132.d1l"),"LoadLibraryA") ;// 5.调用QueueUserAPC向远线程插入一个APC,这个APC就是LoadLibraryif (! QueueUserAPC( (PAPCFUNC) nLoadLibrary, pi. hThread, (ULONG_PTR) 1pD1 1Name) ){OutputDebugString("APCInject QueueUserAPC call error!") ;dRet=-6;}
}
}

除了可以通过VirtualAllocEx和WriteProcessMemory函数在目标进程地址空间存放待加载DLL的路径,还可以通过CreateFileMapping、MapViewOfFile和NtMapViewOfSection函数的组合来映射路径

优点:比较隐蔽,简单。

缺点:实现的条件比较苛刻,必须等待进程进入“Alterable WaitStatus"状态。

消息钩子注入

SetW indowsHookEx函数是微软提供给程序开发人员进行消息拦截的一个API。不过,它的功能不仅可以用作消息拦截,还可以进行DLL注入。

SetWindwosHookEx的原型声明如下。

HHOOK Se tWi ndowsHookEx (
Int idHook,                                 //指示将要安装的挂钩处理过程的类型。例如,idHook为“WH_CALLWNDPROC"时代表安装一个挂钩处理过程,在系统将消息发送至目标窗口处理过程之前对该消息进行监视。    HOOKPROC lpfn,                      //指向相应的挂钩处理过程。
HINSTANCE hMod,                   //指示了一个DLL句柄。该DLL包含参数lpfn所指向的挂钩处理过程。
DWORD dwThreadId                 //指示了一个线程标识符,挂钩处理过程与线程相关。若此参数值为0,则该挂钩处理过程与所有现存的线程相关。
);

如果要去掉消息钩子,可以调用UnhookWindowsHookEx函数。

下面是注入的核心代码。

//利用Windows API SetWindowsHookEx 实现注入DLL
BOOL SetWinHKInject (char* pszDllPath,char* pszProcess)
{//加载待注人的DLL到本进程空间hMod = LoadLibrary (pszDllPath) ;if (!hMod){return FALSE;}//获取待注人DLL中导出的消息钩子过程函数的地址lpFunc = (DWORD) GetProcAddress (hMod, "MyMessageProc") ;if (!lpFunc){FreeLibrary (hMod) ;return FALSE;}//获取待注入进程的线程IDdwThreadId = GetTargetThreadIdFromProcname (pszProcess) ;if (!dwThreadId){FreeLibrary (hMod) ;return FALSE}//调用SetwindowsHookEx实现消息钩子注人hook = SetWindowsHookEx (WH_ GETMESSAGE, / /WH KEYBOARD, / /WH_ CALLWNDPROC,(HOOKPROC) 1pFunC,hMod,dwThreadId) ;FreeLibrary (hMod) ;return TRUE;
}//待注人DLL导出的消息钩子函数MyMessageProc
_declspec (dllexport) LRESULT MyMessageProc (int code, WPARAM wParam,
LPARAM 1Param)
{//对消息的处理return CallNextHookEx(g_hhook,code,wParam,lParam);
}

优点:代码和原理简单,容易发现。

缺点:容易被发现。

劫持进程创建注入

如果能在目标进程运行起来之前获取目标进程的读、写等权限,那么注入将容易得多。以下是进程创建的关键API和调用序列。

Windows下创建进程的API是CreateProcess,它的原型如下。

BOOL CreateProcess (
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes。
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID IpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);

主要介绍dwCreationFlags的一个值——CREATE_SUSPENDED的含义。

当给参数dwCreationFlags赋值CREATE_SUSPENDED来调用CreateProcess()函数的时候,该进程的主线程将以挂起的方式启动,要想恢复主线程的运行,需要调用ResumeThread()函数。劫持进程加载就是在主线程被悬挂和恢复的这段时间内,把dll或代码注人目标进程的。

步骤为以下三步:

(1)调用以挂起方式调用CreateProcess()函数,创建进程。

(2)采用远线程方式注入外挂模块。

(3)调用ResumThread()函数恢复游戏主线程。

但由于现在很多游戏进程在启动时采用双进程保护机制,所以即使通过上面的劫持进程成功实现加载,也只不过是注入双进程保护的第一个进程。为了再次使用劫持进程创建机制来注人真正的游戏进程,需要认识用户态下进程创建的函数调用序列,如图

其中的KiFastSystemCall()函数相当于ring3转ring0的一个通道。CreateProcess()函数最后通过KiFastSystemCall()函数进入内核态。可以在任意层次上通过Hook对应的函数来创建劫持进程,以达到加载的目的。例如,在ring3即将进入ing0的时候,即调用KiFastSystemCall()函数的时候,劫持这个函数的调用,可以实现加载。

优点:不易防御,成功率较高。
缺点:劫持时间不宜过长,否则会被发现;劫持后,如需再次劫持,则需要Hook,因此易被检测。

总结

DLL注入共四个步骤:

1.附加到目标/远程进程

2.在目标/远程进程内分配内存

3.将DLL文件路径,或者DLL文件,复制到目标/远程进程的内存空间

4.控制进程运行DLL文件

所有这些步骤是通过调用一系列指定的API函数来完成的。每种技术需要进行特定的设置和选项配置。每种技术都有其优点和缺点

但对于有驱动保护的程序来说,这些都是处于3环层次的注入方法,在0环的保护下3环的注入方法就不太够看了,要想真正的与驱动保护的程序对抗,只有也进入0环与之抗衡

DLL注入的多种方式相关推荐

  1. Spring属性注入的多种方式

    随缘记录 方便记忆 1.通过setter方式注入 <property> 前提 该已提供setter方法 1.1 <!-- 使用setter方法注入数据  普通数据--> < ...

  2. [web安全]深入理解反射式dll注入技术

    一.前言 dll注入技术是让某个进程主动加载指定的dll的技术.恶意软件为了提高隐蔽性,通常会使用dll注入技术将自身的恶意代码以dll的形式注入高可信进程. 常规的dll注入技术使用LoadLibr ...

  3. 深入理解反射式dll注入技术

    前言 dll 注入技术是让某个进程主动加载指定的 dll 的技术.恶意软件为了提高隐蔽性,通常会使用 dll 注入技术将自身的恶意代码以 dll 的形式注入高可信进程. 常规的 dll 注入技术使用 ...

  4. DLL注入的方式 (转载自看雪学院)

    DLL 注入技术的 N 种姿势 看雪学院 看雪学院,为IT专业人士.技术专家提供了一个民间交流与合作空间. 18 人赞同了该文章 本文中我将介绍DLL注入的相关知识.不算太糟的是,DLL注入技术可以被 ...

  5. 【安全技术】关于几种dll注入方式的学习

    何为dll注入 DLL注入技术,一般来讲是向一个正在运行的进程插入/注入代码的过程.我们注入的代码以动态链接库(DLL)的形式存在.DLL文件在运行时将按需加载(类似于UNIX系统中的共享库(shar ...

  6. ASP.NET Core默认注入方式下如何注入多个实现(多种方式)

    版权声明:本文为starfd原创文章,转载请标明出处. https://blog.csdn.net/starfd/article/details/81282651 在我们开发过程中,对于服务来说,一般 ...

  7. ASP.NET Core默认注入方式下如何注入多个实现(多种方式) - sky 胡萝卜星星 - CSDN博客...

    ASP.NET Core默认注入方式下如何注入多个实现(多种方式) - sky 胡萝卜星星 - CSDN博客 原文:ASP.NET Core默认注入方式下如何注入多个实现(多种方式) - sky 胡萝 ...

  8. Windows核心编程_远线程方式实现Dll注入

    之前有介绍过HOOK的方式注入,这次介绍以其它方式注入,而无须HOOK,要知道在Windows这个浩荡的海洋里,API就是宝藏,找到足够多的宝藏那么你就是海贼王~! 实现思路如下: 首先打开一个进程的 ...

  9. c++实现DLL注入的几种方式

    经过几天的折腾,找到了几个dll注入的方法,但是不意外的是,都暂时没法注入到LOL中,毕竟有进程保护在那,OpenProcess这一步就直接被拒绝了,提升Debug权限也没用,下面记录一些代码,希望能 ...

  10. Java注入bean的方式_多种方式实现Spring的Bean注入

    Spring的核心是控制反转(IoC)和面向切面(AOP). Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理 . Spring工厂是用于生成Bean,对Be ...

最新文章

  1. SQL Server 数据类型转换函数
  2. Java多线程 - 控制线程
  3. 超融合与传统架构真正的区别在哪?
  4. PLSQL中Database怎么填
  5. 2006---2009年杭电计算机历年研究生复试---笔试编程
  6. So Easy! 让开发人员更轻松的工具和资源
  7. 解决安卓项目显示cannot resolve symbol 'R'
  8. react-生命周期
  9. 2014计算机二级vfp,2014计算机二级VF考前试题解析
  10. php报表开发韩顺平,韩顺平从Html基础到php实战开发视频教程非常全面的一套PHP开发教程...
  11. 老司机 iOS 周报 #37 | 2018-09-24
  12. Html 5 网络存储之 LocalStorage、SessionStorage
  13. Atitit 知识管理的艺术 艾提拉著作 这个实际上涉及到知识的管理(获取 ,存储,索引,查找等方法 目录 1. 记不住的本质 2 1.1. 真的没有记住 2 1.2. 暂时没有搜索到,可能是
  14. python建模概述
  15. 计算机应用基础作业4第一次,《计算机应用基础》第一次作业题目、答案
  16. UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xae in position解决办法
  17. 杭州地铁2号线西北段顺利通车 三思LED照明彰显“暖心”服务
  18. 系统内存占用率高导致电脑卡顿的解决方案
  19. layui table表格中加input 日期插件
  20. html标签(5):form,input,select,textarea

热门文章

  1. 【ArcGIS教程03】基础知识(建议收藏)
  2. Loadrunner12实现手机APP压力测试
  3. 【Ubuntu】USB 摄像头测试工具
  4. 汉字转换拼音及首字母
  5. “微积分7天搞定”学习记录
  6. 跟着莫烦python 从零开始强化学习之Q-Learning 一维探索者 代码完整注释版
  7. 数据库变为可疑_Sql 2008数据库可疑如何解决
  8. android 歌词 开源,NLyric 网易云音乐歌词自动搜索下载【开源】
  9. ADI AD9371/9375+Xilinx ZC706 No-OS初始工程搭建 ——Vivado2019.2
  10. 如何使用ShoeBox和PhotoShop制作出漂亮的Fnt字体