bubbletea 发表于 2018-2-15 00:51

【C语言】编写的DLL注入工具

本帖最后由 wushaominkk 于 2018-4-26 11:11 编辑

现已更新附件,之前的代码有个地方有问题,EjectDll.c中第77行return 1;之前加上一句
((PFFREELIBRARY)pParam->pFunc)(hModule);
再编译生成一下,否则不执行用户输入的卸载时执行函数就无法卸载DLL。
最近学习了几种DLL注入的方式,这里分享一个我写的DLL注入工具(ring3),编译平台是windows7 32位+VS2013,含32位和64位,win10上测试了一下也能运行。

注入方式使用的是代码注入,参考了《逆向工程核心原理》中的相关代码。代码注入占用内存少并难以查找痕迹,在代码量小的时候比较合适。
不过这边有一个问题就是在执行用户选择的启动函数时我选择让目标进程使用CreateThread来调用dll的导出函数,这样做是否合适?测试了一些暂时还没发现什么问题

// 参数类型
typedef struct _INJECTTHREAD_PARAM
{
      FARPROC pFunc;
      char szBuf;
} INJECTTHREAD_PARAM, *PINJECTTHREAD_PARAM;

// 此函数以代码形式注入目标进程
DWORD WINAPI InjectThreadProc(LPVOID param)
{
      PINJECTTHREAD_PARAM pParam = (PINJECTTHREAD_PARAM)param;
      HMODULE hModule;
      FARPROC pFunc;
      HANDLE hThread;

      // 注入的代码里不能直接调用API函数
      // LoadLibraryA(szDllPath)
      hModule = ((PFLOADLIBRARYA)pParam->pFunc)(pParam->szBuf);
      if (!hModule)
      {
                return 1;
      }

      // GetProcAddress(hModule, szFunc)
      pFunc = ((PFGETPROCADDRESS)pParam->pFunc)(hModule, pParam->szBuf);
      if (!pFunc)
      {
                return 1;
      }

      // CreateThread()执行加载时要运行的函数, 不知道使用这种方式合不合适
      hThread = ((PFCREATETHREAD)pParam->pFunc)(NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, NULL, 0, NULL);

      return 0;
}

BOOL InjectDll(DWORD dwPID, LPCSTR szDllPath, LPCSTR szFunc)
{
      HMODULE hModule;
      INJECTTHREAD_PARAM param;
      HANDLE hProcess;
      HANDLE hThread;
      LPVOID pRemoteBuf;
      DWORD dwSize;

      hModule = GetModuleHandleW(L"kernel32.dll");
      memset(¶m, 0, sizeof(INJECTTHREAD_PARAM));
      // 要进行代码注入, 就必需要把要调用参数先写入目标进程
      param.pFunc = GetProcAddress(hModule, "LoadLibraryA");
      param.pFunc = GetProcAddress(hModule, "GetProcAddress");
      param.pFunc = GetProcAddress(hModule, "CreateThread");
      strcpy_s(param.szBuf, strlen(szDllPath) + 1, szDllPath);
      strcpy_s(param.szBuf, strlen(szFunc) + 1, szFunc);

      if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
      {
                return FALSE;
      }

      // 判断环境
      if (Is64BitProcess(GetCurrentProcess()) != Is64BitProcess(hProcess))
      {
                MessageBox(NULL, TEXT("打开动态链接库文件失败"), TEXT("提示"), MB_ICONERROR | MB_OK);
                CloseHandle(hProcess);
                return FALSE;
      }

      dwSize = sizeof(INJECTTHREAD_PARAM);
      if (!(pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE)))
      {
                return FALSE;
      }
      // 将全部的参数作为结构体整个写入
      if (!WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)¶m, dwSize, NULL))
      {
                return FALSE;
      }

      dwSize = (DWORD)InjectDll - (DWORD)InjectThreadProc;
      if (!(pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE)))
      {
                return FALSE;
      }
      // 再将InjectThreadProc的函数代码写入目标进程
      if (!WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)InjectThreadProc, dwSize, NULL))
      {
                return FALSE;
      }

      // pRemoteBuf就是InjectThreadProc在目标进程中的起始地址, 已经被写入, pRemoteBuf则是写入的参数地址
      if (!(hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteBuf, pRemoteBuf, 0, NULL)))
      {
                return FALSE;
      }

      WaitForSingleObject(hThread, INFINITE);

      VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
      VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);

      CloseHandle(hThread);
      CloseHandle(hProcess);

      return TRUE;

}

bubbletea 发表于 2018-5-14 20:52

AIDONG 发表于 2018-5-14 00:11
加载时执行函数 要怎么填 。。。。。。

填你编写的DLL里的导出函数名字来执行你的函数代码,没有就不填了:lol

yangchunlang 发表于 2019-1-8 08:53

个问题就是在执行用户选择的启动函数时我选择让目标进程使用CreateThread来调用dll的导出函数,这样做是否

帅到被排挤 发表于 2018-2-15 00:59

感谢分享源码,研究一下

绝美之城 发表于 2018-2-15 01:00

感谢楼主热心分享。

BY丶显示 发表于 2018-2-15 01:26

{:17_1068:}下载学习一下,谢谢楼主分享。

xiaoyima 发表于 2018-2-15 01:48

明天试试,注入能检测到不

djswzw 发表于 2018-2-15 02:10

谢谢分享 学习学习

peter_king 发表于 2018-2-15 02:12

感谢无私的分享!!

大虾米的爱情 发表于 2018-2-15 02:31

感谢分享源码

xie83544109 发表于 2018-2-15 09:41

{:1_893:}
多谢楼主分享哟

follower 发表于 2018-2-15 09:56

小白来学习了。谢谢代码。
页: [1] 2 3 4 5 6
查看完整版本: 【C语言】编写的DLL注入工具