插入DLL和挂接API

每个进程都有它自己的私有地址空间。当使用指针来引用内存时,指针的值将引用你自己进程的地址空间中的一个内存地址,有些情况下,必须打破进程的界限,访问另一个进程的地址空间,这些情况包括:
• 当你想要为另一个进程创建的窗口建立子类时。
• 当你需要调试帮助时(例如,当你需要确定另一个进程正在使用哪个DLL时)。
• 当你想要挂接其他进程时
将DLL插入到另一个进程的地址空间中。一旦DLL进入另一个进程的地址空间,就可以对另一个进程为所欲为。Dll必须进入进程的空间否则就会出现地址访问的越界违规。这就是问什么不能直接用函数 SetWindowLongPtr(hwnd,GWLP_WNDPROC,Mysubclassproc);插入的方法有多种:
1 :注册表插入
windows98不可以用!是在windows初始化的时候加载的!DLL只会映射到使用User 32.dll的进程中。所有基于GUI的应用程序均使用User32.dll,不过大多数基于CUI的应用程序并不使用它。很容易实现但很不安全,系统易崩溃!
2 :用 windows 挂钩插入 DLL
       Microsoft Spy++就是安装了挂钩(wm_getmessage)查看系统各个窗口处理的消息!用下面的函数安装
HHOOK HhOOK = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hinstDll,0);
第一个参数WH_GETMESSAGE用于指定安装挂钩的类型,GetMsgProc用于指明窗口准备处理一个消息时系统应该调用的函数的地址。HinstDll指明包含GetMsgProc函数的DLL,DLL的hinstDll的值用于标识DLL被映射到的进程的地址空间中的虚拟内存地址;最后一个参数0用于指明要挂接的线程,对于一个线程来说,它可以调用SetWindowsHookEx函数,传递系统中的另一个线程的ID。通过为这个参数传递0,就告诉系统说,我们想要挂接系统中的所有GUI线程。现在让我们来看一看将会发生什么情况:
1) 进程B中的一个线程准备将一条消息发送到一个窗口。
2) 系统查看该线程上是否已经安装了WH_GETMESSAGE挂钩。
3) 系统查看包含GetMsgProc函数的DLL是否被映射到进程B的地址空间中。
4) 如果该DLL尚未被映射,系统将强制该DLL映射到进程B的地址空间,并且将进程B中的DLL映像的自动跟踪计数递增1
这个方法允许你在另一个进程的地址空间中不再需要DLL时删除该DLL的映像,方法是调用函数        BOOL UnhookWindowsHookEx(HHOOK hhook);
3: 使用远程线程来插入 D L L
这个DLL插入法要求目标进程中的线程调用LoadLibrary函数来加载必要的DLL。但我们无法控制其它线程,因此要求我们可以在目标进程中创建一个新进程以便控制它。CreateRemoteThread函数可以做到这一点:
HANDLE CreateRemoteThread(
       HANDLE hProcess,                                          //指明拥有新创建线程的进程句柄
       PSECURITY_ATTRIBUTES psa,
       PTHREAD_START_ROUTINE pfnStartAddr,       //线程函数的地址空间
       PVOID pvParam,
       DWORD fdwCreate,
       PDWORD pdwThreadId);
使用实例 :
HANDLE hThread=CreateRemoteThread(hProcessRemote,NULL,0,
LoadLibraryA,”C://mylib.dll”,0,NULL);
CreateRemoteThread 的前提条件是 Kernel32.dll 已经被同事映射到了本地和远程进程的地址空间中,恰好每个程序都要用到 Kernel32.dll
PTHREAD_START_ROUTIME pfnThreadRtn = (PTHREAD_START_ROUTIME)
GetProcAddress(GetModuleHandle(TEXT(“Kernel32”),”LoadLibraryA”);
HANDLE hThread = CreateRemoteThread(hProcessRemote,NULL,0,
pfnThreadRtn,”c://mylib.dll”,0,NULL);
《WINDOWS 核心编程》中的例子
BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile)
{
   BOOL fOk = 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);
 
     // 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's 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)
     hThread = CreateRemoteThread(hProcess, NULL, 0,
         pfnThreadRtn, pszLibFileRemote, 0, NULL);
      if (hThread == NULL) __leave;
 
      // Wait for the remote thread to terminate
      WaitForSingleObject(hThread, INFINITE);
 
      fOk = TRUE; // Everything executed successfully
   }
   __finally { // Now, we can clean everthing 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);
   }
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值