win32api | 逆向 | 进程间通信与dll注入外挂原理

本随笔记录通过win32api学习进程间通信和dll注入外挂原理的学习过程

基本思路:

  1. 通过dll注入的方式将代码加载进目标进程
  2. 通过共享内存的方式进行数据通信(共享物理页)
  3. 通过循环读取命令队列,并通过内联汇编的方式调用各种函数

准备/具体实现:

1.获取进程PID:

说明通过函数去实现,这样就不需要每次都修改再编译。【之前没有详细写过这块,所以这边会详细的写一下】

重要头文件:#include <tlhelp32.h>

原理:通过CreateToolhelp32Snapshot()函数捕捉即时的操作系统进程快照,再遍历找出需要使用的进程。

重要结构体:PROCESSENTRY32结构体

具体代码实现如下(函数参数为可执行文件名而不是窗口名):

 1 DWORD GetPid(char* szName){
 2     HANDLE hprocessSnap = NULL;
 3     PROCESSENTRY32 pe32 = {0};
 4     hprocessSnap = CreateToolhelp32Snapshot(
 5         TH32CS_SNAPPROCESS,
 6         0);//捕捉所有进程的快照
 7     if (hprocessSnap == INVALID_HANDLE_VALUE){
 8         //快照失败
 9         return 0;
10     }
11     //初始化pe32结构体
12     pe32.dwSize = sizeof(PROCESSENTRY32);
13     if (Process32First(hprocessSnap, &pe32)){
14         do{
15             if (!strcmp(szName, pe32.szExeFile)){
16                 printf("Process Found, PID: %d 
", (int)pe32.th32ProcessID);
17                 return (int)pe32.th32ProcessID;
18             }
19             //遍历查找进程名
20         }while (Process32Next(hprocessSnap, &pe32));
21     }else{
22         CloseHandle(hprocessSnap);
23     }
24     return 0;
25 }

2.共享内存的实现(共享物理页):

这里主要就是那几个api函数以及原理,直接贴关键代码了。

执行注入程序的代码:

 1 //创建一块共享内存物理页
 2 HANDLE hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,0x1000,"外挂");
 3 DWORD dwtype = 0;
 4 if (hMapFile == NULL){
 5     printf("CreateFileMapping Error 
");
 6 }
 7 //映射内存
 8 LPTSTR lpBuff = (LPTSTR)MapViewOfFile(hMapFile, 
 9                 FILE_MAP_ALL_ACCESS,
10                 0,0,BUFSIZ);
11 if (lpBuff == NULL){
12     printf("MapViewOfFile error 
");
13     exit(0);
14 }

被注入的dll的代码:

 1 //共享内存映射
 2 HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "外挂");
 3 DWORD dwtype = 0;
 4 if (hMapFile == NULL){
 5     printf("OpenFileMapping Error 
");
 6 }
 7 //映射内存
 8 LPTSTR lpBuff = (LPTSTR)MapViewOfFile(hMapFile, 
 9     FILE_MAP_ALL_ACCESS,
10     0,0,BUFSIZ);

关键的api函数:CreateFileMapping/OpenFileMapping/MapViewOfFile

之后通过CopyMemory的方式进行共享内存的读写。

3.dll注入:

dll注入的内容在上一篇随笔中已经有了详细的记录,此处不再赘述。

链接:https://www.cnblogs.com/Mz1-rc/p/13671844.html

4.内联汇编调用各种函数:

先通过调试器找到所有函数的地址,再通过dll去调用。

例:

1 #define ATTACK 0x00401014
2 __asm{
3     mov eax,ATTACK
4     call eax
5 }

5.将dll释放

由执行注入的线程对目标线程中的dll创建的线程传递信号,dll通过执行FreeLibraryAndExitThread()函数释放自身。

FreeLibraryAndExitThread((HMODULE)g_hModule, 0); //g_hModule与传入DllMain的第一个参数相同。

实现效果:

原文地址:https://www.cnblogs.com/Mz1-rc/p/13673102.html