远程线程注入

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28110727/article/details/81774342

在win32进程中,每个进程都有自己独立的4GB地址空间,各个进程之间相互不影响,win32API中提供能够了2个函数,writeProcessMemory和readProcessMemory,这两个函数可以在指定进程的内存中进行读写操作。

HANDLE CreateRemoteThread(

     HANDLE hProcess,

     LPSECURITY_ATTRIBUTES lpThreadAttributes,

     SIZE_T dwStackSize,

     LPTHREAD_START_ROUTINE lpStartAddress,

     LPVOID lpParameter,

     DWORD dwCreationFlags,

     LPDWORD lpThreadId

);

参数说明:

hProcess:目标进程的句柄

lpThreadAttributes:指向线程的安全描述结构体的指针,一般设置为NULL,表示使用默认的安全级别

dwStackSize:线程堆栈大小,一般设置为0,表示使用默认的大小,一般为1M

lpStartAddress:线程函数的地址

lpParameter:线程参数

dwCreationFlags:线程的创建方式

                  CREATE_SUSPENDED 线程以挂起方式创建

lpThreadId:输出参数,记录创建的远程线程的ID

CreateRemoteThread函数可以在指定进程中创建线程,但是线程的入口函数必须在目标进程中,那么我们如何在目标进程中写入我们的代码。通常就是在目标进程中写入 LoadLiraryA ,让其来加载我们的 DLL 文件(我们在目标进程中写入的代码)。DllMain 函数就开始运行了,通常也是在 DllMain 中创建一个线程,用 CreateThread ,记住,这个线程是在目标进程中创建的了,因为这个 DLL 文件已经被加载到了目标进程中,这就叫做远程线程注入。首先用 VirtualAllocEx 来在目标进程中分配一个内存空间,然后再在这个空间中把 DLL 的路径名写到目标进程中,然后创建远线程,把这个空间的地址传给LoadLibraryA ,因为这样 DLL 的路径名就在目标进程里了,LoadLibraryA 也就可以正确加载 DLL 了,然后 DLL 就可以响应 DLL_PROCESS_ATTACH,然后就可以创建线程了,然后那个 EXE 就可以退出了,只要被注入的进程不退出,那么 DLL 文件将一直运行。

typedef struct tagPROCESSENTRY32

{

    DWORD dwSize; //sizeof(tagPROCESSENTRY32)

    DWORD cntUsage; //进程的引用计数,未使用,设置为0

    DWORD th32ProcessID; //进程ID

    ULONG_PTR th32DefaultHeapID; //进程默认堆ID,未使用,设置为0

    DWORD th32ModuleID; //进程模块ID, 未使用,设置为0

    DWORD cntThreads; //进程开启的线程计数

    DWORD th32ParentProcessID; //父进程ID

    LONG pcPriClassBase;

    DWORD dwFlags;

    TCHAR szExeFile[MAX_PATH]; //进程的可执行文件名称,非完整路径

} PROCESSENTRY32, *PPROCESSENTRY32;

0.可以通过进程快照信息,遍历进程快照,通过进程名称,找到需要注入的进程ID。

CreateToolhelp32Snapshot(TH32CS_SNAPPPROCESS, 0);

1.获取想要注入进程的句柄

Handle handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);

2.计算DLL路径名需要的字节数.在远程线程中为路径名分配空间.

cch = 1 + lstrlen(lpszLibName);

pszLibFileRemote = (PSTR)VirtualAllocEx

(hProcess, NULL, cch, MEM_COMMIT, PAGE_READWRITE);

3.将DLL的路径名复制到远程进程的内存空间.

WriteProcessMemory(hProcess, (PVOID)pszLibFileRemote, (PVOID)lpszLibName, cch, NULL)) 

4.获得LoadLibraryA在Kernel32.dll中的真正地址. 

pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(

GetModuleHandle(TEXT("Kernel32")),

TEXT("LoadLibraryA"));

5.创建远程线程,并通过远程线程调用用户的DLL文件. 

hThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, 

(PVOID)pszLibFileRemote, 0, NULL);

6.等待远程线程终止.

WaitForSingleObject(hThread, INFINITE);

7.关闭句柄. 

if (pszLibFileRemote != NULL) 

VirtualFreeEx(hProcess, (PVOID)pszLibFileRemote, 0, MEM_RELEASE);

if (hThread  != NULL) 

CloseHandle(hThread);

if (hProcess != NULL) 

CloseHandle(hProcess);

猜你喜欢

转载自blog.csdn.net/qq_28110727/article/details/81774342