Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 680|回复: 0
打印 上一主题 下一主题

详细解读:远程线程注入DLL到PC版微信

[复制链接]

1228

主题

1998

帖子

7598

积分

认证用户组

Rank: 5Rank: 5

积分
7598
跳转到指定楼层
楼主
发表于 2020-3-4 23:08:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
https://www.cnblogs.com/codex/p/10849200.html
一、远程线程注入的原理
  1、其基础是在 Windows 系统中,每个 .exe 文件在双击打开时都会加载 kernel32.dll 这个系统模块,该模块中有一个 LoadLibrary() 函数,可以将DLL文件加载到自身进程中。
  2、这样,就可以用 CreateRemoteThread() 函数创建一个远程线程,让目标进程调用LoadLibrary() 来加载我们自己写的DLL 。CreateRemoteThread() 有这几个参数比较关键:A:想要注入的进程的句柄,这里可以通过OpenProcess()得到; B:想要运行的函数,本例中当然是 LoadLibrary() 啦; C: 所运行函数的参数,本例中是自己写的DLL的存放路径。
  3、那么,怎么让 LoadLibrary() 找到自己写的DLL的存放路径呢?这就需要在内存中开辟一块空间,把路径写入进去。这要先用 VirtualAllocEx()开辟一块空间,然后用WriteProcessMemory() 函数把DLL路径写进去。
  4、小结:总的来说,就是:先在目标进程的内存空间里开辟一块新地方,往新地方里面写入DLL的路径,再创建远程线程找到LoadLibrary() 函数,并在刚才开辟的新地方中读取DLL路径,进而加载我们自己写的DLL。
二、代码实现(含详细注释)
  1. #include <iostream>
  2. #include "stdlib.h"
  3. #include <tchar.h>
  4. #include <Windows.h>

  5. bool Inject(DWORD dwId, WCHAR* szPath)//参数1:目标进程PID  参数2:DLL路径
  6. {
  7.     //一、在目标进程中申请一个空间


  8.     /*
  9.     【1.1 获取目标进程句柄】
  10.     参数1:想要拥有的进程权限(本例为所有能获得的权限)
  11.     参数2:表示所得到的进程句柄是否可以被继承
  12.     参数3:被打开进程的PID
  13.     返回值:指定进程的句柄
  14.     */
  15.     HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwId);


  16.     /*
  17.     【1.2 在目标进程的内存里开辟空间】
  18.     参数1:目标进程句柄
  19.     参数2:保留页面的内存地址,一般用NULL自动分配
  20.     参数3:欲分配的内存大小,字节单位
  21.     参数4:MEM_COMMIT:为特定的页面区域分配内存中或磁盘的页面文件中的物理存储
  22.     参数5:PAGE_READWRITE 区域可被应用程序读写
  23.     返回值:执行成功就返回分配内存的首地址,不成功就是NULL
  24.     */
  25.     LPVOID pRemoteAddress = VirtualAllocEx(
  26.         hProcess,
  27.         NULL,
  28.         1,
  29.         MEM_COMMIT,
  30.         PAGE_READWRITE
  31.     );

  32.     //二、 把dll的路径写入到目标进程的内存空间中

  33.     DWORD dwWriteSize = 0;
  34.     /*
  35.     【写一段数据到刚才给指定进程所开辟的内存空间里】
  36.     参数1:OpenProcess返回的进程句柄
  37.     参数2:准备写入的内存首地址
  38.     参数3:指向要写的数据的指针(准备写入的东西)
  39.     参数4:要写入的字节数(东西的长度+0/)
  40.     参数5: 返回值。返回实际写入的字节
  41.     */
  42.     WriteProcessMemory(hProcess,pRemoteAddress, szPath, wcslen(szPath) * 2 + 2, &dwWriteSize);


  43.     //三、 创建一个远程线程,让目标进程调用LoadLibrary

  44.     /*
  45.     参数1:该远程线程所属进程的进程句柄
  46.     参数2:一个指向 SECURITY_ATTRIBUTES 结构的指针, 该结构指定了线程的安全属性
  47.     参数3:线程栈初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小
  48.     参数4:在远程进程的地址空间中,该线程的线程函数的起始地址(也就是这个线程具体要干的活儿)
  49.     参数5:传给线程函数的参数(刚才在内存里开辟的空间里面写入的东西)
  50.     参数6:控制线程创建的标志。0(NULL)表示该线程在创建后立即运行
  51.     参数7:指向接收线程标识符的变量的指针。如果此参数为NULL,则不返回线程标识符
  52.     返回值:如果函数成功,则返回值是新线程的句柄。如果函数失败,则返回值为NULL
  53.     */
  54.     HANDLE hThread = CreateRemoteThread(
  55.         hProcess,
  56.         NULL,
  57.         0,
  58.         (LPTHREAD_START_ROUTINE)LoadLibrary,
  59.         pRemoteAddress,
  60.         NULL,
  61.         NULL
  62.     );
  63.     WaitForSingleObject(hThread, -1); //当句柄所指的线程有信号的时候,才会返回
  64.    
  65.     /*
  66.     四、 【释放申请的虚拟内存空间】
  67.     参数1:目标进程的句柄。该句柄必须拥有 PROCESS_VM_OPERATION 权限
  68.     参数2:指向要释放的虚拟内存空间首地址的指针
  69.     参数3:虚拟内存空间的字节数
  70.     参数4:MEM_DECOMMIT仅标示内存空间不可用,内存页还将存在。
  71.            MEM_RELEASE这种方式很彻底,完全回收。
  72.     */
  73.     VirtualFreeEx(hProcess, pRemoteAddress, 1, MEM_DECOMMIT);
  74.     return 0;
  75. }


  76. int _tmain(int argc, _TCHAR * argv[])
  77. {
  78.     wchar_t wStr[] = L"E:\\inject.dll";
  79.     DWORD dwId = 0;

  80.     //参数1:(NULL
  81.     //参数2:目标窗口的标题
  82.     //返回值:目标窗口的句柄
  83.     HWND hCalc = FindWindow(NULL, L"微信");
  84.     printf("目标窗口的句柄为:%d\n", hCalc);

  85.     DWORD dwPid = 0;

  86.     //参数1:目标进程的窗口句柄
  87.     //参数2:把目标进程的PID存放进去
  88.     DWORD dwRub = GetWindowThreadProcessId(hCalc, &dwPid);
  89.     printf("目标窗口的进程PID为:%d\n", dwPid);

  90.     //参数1:目标进程的PID
  91.     //参数2:想要注入DLL的路径
  92.     Inject(dwPid, wStr);

  93.     return 0;
  94. }
复制代码
执行之后,DLL就注入到了PC版的微信进程。且该DLL中含有一个弹窗代码,也出现在了PC版微信的界面之上。


附:测试用的DLL代码
  1. #include <windows.h>


  2. DWORD WINAPI runBot(LPVOID lpParam) {
  3.     // 此处可以写具体的bot代码
  4.     return 1;
  5. }


  6. BOOL APIENTRY DllMain( HMODULE hModule,
  7.                        DWORD  ul_reason_for_call,
  8.                        LPVOID lpReserved
  9.                      )
  10. {
  11.     switch (ul_reason_for_call)
  12.     {
  13.     case DLL_PROCESS_ATTACH:
  14.         MessageBoxA(NULL, "DLL Attached!\n", "Game Hacking", MB_OK | MB_TOPMOST);
  15.         CreateThread(NULL, 0, &runBot, NULL, 0, NULL);
  16.         break;
  17.     }
  18.     return TRUE;
  19. }
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-5-18 01:41 , Processed in 0.058028 second(s), 19 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表