防dll远程注入

dll远程注入

注入步骤:

远程注入是在远程进程中创建远程线程,并调用loadlibrary加载dll。

1、openProcess 打开远程进程

2、VirtualAllocEx 分配远程进程的地址空间中的内存

3、WriteProcessMemory 将dll路径名拷贝到第二步的内存中

4、GetProcAddress 获取LoadLibraryA/LoadLibraryW函数的实地址(kernel32.dll中)

5、CreateRemoteThread 创建远程线程,调用LoadLibrary传递第二部的内存地址

至此,被注入的dll的DllMain函数收到DLL_PROCESS_ATTACH通知。执行完DllMain函数时,远程线程从LoadLibrary返回到BaseThreadStart函数,然后BaseThreadStart调用ExitThread,使远程线程终止运行。

接下来是清理步骤:

6、VirtualFreeEx释放第二步申请的内存

7、GetProcAddress获取FreeLibrary函数的实地址

8、使用CreateRemoteThread创建远程线程,调用FreeLibrary,传递远程DLL的HINSTANCE

防注入:

当外部函数通过CreateRemoteThread创建远程线程,调用远程dll 的DllMain函数之前,会向该进程加载的本地dll发送DLL_THREAD_ATTACH 通知。

因此可以同在本地dll中判断,远程线程写入请求信息的函数是否是LoadLibrary。 线程+LoadLibrary可以判断该dll是远程注入。


BOOL VerifyDLLThread() {
  NTQUERYINFORMATIONTHREAD NtQueryInformationThread =
    (NTQUERYINFORMATIONTHREAD)GetProcAddress(GetModuleHandle(TEXT("ntdll")), "NtQueryInformationThread");
  if (NtQueryInformationThread == NULL) {
    return TRUE;
  }

  HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, GetCurrentThreadId());

  DWORD_PTR dwStaAddr = 0;
  DWORD dwLength = 0;
  MEMORY_BASIC_INFORMATION mbi = { 0 };
  DWORD ret = NtQueryInformationThread(hThread, 9, &dwStaAddr, sizeof(dwStaAddr), &dwLength);
  if (ret != 0) {
    CloseHandle(hThread);
    return TRUE;
  }
  if (s_loadlibrarya_addr == NULL) {
    s_loadlibrarya_addr = (DWORD_PTR)GetProcAddress(LoadLibraryA("kernel32.dll"), "LoadLibraryA");
  }
  if (s_loadlibraryw_addr == NULL) {
    s_loadlibraryw_addr = (DWORD_PTR)GetProcAddress(LoadLibraryA("kernel32.dll"), "LoadLibraryW");
  }
  if (s_loadlibraryexa_addr == NULL) {
    s_loadlibraryexa_addr = (DWORD_PTR)GetProcAddress(LoadLibraryA("kernel32.dll"), "LoadLibraryExA");
  }
  if (s_loadlibraryexw_addr == NULL) {
    s_loadlibraryexw_addr = (DWORD_PTR)GetProcAddress(LoadLibraryA("kernel32.dll"), "LoadLibraryExW");
  }
  if (dwStaAddr == s_loadlibrarya_addr ||
    dwStaAddr == s_loadlibraryw_addr ||
    dwStaAddr == s_loadlibraryexa_addr ||
    dwStaAddr == s_loadlibraryexw_addr) {

    CloseHandle(hThread);
    return FALSE;
  }

  BOOL bVerifyResult = TRUE;
  VirtualQueryEx(GetCurrentProcess(), (LPVOID)dwStaAddr, &mbi, sizeof(mbi));
  if (mbi.State == MEM_COMMIT && mbi.Type != MEM_IMAGE) {
    bVerifyResult = FALSE;
  }
  CloseHandle(hThread);
  return bVerifyResult;
}

当然这样处理最多是提示,有远程注入。想要在这一步FreeLibrary是不行的。因为此时远程dll的DllMain函数还未执行,而TerminateThread也是失败。

最好的解决方案还是循环不断进行dll表的遍历检测,并且维护一个白名单,防止白名单以外的dll文件被加载。

参考:windows核心编程

​​​​​​Remote_DLL_Injection

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值