方式三:使用远程线程注入DLL

本文介绍了如何使用CreateRemoteThread API进行DLL注入和卸载的过程。通过创建远程线程调用LoadLibraryW或FreeLibrary来实现DLL的加载与卸载,并展示了具体的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


HANDLE WINAPI CreateRemoteThread(
  __in   HANDLE hProcess,
  __in   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in   SIZE_T dwStackSize,
  __in   LPTHREAD_START_ROUTINE lpStartAddress,
  __in   LPVOID lpParameter,
  __in   DWORD dwCreationFlags,
  __out  LPDWORD lpThreadId
);

lpStartAddress 必须是LoadLibraryW绝对地址(GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW"));
不能直接写LoadLibraryW名字,因为它是个导入函数,先是经过转换函数再跳到上面绝对地址,不能把导入函数地址当成实际地址使用。
lpParameter 必须是目标进程空中中的地址。
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID) pszLibFile, cb, NULL)

exemain.cpp
#include <Windows.h>
#include <TlHelp32.h>
#include <tchar.h>
#include <stdio.h>

wchar_t log[1024] = { 0 };

BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {

   BOOL bOk = FALSE; // Assume that the function fails
   HANDLE hProcess = NULL, hThread = NULL;
   PWSTR pszLibFileRemote = NULL;

   __try {
      // Get a handle for the target process.
      hProcess = OpenProcess(
         PROCESS_QUERY_INFORMATION |   // Required by Alpha
         PROCESS_CREATE_THREAD     |   // For CreateRemoteThread
         PROCESS_VM_OPERATION      |   // For VirtualAllocEx/VirtualFreeEx
         PROCESS_VM_WRITE,             // For WriteProcessMemory
         FALSE, dwProcessId);
      if (hProcess == NULL) __leave;

      // Calculate the number of bytes needed for the DLL's pathname
      int cch = 1 + lstrlenW(pszLibFile);
      int cb  = cch * sizeof(wchar_t);

      // Allocate space in the remote process for the pathname
      pszLibFileRemote = (PWSTR) 
         VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
      if (pszLibFileRemote == NULL) __leave;

      // Copy the DLL's pathname to the remote process' address space
      if (!WriteProcessMemory(hProcess, pszLibFileRemote, 
         (PVOID) pszLibFile, cb, NULL)) __leave;

      // Get the real address of LoadLibraryW in Kernel32.dll
      PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
         GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
      if (pfnThreadRtn == NULL) __leave;

      // Create a remote thread that calls LoadLibraryW(DLLPathname)
	  DWORD remoteTID = 0;
      hThread = CreateRemoteThread(hProcess, NULL, 0, 
         pfnThreadRtn, pszLibFileRemote, 0, &remoteTID);
	  wsprintfW(log,L"CreateRemoteThread tid:%d for inject dll.\n",remoteTID);
	  ::OutputDebugStringW(log);
      if (hThread == NULL) __leave;

      // Wait for the remote thread to terminate
      WaitForSingleObject(hThread, INFINITE);

      bOk = TRUE; // Everything executed successfully
   }
   __finally { // Now, we can clean everything up

      // Free the remote memory that contained the DLL's pathname
      if (pszLibFileRemote != NULL) 
         VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);

      if (hThread  != NULL) 
         CloseHandle(hThread);

      if (hProcess != NULL) 
         CloseHandle(hProcess);
   }

   return(bOk);
}

BOOL WINAPI EjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {

   BOOL bOk = FALSE; // Assume that the function fails
   HANDLE hthSnapshot = NULL;
   HANDLE hProcess = NULL, hThread = NULL;

   __try {
      // Grab a new snapshot of the process
      hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
      if (hthSnapshot == INVALID_HANDLE_VALUE) __leave;

      // Get the HMODULE of the desired library
      MODULEENTRY32W me = { sizeof(me) };
      BOOL bFound = FALSE;
      BOOL bMoreMods = Module32FirstW(hthSnapshot, &me);
      for (; bMoreMods; bMoreMods = Module32NextW(hthSnapshot, &me)) {
         bFound = (_wcsicmp(me.szModule,  pszLibFile) == 0) || 
                  (_wcsicmp(me.szExePath, pszLibFile) == 0);
         if (bFound) break;
      }
      if (!bFound) __leave;

      // Get a handle for the target process.
      hProcess = OpenProcess(
         PROCESS_QUERY_INFORMATION |   
         PROCESS_CREATE_THREAD     | 
         PROCESS_VM_OPERATION,  // For CreateRemoteThread
         FALSE, dwProcessId);
      if (hProcess == NULL) __leave;

      // Get the real address of FreeLibrary in Kernel32.dll
      PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
         GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "FreeLibrary");
      if (pfnThreadRtn == NULL) __leave;

      // Create a remote thread that calls FreeLibrary()
      //hThread = CreateRemoteThread(hProcess, NULL, 0, 
      //   pfnThreadRtn, me.modBaseAddr, 0, NULL);
	  DWORD remoteTID = 0;
	  hThread = CreateRemoteThread(hProcess, NULL, 0, 
         pfnThreadRtn, me.hModule, 0, &remoteTID);
	  wsprintfW(log,L"CreateRemoteThread tid:%d for Eject dll.\n",remoteTID);
	  ::OutputDebugStringW(log);
      if (hThread == NULL) __leave;

      // Wait for the remote thread to terminate
      WaitForSingleObject(hThread, INFINITE);

      bOk = TRUE; // Everything executed successfully
   }
   __finally { // Now we can clean everything up

      if (hthSnapshot != NULL) 
         CloseHandle(hthSnapshot);

      if (hThread     != NULL) 
         CloseHandle(hThread);

      if (hProcess    != NULL) 
         CloseHandle(hProcess);
   }

   return(bOk);
}

void main(int argc, wchar_t **argv)
{
	wchar_t szLibFile[MAX_PATH];
    GetModuleFileNameW(NULL, szLibFile, _countof(szLibFile));
    wchar_t *pFilename = wcsrchr(szLibFile, L'\\') + 1;
    wcscpy_s(pFilename, _countof(szLibFile) - (pFilename-szLibFile),L"injectdll.dll");
	DWORD pid = 0;
	wprintf_s(L"Please put in inject process ID:\n");
	wscanf_s(L"%d",&pid);
	//pid = GetCurrentProcessId();
	InjectLibW(pid,szLibFile);
	getchar();
	EjectLibW(pid,szLibFile);
}


 

 

dllmain.cpp

#include <windows.h>

wchar_t log[1024] = { 0 };

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		wsprintfW(log,L"DLL_PROCESS_ATTACH tid:%d \n",GetCurrentThreadId());
		::OutputDebugStringW(log);
		break;
	case DLL_THREAD_ATTACH:
		wsprintfW(log,L"DLL_THREAD_ATTACH tid:%d \n",GetCurrentThreadId());
		::OutputDebugStringW(log);
		break;
	case DLL_THREAD_DETACH:
		wsprintfW(log,L"DLL_THREAD_DETACH tid:%d \n",GetCurrentThreadId());
		::OutputDebugStringW(log);
		break;
	case DLL_PROCESS_DETACH:
		wsprintfW(log,L"DLL_PROCESS_DETACH tid:%d \n",GetCurrentThreadId());
		::OutputDebugStringW(log);
		break;
	}
	return TRUE;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值