Skip to content
利用Windows API开发的DLL注入工具
C++ C
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
InjectDll
.gitattributes
.gitignore
InjectDLLTool.sln
LICENSE
README.md

README.md

InjectDLLTool

利用Windows API开发的DLL注入工具

为什么要DLL注入?

有一些操作放在目标程序中比远程执行更方便,可定制性强。注入DLL可以帮助目标程序实现更多功能。

工具使用

流程

  • 选择DLL
  • 输入进程名,大小写敏感(推荐使用火绒剑查看)
  • 点击“注入”按钮
  • (此时转到DLL操作)
  • 点击“卸载”按钮(如果不卸载就不能再次注入)
  • 退出本程序

问题

  1. 如果点击“注入”按钮之后,DLL没有注入或者无反应,则是DLL的问题,与本程序无关。
  2. 如果多次点击“注入”按钮没有反应,先尝试点击“卸载”按钮,知道弹出“卸载失败”后再次注入。

原理解释

DLL注入步骤

大概流程如下:

  1. 打开进程,获取进程句柄
  2. 在目标进程中申请内存空间
  3. 写入DLL路径
  4. 创建远程调用线程通过LoadLibrary载入dll

涉及的API主要如下:

  • OpenProcess

  • VirtualAllocEx

  • WriteProcessMemory

  • VirtualFreeEx

  • CreateRemoteThread

  • WaitForSingleObject

示例代码:

BOOL InjectDll(char * szDllPath, DWORD dwPID)

{

       // 获取进程访问权限

       HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);

       if (!hProcess)

       {

              return FALSE;

       }

       // 申请内存空间

       LPVOID lpDllMem = VirtualAllocEx(hProcess, NULL, sizeof(szDllPath), 
MEM_COMMIT, PAGE_READWRITE);

       if (!lpDllMem)

       {

              CloseHandle(hProcess);

              return FALSE;

       }

       // dll路径写入内存

       if (0 == WriteProcessMemory(hProcess, lpDllMem, szDllPath, 
sizeof(szDllPath), NULL))

       {

              VirtualFreeEx(hProcess, lpDllMem, sizeof(szDllPath), MEM_DECOMMIT);

              CloseHandle(hProcess);

              return FALSE;

       }

       // 调用远程dll

       HMODULE hK32 = GetModuleHandle(_T("Kernel32.dll"));

       LPVOID lpLoadLibAddr = GetProcAddress(hK32, "LoadLibraryA");

       HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, 
(LPTHREAD_START_ROUTINE)lpLoadLibAddr, lpDllMem, 0, 0);

       if (!hThread)

       {

              VirtualFreeEx(hProcess, lpDllMem, sizeof(szDllPath), MEM_DECOMMIT);

              CloseHandle(hProcess);

              return FALSE;

       }



       WaitForSingleObject(hThread, INFINITE);

       VirtualFreeEx(hProcess, lpDllMem, sizeof(szDllPath), MEM_DECOMMIT);

       CloseHandle(hThread);

       CloseHandle(hProcess);

       /*TCHAR test[100] = { 0 };

       _sntprintf_s(test, sizeof(test)/sizeof(TCHAR), _T("写入的地址: %p"), 
lpDllMem);

       OutputDebugString(test);*/

       return TRUE;

}

DLL卸载

卸载与注入步骤类似,注入用的LoadLibrary,卸载用FreeLibrary。示例如下:

BOOL UnInjectDll(char * szDllPath, DWORD dwPID)

{
       char szDName[0x100] = "WeChatHelperDll.dll";

       // 获取进程访问权限

       HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);

       if (!hProcess)

       {

              return FALSE;

       }

       HMODULE hK32 = GetModuleHandle(_T("Kernel32.dll"));

       LPVOID lpFreeLibAddr = GetProcAddress(hK32, "FreeLibraryAndExitThread");

       HMODULE hDll = GetDLLHandle(szDName, dwPID);

       if (!hDll)

       {

              CloseHandle(hProcess);

              return FALSE;

       }

       HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, 
(LPTHREAD_START_ROUTINE)lpFreeLibAddr, hDll, 0, 0);

       if (!hThread)

       {

              CloseHandle(hProcess);

              return FALSE;

       }



       WaitForSingleObject(hThread, INFINITE);

       CloseHandle(hThread);

       CloseHandle(hProcess);

       return TRUE;

}

注意这里没有使用的FreeLibrary,在Win10系统中测试注入微信,发生了异常崩溃,改用FreeLibraryAndExitThread后正常卸载,原因尚不明确。

You can’t perform that action at this time.