远程线程注入DLL技术及其实践

17,424次阅读
没有评论

共计 2533 个字符,预计需要花费 7 分钟才能阅读完成。

前言

通过多个 Api 配合使用 CreateRemoteThread 使用实现让目标进程加载指定 DLL 或二进制代码并执行

注入步骤

  1. 获取进程 Pid
    • 获取窗口句柄,可以通过 FindWindow 获取窗口句柄拿进程 ID GetWindowThreadProcessId
    • 也可以直接遍历进程获取 Pid
  2. 通过 OpenProcess 打开进程
  3. 通过 VirtualAllocEx 在目标进程上申请一块内存空间
  4. 通过 WriteProcessMemory 往申请的内存空间里面写入 DLL 路径或二进制代码
  5. 获取 LoadLibraryA 函数地址
    • 先通过 GetModuleHandle 拿到模块句柄 在通过 GetProcAddress 获取函数地址
    • 或则 先通过(LoadLibraryA – GetModuleHandle)RVA 函数在模块中的偏移,在通过遍历等方式拿到目标进程的 kernel32 的模块句柄,模块句柄 + RVA 函数偏移 = LoadLibraryA 在目标进程的位置
  6. 通过 WriteProcessMemory 创建远程线程执行注入的 DLL 或二进制代码

完整代码

#include <cstdio>
#include <Windows.h>

int main()
{
	// 获取窗口句柄
	HWND hWnd = FindWindow(TEXT("wcTKKN"), NULL);
	if (hWnd == NULL)
	{printf("FindWindow error \n");
		return 0;
	}

	printf("FindWindow %p \n" , hWnd);

	// 通过窗口句柄获取进程 ID
	DWORD dwPid = 0;
	GetWindowThreadProcessId(hWnd, &dwPid);
	if (dwPid == 0)
	{printf("GetWindowThreadProcessId error \n");
		return 0;
	}

	printf("GetWindowThreadProcessId %d \n", dwPid);

	// 通过进程 ID 打开进程拿到进程句柄
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
	if (hProcess == NULL)
	{printf("OpenProcess error \n");
		return 0;
	}

	printf("OpenProcess %p \n", hProcess);

	// 通过进程句柄 申请内存空间
	LPVOID lpBuffer =  VirtualAllocEx(hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if (lpBuffer == NULL)
	{printf("VirtualAllocEx error \n");
		CloseHandle(hProcess);
		return 0;
	}

	// 在内存空间内写入 dll 路径或二进制代码
	char szPath[MAX_PATH] = "D:\\InjectDll.dll";
	DWORD dwBytes = 0;
	BOOL bRet = WriteProcessMemory(hProcess, lpBuffer, szPath, MAX_PATH, &dwBytes);
	if (bRet == FALSE || dwBytes != MAX_PATH)
	{printf("WriteProcessMemory error \n");
		VirtualFree(lpBuffer, 0, MEM_RELEASE);
		CloseHandle(hProcess);
		return 0;
	}

	printf("WriteProcessMemory %d \n", dwBytes);

	// 获取 kernel32 模块地址
	HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32"));
	if (hKernel32 == NULL)
	{printf("GetModuleHandle error \n");
		VirtualFree(lpBuffer, 0, MEM_RELEASE);
		CloseHandle(hProcess);
		return 0;
	}

	printf("GetModuleHandle %p \n", hKernel32);

	// 通过模块地址 拿到 LoadLibraryA 函数地址
	FARPROC pLoadLibrary = GetProcAddress(hKernel32, "LoadLibraryA");
	if (pLoadLibrary == NULL)
	{printf("GetProcAddress error \n");
		VirtualFree(lpBuffer, 0, MEM_RELEASE);
		CloseHandle(hProcess);
		return 0;
	}

	printf("GetProcAddress %p \n", pLoadLibrary);

	// 创建远程线程
	HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pLoadLibrary, lpBuffer, 0, NULL);
	if (hThread == NULL)
	{printf("CreateRemoteThread error \n");
		VirtualFree(lpBuffer, 0, MEM_RELEASE);
		CloseHandle(hProcess);
		return 0;
	}

	printf("CreateRemoteThread %p \n", hThread);
	
	// 等待线程结束
	WaitForSingleObject(hThread, -1);
	DWORD dwExitCode = 0;
	GetExitCodeThread(hThread, &dwExitCode);
	printf("GetExitCodeThread %d \n", dwExitCode);
	if (dwExitCode == NULL)
	{printf("Inject error \n");
	} 
	else
	{printf("Inject ok \n");
	}

	// 释放资源
	CloseHandle(hThread);
	VirtualFree(lpBuffer, 0, MEM_RELEASE);
	CloseHandle(hProcess);
	return 0;
}

正文完
 0
s2ad0w
版权声明:本站原创文章,由 s2ad0w 于2023-07-17发表,共计2533字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)