DLL注入之CreateRemoteThread

来源:互联网 发布:农村淘宝下载电脑版 编辑:程序博客网 时间:2024/05/13 01:49

本文转载自DLL注入的几种姿势(二):CreateRemoteThread And More
在SetWindowsHookEx中,我们使用LoadLibrary将DLL加载至当前进程(不是目标进程)的地址空间中,接着使用GetProcAddress获得所需函数的地址。下面的事情就交给SetWindowsHookEx了,构造一个钩子钩取一个会自动加载我们DLL的进程,这样就搞定整个DLL注入过程了。而CreateRemoteThread则跟上述过程不一样,下面是其步骤。
1.使用VirtualAllocEx在目标进程的地址空间中创建一块我们DLL所在路径长度的内存空间。
2.使用WriteProcessMemory将DLL路径写入分配的内存。
3.一旦DLL路径写入内存中,再使用CreateRemoteThread(或者其他无正式说明的功能),它再调用LoadLibrary函数将DLL注入目标进程中。
在代码中,我们使用CreateRemoteThread和两个无正式说明的函数NtCreateThreadEx和RtlCreateUserThread。NtCreateThreadEx是一个系统调用,是用户空间应用和内核打交道的方法;RtlCreateUserThread调用NtCreateThreadEx,因此RtlCreateUserThread应该是NtCreateThreadEx的封装。我们可以直接调用CreateRemoteThread因为它是Windows API的一部分,而NtCreateThreadEx和RtlCreateUserThread不具备这个特点,因此需要创建一个模板。

#include<stdio.h> #include<windows.h>HANDLE RtlCreateUserThread(HANDLE hProcess,LPVOID lpBaseAddress,LPVOID lpSpace){//The prototype of RtlCreateUserThread from undocumented.ntinternals.comtypedef DWORD(WINAPI * functypeRtlCreateUserThread)(HANDLE      ProcessHandle,PSECURITY_DESCRIPTOR  SecurityDescriptor,BOOL      CreateSuspended,ULONG     StackZeroBits,PULONG     StackReserved,PULONG     StackCommit,LPVOID     StartAddress,LPVOID     StartParameter,HANDLE      ThreadHandle,LPVOID     ClientID);//Get handle for ntdll which contains RtlCreateUserThreadHANDLE hRemoteThread = NULL;HMODULE hNtDllModule = GetModuleHandle("ntdll.dll");if (hNtDllModule == NULL){return NULL;}functypeRtlCreateUserThread funcRtlCreateUserThread = (functypeRtlCreateUserThread)GetProcAddress(hNtDllModule, "RtlCreateUserThread");if (!funcRtlCreateUserThread){return NULL;}funcRtlCreateUserThread(hProcess, NULL, 0, 0, 0, 0, lpBaseAddress, lpSpace,&hRemoteThread, NULL);DWORD lastError = GetLastError();return hRemoteThread;}HANDLE NtCreateThreadEx(HANDLE hProcess,LPVOID lpBaseAddress,LPVOID lpSpace){//The prototype of NtCreateThreadEx from undocumented.ntinternals.comtypedef DWORD(WINAPI * functypeNtCreateThreadEx)(PHANDLE                 ThreadHandle,ACCESS_MASK             DesiredAccess,LPVOID                  ObjectAttributes,HANDLE                  ProcessHandle,LPTHREAD_START_ROUTINE  lpStartAddress,LPVOID                  lpParameter,BOOL                    CreateSuspended,DWORD                   dwStackSize,DWORD                   Unknown1,DWORD                   Unknown2,LPVOID                  Unknown3);HANDLE                      hRemoteThread = NULL;HMODULE                     hNtDllModule = NULL;functypeNtCreateThreadEx    funcNtCreateThreadEx = NULL;//Get handle for ntdll which contains NtCreateThreadExhNtDllModule = GetModuleHandle("ntdll.dll");if (hNtDllModule == NULL){return NULL;}funcNtCreateThreadEx = (functypeNtCreateThreadEx)GetProcAddress(hNtDllModule, "NtCreateThreadEx");if (!funcNtCreateThreadEx){return NULL;}funcNtCreateThreadEx(&hRemoteThread, GENERIC_ALL, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, FALSE, NULL, NULL, NULL, NULL);return hRemoteThread;}int injectIntoPID(int process, int method){DWORD pid = (DWORD)process;char* dll = "D:\\DLLTest.dll";//Gets the process handle for the target processHANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);if (OpenProcess == NULL){puts("Could not find process");}//Retrieves kernel32.dll module handle for getting loadlibrary base addressHMODULE hModule = GetModuleHandle("kernel32.dll");//Gets address for LoadLibraryA in kernel32.dllLPVOID lpBaseAddress = (LPVOID)GetProcAddress(hModule, "LoadLibraryA");if (lpBaseAddress == NULL){puts("Unable to locate LoadLibraryA");return -1;}//Allocates space inside for inject.dll to our target processLPVOID lpSpace = (LPVOID)VirtualAllocEx(hProcess, NULL, strlen(dll), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);if (lpSpace == NULL){printf("Could not allocate memory in process %u", (int)process);return -1;}//Write inject.dll to memory of processint n = WriteProcessMemory(hProcess, lpSpace, dll, strlen(dll), NULL);if (n == 0){puts("Could not write to process's address space");return -1;}HANDLE hThread;switch (method){case 1:hThread = NtCreateThreadEx(hProcess, lpBaseAddress, lpSpace);break;case 2:hThread = RtlCreateUserThread(hProcess, lpBaseAddress, lpSpace);break;default:hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, NULL, NULL);}if (hThread == NULL){return -1;}else{DWORD threadId = GetThreadId(hThread);DWORD processId = GetProcessIdOfThread(hThread);printf("Injected thread id: %u for pid: %u", threadId, processId);getchar();getchar();getchar();CloseHandle(hProcess);return 0;}}int main(int argc, char* argv){int pid;int method;puts("Inject into which PID?");scanf_s("%u", &pid);puts("Which method? (0 (default): CRT, 1: NtCreateThread, 2: RtlCreateUserThread)");scanf_s("%u", &method);int result = injectIntoPID(pid, method);if (result == -1){puts("Could not inject into PID");}system("pause");}

按照在VS2015中用C++编写可被其它语言调用的动态库DLL中的方法在VS2015中创建我们所需的DLL。

// dllmain.cpp : Defines the entry point for the DLL application.#include "stdafx.h"#include  <stdio.h>BOOL APIENTRY DllMain( HMODULE hModule,                       DWORD  ul_reason_for_call,                       LPVOID lpReserved ){switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:char str[80];/*Get's the current process id to display in the message box*/int id = GetCurrentProcessId();sprintf_s(str, "Hello, process: %d", id);MessageBox(NULL, str, "Hello DLL!", MB_OK);return 0;break;}return TRUE;}


DLL、EXE和源代码在github:dll-injection-by-CreateRemoteThread


0 0
原创粉丝点击