当你的才华

还撑不起你的野心时

那你就应该静下心来学习


lpk.dll劫持游戏注入

由于 输入表中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索 DLL文件。首先会尝试从当前程序所在的目录加载DLL,如果没找到,则在 Windows系统目录中查找,最后是在 环境变量中列出的各个目录下查找。利用这个特点,先伪造一个系统同名的DLL,提供同样的 输出表,每个输出函数转向真正的系统DLL。程序调用系统DLL时会先调用当前目录下伪造的DLL,完成相关功能后,再跳到系统DLL同名函数里执行。这个过程用个形象的词来描述就是系统DLL被劫持(hijack)了。

利用这种方法取得控制权后,可以对主程序进行补丁。此种方法只对除kernel32.dll、ntdll.dll等核心系统库以外的DLL有效,如网络应用程序的 ws2_32.dll、游戏程序中的 d3d8.dll,还有大部分应用程序都调用的lpk.dll、 sxs.dll,这些DLL都可被劫持。

伪造的dll制作好后,放到程序当前目录下,这样当原程序调用 原函数时就调用了伪造的dll的同名函数,进入劫持DLL的代码,处理完毕后,再调用原DLL此函数。

这种补丁技术,对 加壳保护的软件很有效,选择挂接的函数最好是 在壳中没有被调用的,当挂接函数被执行时,相关的代码已被解压,可以直接补丁了。在有些情况下,必须用计数器统计挂接的函数的调用次数来接近OEP。此方法巧妙地绕过了壳的复杂检测,很适合加壳程序的补丁制作。

一些木马或病毒也会利用DLL劫持技术搞破坏,因此当在应用程序目录下发现系统一些 DLL文件存在时,如lpk.dll,应引起注意。

在本次中,我们将要利用这个技术来实现对游戏窗口进行注入,有很多方法都可以实现,比如劫持lpk.dll ,或者是d3d8thk.dll等都可以实现。

下面首先以lpk.dll为例来进行说明

  1. // 导出函数
  2. #pragma comment(linker, "/EXPORT:LpkInitialize=_AheadLib_LpkInitialize,@1")
  3. #pragma comment(linker, "/EXPORT:LpkTabbedTextOut=_AheadLib_LpkTabbedTextOut,@2")
  4. #pragma comment(linker, "/EXPORT:LpkDllInitialize=_AheadLib_LpkDllInitialize,@3")
  5. #pragma comment(linker, "/EXPORT:LpkDrawTextEx=_AheadLib_LpkDrawTextEx,@4")
  6. //#pragma comment(linker, "/EXPORT:LpkEditControl=_AheadLib_LpkEditControl,@5")
  7. #pragma comment(linker, "/EXPORT:LpkExtTextOut=_AheadLib_LpkExtTextOut,@6")
  8. #pragma comment(linker, "/EXPORT:LpkGetCharacterPlacement=_AheadLib_LpkGetCharacterPlacement,@7")
  9. #pragma comment(linker, "/EXPORT:LpkGetTextExtentExPoint=_AheadLib_LpkGetTextExtentExPoint,@8")
  10. #pragma comment(linker, "/EXPORT:LpkPSMTextOut=_AheadLib_LpkPSMTextOut,@9")
  11. #pragma comment(linker, "/EXPORT:LpkUseGDIWidthCache=_AheadLib_LpkUseGDIWidthCache,@10")
  12. #pragma comment(linker, "/EXPORT:ftsWordBreak=_AheadLib_ftsWordBreak,@11")

首先是对lpk动态链接库中的函数进行导出

  1. // 宏定义
  2. #define EXTERNC extern "C"
  3. #define NAKED __declspec(naked)
  4. #define EXPORT __declspec(dllexport)
  5. #define ALCPP EXPORT NAKED
  6. #define ALSTD EXTERNC EXPORT NAKED void __stdcall
  7. #define ALCFAST EXTERNC EXPORT NAKED void __fastcall
  8. #define ALCDECL EXTERNC NAKED void __cdecl

宏定义,用来指明函数的调用方式等东西

  1. //LpkEditControl导出的是数组,不是单一的函数(by Backer)
  2. EXTERNC void __cdecl AheadLib_LpkEditControl(void);
  3. EXTERNC __declspec(dllexport) void(*LpkEditControl[14])() = { AheadLib_LpkEditControl };

由于 LpkEditControl中存的是数组数组,所以需要拷贝过来,而不是直接导出

  1. // AheadLib 命名空间
  2. namespace AheadLib
  3. {
  4. HMODULE m_hModule = NULL; // 原始模块句柄
  5. // 加载原始模块
  6. inline BOOL WINAPI Load()
  7. {
  8. TCHAR tzPath[MAX_PATH];
  9. TCHAR tzTemp[MAX_PATH * 2];
  10. GetSystemDirectory(tzPath, MAX_PATH);
  11. //MessageBox(NULL, tzPath, "path", MB_OK);
  12. //GetCurrentDirectory(MAX_PATH, tzPath);
  13. lstrcat(tzPath, TEXT("\\lpk.dll"));
  14. m_hModule = LoadLibrary(tzPath);
  15. if (m_hModule == NULL)
  16. {
  17. wsprintf(tzTemp, TEXT("无法加载 %s,程序无法正常运行。"), tzPath);
  18. MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
  19. };
  20. //MessageBox(NULL, "原始模块加载成功", TEXT("AheadLib"), MB_ICONSTOP);
  21. return (m_hModule != NULL);
  22. }
  23. // 释放原始模块
  24. inline VOID WINAPI Free()
  25. {
  26. if (m_hModule)
  27. {
  28. FreeLibrary(m_hModule);
  29. }
  30. }
  31. // 获取原始函数地址
  32. FARPROC WINAPI GetAddress(PCSTR pszProcName)
  33. {
  34. FARPROC fpAddress;
  35. CHAR szProcName[16];
  36. TCHAR tzTemp[MAX_PATH];
  37. fpAddress = GetProcAddress(m_hModule, pszProcName);
  38. if (fpAddress == NULL)
  39. {
  40. if (HIWORD(pszProcName) == 0)
  41. {
  42. wsprintf(szProcName, "%d", pszProcName);
  43. pszProcName = szProcName;
  44. }
  45. wsprintf(tzTemp, TEXT("无法找到函数 %hs,程序无法正常运行。"), pszProcName);
  46. MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
  47. ExitProcess(-2);
  48. }
  49. return fpAddress;
  50. }
  51. }
  52. 下面就是我们要实现dll注入的地方,一般的dll注入都是在这存入关键代码
  53. //函数声明
  54. void WINAPIV Init(LPVOID pParam);
  55. void WINAPIV Init(LPVOID pParam)
  56. {
  57. //在这里添加DLL加载代码
  58. // LoadLibrary(TEXT(".\\MFC_DLL.dll"));
  59. MessageBox(NULL, "lpkdll劫持成功", "lpkk劫持", MB_OK);
  60. return;
  61. }

下面是入口函数:

  1. // 入口函数
  2. BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
  3. {
  4. if (dwReason == DLL_PROCESS_ATTACH)
  5. {
  6. DisableThreadLibraryCalls(hModule);
  7. if (Load())
  8. {
  9. //LpkEditControl这个数组有14个成员,必须将其复制过来
  10. memcpy((LPVOID)(LpkEditControl + 1), (LPVOID)((int*)GetAddress("LpkEditControl") + 1), 52);
  11. _beginthread(Init, NULL, NULL);
  12. }
  13. else{
  14. // MessageBox(NULL, "初始化失败", "123 ERROR", MB_ICONSTOP);
  15. return FALSE;
  16. }
  17. }
  18. else if (dwReason == DLL_PROCESS_DETACH)
  19. {
  20. Free();
  21. }
  22. return TRUE;
  23. }
  24. 然后是函数导出:
  25. // 导出函数
  26. ALCDECL AheadLib_LpkInitialize(void)
  27. {
  28. GetAddress("LpkInitialize");
  29. __asm JMP EAX;
  30. }
  31. // 导出函数
  32. ALCDECL AheadLib_LpkTabbedTextOut(void)
  33. {
  34. GetAddress("LpkTabbedTextOut");
  35. __asm JMP EAX;
  36. }
  37. // 导出函数
  38. ALCDECL AheadLib_LpkDllInitialize(void)
  39. {
  40. GetAddress("LpkDllInitialize");
  41. __asm JMP EAX;
  42. }
  43. // 导出函数
  44. ALCDECL AheadLib_LpkDrawTextEx(void)
  45. {
  46. GetAddress("LpkDrawTextEx");
  47. __asm JMP EAX;
  48. }
  49. // 导出函数
  50. ALCDECL AheadLib_LpkEditControl(void)
  51. {
  52. GetAddress("LpkEditControl");
  53. __asm jmp DWORD ptr[EAX];//这里的LpkEditControl是数组,eax存的是函数指针
  54. }
  55. // 导出函数
  56. ALCDECL AheadLib_LpkExtTextOut(void)
  57. {
  58. GetAddress("LpkExtTextOut");
  59. __asm JMP EAX;
  60. }
  61. // 导出函数
  62. ALCDECL AheadLib_LpkGetCharacterPlacement(void)
  63. {
  64. GetAddress("LpkGetCharacterPlacement");
  65. __asm JMP EAX;
  66. }
  67. // 导出函数
  68. ALCDECL AheadLib_LpkGetTextExtentExPoint(void)
  69. {
  70. GetAddress("LpkGetTextExtentExPoint");
  71. __asm JMP EAX;
  72. }
  73. // 导出函数
  74. ALCDECL AheadLib_LpkPSMTextOut(void)
  75. {
  76. GetAddress("LpkPSMTextOut");
  77. __asm JMP EAX;
  78. }
  79. // 导出函数
  80. ALCDECL AheadLib_LpkUseGDIWidthCache(void)
  81. {
  82. GetAddress("LpkUseGDIWidthCache");
  83. __asm JMP EAX;
  84. }
  85. // 导出函数
  86. ALCDECL AheadLib_ftsWordBreak(void)
  87. {
  88. GetAddress("ftsWordBreak");
  89. __asm JMP EAX;
  90. }

函数导出的目的就是让当前dll跳转到系统下的lpk.dll目录下执行相应的函数。这样就实现了先执行自己的伪造的lpk.dll(在其中完成代码的注入等一系列功能),然后在跳转到正常的lpk.dll函数中,就完成了lpk.dll的劫持

最后就是兼容win7,就需要在注册表中添加一个多字节剂的命令 ExcludeFromKnownDlls ,其中的值为 lpk.dll 就可以实现lpk.dll的劫持了

具体源码如下:

  1. // lpk.cpp : Defines the entry point for the DLL application.
  2. //
  3. // 头文件
  4. #include "stdafx.h"
  5. #include <process.h>
  6. #include<Windows.h>
  7. // 导出函数
  8. #pragma comment(linker, "/EXPORT:LpkInitialize=_AheadLib_LpkInitialize,@1")
  9. #pragma comment(linker, "/EXPORT:LpkTabbedTextOut=_AheadLib_LpkTabbedTextOut,@2")
  10. #pragma comment(linker, "/EXPORT:LpkDllInitialize=_AheadLib_LpkDllInitialize,@3")
  11. #pragma comment(linker, "/EXPORT:LpkDrawTextEx=_AheadLib_LpkDrawTextEx,@4")
  12. //#pragma comment(linker, "/EXPORT:LpkEditControl=_AheadLib_LpkEditControl,@5")
  13. #pragma comment(linker, "/EXPORT:LpkExtTextOut=_AheadLib_LpkExtTextOut,@6")
  14. #pragma comment(linker, "/EXPORT:LpkGetCharacterPlacement=_AheadLib_LpkGetCharacterPlacement,@7")
  15. #pragma comment(linker, "/EXPORT:LpkGetTextExtentExPoint=_AheadLib_LpkGetTextExtentExPoint,@8")
  16. #pragma comment(linker, "/EXPORT:LpkPSMTextOut=_AheadLib_LpkPSMTextOut,@9")
  17. #pragma comment(linker, "/EXPORT:LpkUseGDIWidthCache=_AheadLib_LpkUseGDIWidthCache,@10")
  18. #pragma comment(linker, "/EXPORT:ftsWordBreak=_AheadLib_ftsWordBreak,@11")
  19. // 宏定义
  20. #define EXTERNC extern "C"
  21. #define NAKED __declspec(naked)
  22. #define EXPORT __declspec(dllexport)
  23. #define ALCPP EXPORT NAKED
  24. #define ALSTD EXTERNC EXPORT NAKED void __stdcall
  25. #define ALCFAST EXTERNC EXPORT NAKED void __fastcall
  26. #define ALCDECL EXTERNC NAKED void __cdecl
  27. //LpkEditControl导出的是数组,不是单一的函数(by Backer)
  28. EXTERNC void __cdecl AheadLib_LpkEditControl(void);
  29. EXTERNC __declspec(dllexport) void(*LpkEditControl[14])() = { AheadLib_LpkEditControl };
  30. //添加全局变量
  31. // AheadLib 命名空间
  32. namespace AheadLib
  33. {
  34. HMODULE m_hModule = NULL; // 原始模块句柄
  35. // 加载原始模块
  36. inline BOOL WINAPI Load()
  37. {
  38. TCHAR tzPath[MAX_PATH];
  39. TCHAR tzTemp[MAX_PATH * 2];
  40. GetSystemDirectory(tzPath, MAX_PATH);
  41. //MessageBox(NULL, tzPath, "path", MB_OK);
  42. //GetCurrentDirectory(MAX_PATH, tzPath);
  43. lstrcat(tzPath, TEXT("\\lpk.dll"));
  44. m_hModule = LoadLibrary(tzPath);
  45. if (m_hModule == NULL)
  46. {
  47. wsprintf(tzTemp, TEXT("无法加载 %s,程序无法正常运行。"), tzPath);
  48. MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
  49. };
  50. //MessageBox(NULL, "原始模块加载成功", TEXT("AheadLib"), MB_ICONSTOP);
  51. return (m_hModule != NULL);
  52. }
  53. // 释放原始模块
  54. inline VOID WINAPI Free()
  55. {
  56. if (m_hModule)
  57. {
  58. FreeLibrary(m_hModule);
  59. }
  60. }
  61. // 获取原始函数地址
  62. FARPROC WINAPI GetAddress(PCSTR pszProcName)
  63. {
  64. FARPROC fpAddress;
  65. CHAR szProcName[16];
  66. TCHAR tzTemp[MAX_PATH];
  67. fpAddress = GetProcAddress(m_hModule, pszProcName);
  68. if (fpAddress == NULL)
  69. {
  70. if (HIWORD(pszProcName) == 0)
  71. {
  72. wsprintf(szProcName, "%d", pszProcName);
  73. pszProcName = szProcName;
  74. }
  75. wsprintf(tzTemp, TEXT("无法找到函数 %hs,程序无法正常运行。"), pszProcName);
  76. MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
  77. ExitProcess(-2);
  78. }
  79. return fpAddress;
  80. }
  81. }
  82. using namespace AheadLib;
  83. //函数声明
  84. void WINAPIV Init(LPVOID pParam);
  85. void WINAPIV Init(LPVOID pParam)
  86. {
  87. //在这里添加DLL加载代码
  88. // LoadLibrary(TEXT(".\\MFC_DLL.dll"));
  89. MessageBox(NULL, "lpkdll劫持成功", "lpkk劫持", MB_OK);
  90. return;
  91. }
  92. // 入口函数
  93. BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
  94. {
  95. if (dwReason == DLL_PROCESS_ATTACH)
  96. {
  97. DisableThreadLibraryCalls(hModule);
  98. if (Load())
  99. {
  100. //LpkEditControl这个数组有14个成员,必须将其复制过来
  101. memcpy((LPVOID)(LpkEditControl + 1), (LPVOID)((int*)GetAddress("LpkEditControl") + 1), 52);
  102. _beginthread(Init, NULL, NULL);
  103. }
  104. else{
  105. // MessageBox(NULL, "初始化失败", "123 ERROR", MB_ICONSTOP);
  106. return FALSE;
  107. }
  108. }
  109. else if (dwReason == DLL_PROCESS_DETACH)
  110. {
  111. Free();
  112. }
  113. return TRUE;
  114. }
  115. // 导出函数
  116. ALCDECL AheadLib_LpkInitialize(void)
  117. {
  118. GetAddress("LpkInitialize");
  119. __asm JMP EAX;
  120. }
  121. // 导出函数
  122. ALCDECL AheadLib_LpkTabbedTextOut(void)
  123. {
  124. GetAddress("LpkTabbedTextOut");
  125. __asm JMP EAX;
  126. }
  127. // 导出函数
  128. ALCDECL AheadLib_LpkDllInitialize(void)
  129. {
  130. GetAddress("LpkDllInitialize");
  131. __asm JMP EAX;
  132. }
  133. // 导出函数
  134. ALCDECL AheadLib_LpkDrawTextEx(void)
  135. {
  136. GetAddress("LpkDrawTextEx");
  137. __asm JMP EAX;
  138. }
  139. // 导出函数
  140. ALCDECL AheadLib_LpkEditControl(void)
  141. {
  142. GetAddress("LpkEditControl");
  143. __asm jmp DWORD ptr[EAX];//这里的LpkEditControl是数组,eax存的是函数指针
  144. }
  145. // 导出函数
  146. ALCDECL AheadLib_LpkExtTextOut(void)
  147. {
  148. GetAddress("LpkExtTextOut");
  149. __asm JMP EAX;
  150. }
  151. // 导出函数
  152. ALCDECL AheadLib_LpkGetCharacterPlacement(void)
  153. {
  154. GetAddress("LpkGetCharacterPlacement");
  155. __asm JMP EAX;
  156. }
  157. // 导出函数
  158. ALCDECL AheadLib_LpkGetTextExtentExPoint(void)
  159. {
  160. GetAddress("LpkGetTextExtentExPoint");
  161. __asm JMP EAX;
  162. }
  163. // 导出函数
  164. ALCDECL AheadLib_LpkPSMTextOut(void)
  165. {
  166. GetAddress("LpkPSMTextOut");
  167. __asm JMP EAX;
  168. }
  169. // 导出函数
  170. ALCDECL AheadLib_LpkUseGDIWidthCache(void)
  171. {
  172. GetAddress("LpkUseGDIWidthCache");
  173. __asm JMP EAX;
  174. }
  175. // 导出函数
  176. ALCDECL AheadLib_ftsWordBreak(void)
  177. {
  178. GetAddress("ftsWordBreak");
  179. __asm JMP EAX;
  180. }

参考链接:

https://blog.csdn.net/u011619422/article/details/47002145


我不需要自由,只想背着她的梦

一步步向前走,她给的永远不重


后渗透篇:劫持技术(lpk.dll劫持游戏注入【Win7 实例】)相关推荐

  1. 后渗透篇:COM劫持及加载技术

    滥用COM注册表结构:劫持及加载技术 译文链接:https://bohops.com/2018/08/18/abusing-the-com-registry-structure-part-2-load ...

  2. 后渗透篇:映像劫持技术

    当你的才华 还撑不起你的野心时 那你就应该静下心来学习 映像劫持技术 所谓的映像劫持就是Image File Execution Options(IFEO),位于注册表的 HKEY_LOCAL_MAC ...

  3. Win7下实现 lpk.dll劫持游戏注入

    由于输入表中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索DLL文件.首先会尝试从当前程序所在的目录加载DLL,如果没找到,则在Windows系统目录中查找,最后是在环境变量中列出的各个 ...

  4. 【PC样本分析】 一次对lpk.dll劫持木马的分析

    前言 这是一个比较老的样本了,我是在其他论坛里面找到的这个样本,这里写这个文章是通过从内部来剖析该木马的.如果不对的地方还请各位大神们赐教,不足的地方还希望大家能够给我补充一下.谢谢 dll劫持原理 ...

  5. 后渗透篇:常见backdoor和persistence方式方法

    常见backdoor和persistence方式方法 系统工具替换后门 Image 劫持辅助工具管理器 REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT ...

  6. 后渗透篇:COM Object hijacking 后门实现思路——劫持CAccPropServicesClass and MMDeviceEnumerator

    0x00 前言 在之前的文章<Use CLR to maintain persistence>介绍了通过 CLR 劫持所有 .Net 程序的方法,无需管理员权限,可用作后门.美中不足的是通 ...

  7. C/C++劫持技术(函数劫持、dll注入、动态库注入、HOOK)

    目录 劫持 detours 实现劫持 步骤: 1. 安装Detours 2. 编译Detours工程 3. 把静态库和头文件引入工程 4. 函数指针与函数的定义 5.拦截 劫持QQ 实现劫持syste ...

  8. 后渗透篇:利用Volatility进行入侵痕迹分析

    本文利用Volatility进行内存取证,分析入侵攻击痕迹,包括网络连接.进程.服务.驱动模块.DLL.handles.检测进程注入.检测Meterpreter.cmd历史命令.IE浏览器历史记录.启 ...

  9. 后渗透篇:Windows 2008 server提权之突破系统权限安装shift后门

    当你的才华 还撑不起你的野心时 那你就应该静下心来学习 目录 Windows 2008 server提权之突破系统权限安装shift后门 0x01 前言 0x02 主要操作部分 0x03 主要命令组成 ...

最新文章

  1. 深度学习CTR预估模型凭什么成为互联网增长的关键?
  2. 如何自动保存 Spring Boot 应用进程号?
  3. 使用qwt作曲线图——有网格线背景的画法
  4. 冒号课堂§6.4:后台脚本
  5. Node.js-Express框架
  6. 【Flink】Flink 报错 Hash join exceeded Too many duplicate keys
  7. PHP第十次实验总结,The Clean Architecture in PHP 读书笔记(十)
  8. hypermesh安装包百度云_HYPERMESH11.0 64bt软件
  9. java lambda表达式详解_java8新特性-Lambda表达式的详解(从0开始)
  10. Ubuntu 安装 OpenCV(亲测有效)
  11. 利用MEGA做序列比对
  12. pdf如何转换成word文档格式
  13. Gflops是什么?
  14. H266 ISP 帧内子划分
  15. HTTP:超文本传输协议
  16. docker下载gcr.io镜像
  17. SCOI-2017 游记 SCOI-2017 酱油记 SCOI-2017 没有滚粗资格的记
  18. SpringBoot整合Elasticsearch,中软国际java二面华为面试
  19. Joplin+七牛云+vscode 免费云端同步笔记工具(跨平台)
  20. Typora插入图片的合理保存【windows平台】

热门文章

  1. 2.文件---open
  2. sdk无法打开的原因,值得新手参考
  3. 传奇登录器列表显示不连接
  4. 高校教师科研文献管理系统
  5. 2023财年Q4业绩继续下滑,ChatGPT能驱动英伟达重回巅峰吗?
  6. element-ui输入框限制只能输入数字一系列问题
  7. element-ui input限制输入数字
  8. java语言常用的包和类
  9. Django实现短信注册功能
  10. linux代码行数统计工具,统计代码行数工具 用golang实现