[普通]DLL注入方法小结

作者(passion) 阅读(1013次) 评论(0) 分类( 软件)

DLL注入到进程中,是当前游戏外挂常使用的一种作弊方式,因此在这里先和大家交流一下DLL的注入方法,在以后的文章中还会和大家讨论一下如何拦截:

DLL的注入方法总结:
1.使用远程线程
2.hook的方式
一、 远程线程注入
1. 想要把自己的DLL注入到目标进程中,需要获取目标进程的句柄,因此,我们就需要提高我们自己注入工具的权限,否则获取不到目标进程的句柄,下面是提高权限的方法:


bool enableDebugPriv() 
{ 
      HANDLE hToken; 
      LUID sedebugnameValue; 
      TOKEN_PRIVILEGES tkp; 
      if (!OpenProcessToken(GetCurrentProcess(), 
          TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 
      { 
         return false; 
     } 
     if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME,  &sedebugnameValue)) 
     { 
         CloseHandle(hToken); 
         return false; 
     } 
     tkp.PrivilegeCount = 1; 
     tkp.Privileges[0].Luid = sedebugnameValue; 
     tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
     if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) 
    { 
         CloseHandle(hToken); 
         return false; 
     } 
     return true; 
}


2. 获取目标进程句柄
OpenProcess(权限类型,是否可被持续,过程ID):功能:返回目标过程句柄
OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);

3. 在目标进程中分配内存,来存储我们要注入的DLL路径:
  VirtualAllocEx(hProcess, NULL, strlen(Path), PAGE_READWRITE);

  //VirtualAllocEx()函数功能:为制订的过程分派虚拟地址
  //参1:要分派的过程句柄
  //参2:要分派的虚拟地址的地位,0默示,主动分派地位
  //参3:分派的大小
  //参4:MEM_COMMIT默示,分派物理内存或者页面内存,并且初始化内存为0
  //参5:存储选项:PAGE_READWRITE默示可以在页面内存中 “读写”
  //返回值:若是分派内存成功,则返回分派内存的地址,若是分派失败则返回NULL,调用GetLastError()查看错误原因

4. 在目标进程中上面分配的内存中,写入DLL的路径:
  4.1 WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID)pszLibFile, strlen(Path), NULL)

  //WriteProcessMemory()函数功能:在制订过程中写入内存
  //参1:写入过程的句柄
  //参2:写入内存的,必须是已经创建的地址,比如上方用VirtualAllocEx()在过程中创建的内存地址
  //参3:写入内存中的数据内容的缓存
  //参4:写入数据大小
  //参5:一个选项,0默示忽视
  //返回值: 非0值默示成功, 返回0则默示写入错误。调用GetLastError()查看错误原因

  有时会读写失败,有可能是因为内存块的保护权限,因此需要修改内存块的保护权限,在写入成功之后,要还原刚才修改的权限
 

   VirtualProtectEx(hProcess, pszLibFileRemote, strlen(Path), PAGE_EXECUTE_READWRITE, &dwOld);
  WriteProcessMemory(hProcess,  pszLibFileRemote, Path, strlen(Path), NULL);
  VirtualProtectEx(hProcess, pszLibFileRemote, strlen(Path), dwOld, &dwOld);
  VirtualFreeEx(hProcess, pszLibFileRemote, strlen(Path), MEM_RELEASE);

5. 获取LoadLibrary()函数地址,因为要用他来动态加载DLL,该函数在kernel32.dll文件中
  PROC AdrMyDllDir=(PROC)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryW");
  //W代表UNICODE版本,说实话,A代表多字节字符集

6. 创建远程线程
CreateRemoteThread(hProcess,NULL, NULL, (LPTHREAD_START_ROUTINE)AdrMyDllDir(LPVOID)LoadString, NULL, NULL);
这里的AdrMyDllDir存放LoadLibraryW ,也就是说把LoadLibraryW当做线程处理惩罚函数,传入的参数bufRemote存放的是目标DLL文件的地址。

二、下面讲解一下如何用hook既钩子注入DLL文件。
所谓hook,既钩子。hook会在应用程序接到消息之前,阻碍应用程序的信息,比如鼠标键盘钩子会阻碍一个应用程序的鼠标键盘信息。要做盗号木马?用WH_KEYBOARD类型的hook
1.我们要跨过程应用钩子,要把hook函数写在DLL文件中。
2.在DLL文件中 设置钩子.
  这里须要调用线程ID,threadId,我们会在面调用DLL的调用端中写入
  hhookGetMsg=::SetWindowsHookEx(WH_GETMESSAGE,GetMessageHookProc,::GetModuleHandle(TEXT("dll.dll")),threadId);
  //参数1:钩子类型
  //参数2:钩子处理函数
  //参数3:钩子地点的模块
  //参数4:钩子要阻碍的线程ID,若是要设置全局钩子,这里给0。
  把这个SetWindowsHookEx()函数写在一个导出函数中:
 

 _declspec(dllexport) void SetHook(DWORD threadId)
  {
     hhookGetMsg=::SetWindowsHookEx(WH_GETMESSAGE,GetMessageHookProc,::GetModuleHandle(TEXT("dll.dll")),threadId);
  }
  SetHook()就是本dll的导出函数


3.在钩子处理函数中写入功能,当钩子截取到WM_NULL消息的,注入DLL文件。因为WM_NULL消息,是个没用的消息,应用程序一般不会收到这个消息,除非我们本身发送一个这个消息,所以我们在注入DLL的时,只要给要注入的应用程序发一个WM_NULL消息,当钩子截取到WM_NULL的时就注入钩子,就可以了。

LRESULT CALLBACK GetMessageHookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
  MSG* pMsg=(MSG*)lParam;
  if(WM_NULL==pMsg->message)
   ::LoadLibraryW(TEXT("D://MyDLL.dll"));
}


编译DLL项目,产生DLL文件。

4.编写调用端,调用钩子
  首先获取窗口句柄
  HWND FindWindow( LPCTSTR lpClassName,LPCTSTR lpWindowName);
  返回窗体句柄。hWnd.
  hWnd=FindWindow(0,要注入dll的窗体的名称(例如:记事本))
  通过hWnd,查找窗体线程ID
  threadId=GetWindowThreadProcessId(hWnd,0);
  有了线程ID了,可以调用钩子了。
  SetHook(threadId);
  这时钩子已经加载到目标线程中了。
  向目标窗体发送WM_NULL消息
  SendMessage(hWnd,WM_NULL,0,0);
  钩子会在目标窗体受到消息前受到WM_NULL消息。因为钩子处理函数中做了判断,当受到WM_NULL消息时,加载DLL文件。所以DLL文件就注入到目标线程中了。

« 上一篇:wifi共享上网(至尊版wifi)
« 下一篇:ASP.NET附加数据库文件的方式,如何发布到IIS7而不导致SQLServer出错
在这里写下您精彩的评论
  • 微信

  • QQ

  • 支付宝

返回首页
返回首页 img
返回顶部~
返回顶部 img