⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 进程注入的三种方法 - benny5609的专栏 - csdnblog.htm

📁 很好的收集,看了以后都不知道说什么了. 都是关于内存调试方面的.十分有用.
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<SCRIPT src="进程注入的三种方法 - benny5609的专栏 - CSDNBlog.files/benny5609.aspx"></SCRIPT>
</DIV><SPAN id=RecentVisitors>
<H3 class=listtitle>最近访客</H3>
<TABLE border=0>
  <TBODY>
  <TR>
    <TD align=middle><IMG 
      onmouseover="try{BlogShowme(event, 'hesinyhe')}catch(ex){}" 
      alt="hesinyhe 的头像" src="进程注入的三种方法 - benny5609的专栏 - CSDNBlog.files/2.jpg" 
      border=0><BR><A title="访问时间: 9/25/2007 1:50:07 PM" 
      href="http://blog.csdn.net/hesinyhe/">hesinyhe</A></TD>
    <TD align=middle><IMG 
      onmouseover="try{BlogShowme(event, 'ilovepd4')}catch(ex){}" 
      alt="ilovepd4 的头像" 
      src="D:\work\tools\vc6.0\调试内存泄漏\进程注入的三种方法 - benny5609的专栏 - CSDNBlog.files\2(1).jpg" 
      border=0><BR><A title="访问时间: 9/20/2007 10:24:02 PM" 
      href="http://blog.csdn.net/ilovepd4/">ilovepd4</A></TD></TR>
  <TR>
    <TD align=middle><IMG 
      onmouseover="try{BlogShowme(event, 'eagleoflove')}catch(ex){}" 
      alt="eagleoflove 的头像" 
      src="D:\work\tools\vc6.0\调试内存泄漏\进程注入的三种方法 - benny5609的专栏 - CSDNBlog.files\2(2).jpg" 
      border=0><BR><A title="访问时间: 9/19/2007 12:52:59 AM" 
      href="http://blog.csdn.net/eagleoflove/">eagleoflove</A></TD>
    <TD align=middle><IMG 
      onmouseover="try{BlogShowme(event, 'liluvu')}catch(ex){}" alt="liluvu 的头像" 
      src="D:\work\tools\vc6.0\调试内存泄漏\进程注入的三种方法 - benny5609的专栏 - CSDNBlog.files\2(3).jpg" 
      border=0><BR><A title="访问时间: 9/18/2007 4:54:35 PM" 
      href="http://blog.csdn.net/liluvu/">liluvu</A></TD></TR></TBODY></TABLE></SPAN>
<H3 class=listtitle>文章</H3>
<UL class=list>
  <LI class=listitem><A 
  href="http://blog.csdn.net/benny5609/category/334908.aspx">Algorithm</A><A 
  href="http://blog.csdn.net/benny5609/category/334908.aspx/rss">(RSS)</A>
  <LI class=listitem><A 
  href="http://blog.csdn.net/benny5609/category/333851.aspx">C/C++</A><A 
  href="http://blog.csdn.net/benny5609/category/333851.aspx/rss">(RSS)</A>
  <LI class=listitem><A 
  href="http://blog.csdn.net/benny5609/category/334688.aspx">DLL</A><A 
  href="http://blog.csdn.net/benny5609/category/334688.aspx/rss">(RSS)</A>
  <LI class=listitem><A 
  href="http://blog.csdn.net/benny5609/category/335554.aspx">ETC.</A><A 
  href="http://blog.csdn.net/benny5609/category/335554.aspx/rss">(RSS)</A>
  <LI class=listitem><A 
  href="http://blog.csdn.net/benny5609/category/333964.aspx">Socket</A><A 
  href="http://blog.csdn.net/benny5609/category/333964.aspx/rss">(RSS)</A>
  <LI class=listitem><A 
  href="http://blog.csdn.net/benny5609/category/335065.aspx">Thread</A><A 
  href="http://blog.csdn.net/benny5609/category/335065.aspx/rss">(RSS)</A>
  <LI class=listitem><A 
  href="http://blog.csdn.net/benny5609/category/337489.aspx">WinCE</A><A 
  href="http://blog.csdn.net/benny5609/category/337489.aspx/rss">(RSS)</A>
  <LI class=listitem><A 
  href="http://blog.csdn.net/benny5609/category/335556.aspx">Windows</A><A 
  href="http://blog.csdn.net/benny5609/category/335556.aspx/rss">(RSS)</A></LI></UL>
<H3 class=listtitle>收藏</H3>
<UL class=list>
  <LI class=listitem><A 
  href="http://blog.csdn.net/benny5609/category/333849.aspx">C++</A></LI></UL>
<H3 class=listtitle>相册</H3><!--category title-->
<UL class=list></UL>
<H3 class=listtitle>杂谈</H3>
<UL class=list></UL>
<H3 class=listtitle>存档</H3>
<UL class=list>
  <LI><A 
  href="http://blog.csdn.net/benny5609/archive/2007/09.aspx">2007年09月(114)</A></LI></UL><SPAN 
id=Anthem_RecentComments_ltlComments__><SPAN id=RecentComments_ltlComments>
<H3 class=listtitle>最近评论</H3>
<UL class=list>
  <LI class=listitem>pluminsnow:<A title="点击查看《回复:VC动态链接库DLL 》" 
  href="http://blog.csdn.net/benny5609/archive/2007/09/13/1784038.aspx#722430">谢谢</A></LI></UL></SPAN></SPAN><BR><BR></DIV>
<DIV id=main>
<DIV class=Tag>
<SCRIPT language=javascript 
src="进程注入的三种方法 - benny5609的专栏 - CSDNBlog.files/urltag.aspx"></SCRIPT>

<DIV style="CLEAR: both"></DIV></DIV><SPAN class=PreAndNext 
id=viewpost.ascx_PreviousAndNextEntriesUp>
<DIV align=center><A 
href="http://blog.csdn.net/benny5609/archive/2007/09/13/1784434.aspx">上一篇:&nbsp;浅谈HOOK技术在VC编程中的应用 
</A>&nbsp;|&nbsp;<A 
href="http://blog.csdn.net/benny5609/archive/2007/09/13/1784051.aspx">下一篇:&nbsp;VC++动态链接库编程之非MFC 
DLL</A></DIV></SPAN><BR>
<SCRIPT>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</SCRIPT>

<DIV class=post>
<DIV class=postTitle>
<SCRIPT src="进程注入的三种方法 - benny5609的专栏 - CSDNBlog.files/vote.js"></SCRIPT>
<A href="http://blog.csdn.net/benny5609/archive/2007/09/13/1784273.aspx"><IMG 
height=13 src="进程注入的三种方法 - benny5609的专栏 - CSDNBlog.files/authorship.gif" 
width=15 border=0>&nbsp;进程注入的三种方法</A>&nbsp;&nbsp;
<SCRIPT src="进程注入的三种方法 - benny5609的专栏 - CSDNBlog.files/count.htm"></SCRIPT>
 </DIV>
<DIV class=postText>一般来说,这个问题有三种可能的解决方案:<BR>  1. 把你的代码放到一个DLL中;然后用 windows 
钩子把它映射到远程进程。<BR>  2. 把你的代码放到一个DLL中;然后用 CreateRemoteThread 和 LoadLibrary 
把它映射到远程进程。<BR>  3. 
不用DLL,直接复制你的代码到远程进程(使用WriteProcessMemory)并且用CreateRemoteThread执行之。在这里有详细的说明:<BR>  <BR>  Ⅰ. 
Windows 钩子<BR>  <BR>  示例程序:HookSpy 和 
HookInjEx<BR>  <BR>  Windows钩子的主要作用就是监视某个线程的消息流动。一般可分为:<BR>  1. 
局部钩子,只监视你自己进程中某个线程的消息流动。<BR>  2. 远程钩子,又可以分为:<BR>  a. 
特定线程的,监视别的进程中某个线程的消息;<BR>  b. 系统级的,监视整个系统中正在运行的所有线程的消息。<BR>  <BR>   
如果被挂钩(监视)的线程属于别的进程(情况2a和2b),你的钩子过程(hook 
procedure)必须放在一个动态连接库(DLL)中。系统把这包含了钩子过程的DLL映射到被挂钩的线程的地址空间。Windows会映射整个DLL而不仅仅是你的钩子过程。这就是为什么windows钩子可以用来向其他线程的地址空间注入代码的原因了。<BR>  <BR>   
在这里我不想深入讨论钩子的问题(请看MSDN中对SetWindowsHookEx的说明),让我再告诉你两个文档中找不到的诀窍,可能会有用:<BR>  1. 
当SetWindowHookEx调用成功后,系统会自动映射这个DLL到被挂钩的线程,但并不是立即映射。因为所有的Windows钩子都是基于消息的,直到一个适当的事件发生后这个DLL才被映射。比如:<BR>  如果你安装了一个监视所有未排队的(nonqueued)的消息的钩子(WH_CALLWNDPROC),只有一个消息发送到被挂钩线程(的某个窗口)后这个DLL才被映射。也就是说,如果在消息发送到被挂钩线程之前调用了UnhookWindowsHookEx那么这个DLL就永远不会被映射到该线程(虽然SetWindowsHookEx调用成功了)。为了强制映射,可以在调用SetWindowsHookEx后立即发送一个适当的消息到那个线程。<BR>  <BR>   
同理,调用UnhookWindowsHookEx之后,只有特定的事件发生后DLL才真正地从被挂钩线程卸载。<BR>  <BR>  2. 
当你安装了钩子后,系统的性能会受到影响(特别是系统级的钩子)。然而如果你只是使用的特定线程的钩子来映射DLL而且不截获如何消息的话,这个缺陷也可以轻易地避免。看一下下面的代码片段:<BR>  BOOL 
APIENTRY DllMain( HANDLE hModule,<BR>   DWORD ul_reason_for_call,<BR>   LPVOID 
lpReserved )<BR>  {<BR>   if( ul_reason_for_call == DLL_PROCESS_ATTACH )<BR>   
{<BR>   //用 LoadLibrary增加引用次数<BR>   char lib_name[MAX_PATH]; <BR>   
::GetModuleFileName( hModule, lib_name, MAX_PATH );<BR>   ::LoadLibrary( 
lib_name );<BR>  <BR>   // 安全卸载钩子<BR>   ::UnhookWindowsHookEx( g_hHook );<BR>   
} <BR>   return TRUE;<BR>  }<BR>  <BR>   
我们来看一下。首先,我们用钩子映射这个DLL到远程线程,然后,在DLL被真正映射进去后,我们立即卸载挂钩(unhook)。一般来说当第一个消息到达被挂钩线程后,这DLL会被卸载,然而我们通过LoadLibrary来增加这个DLL的引用次数,避免了DLL被卸载。<BR>  <BR>   
剩下的问题是:使用完毕后如何卸载这个DLL?UnhookWindowsHookEx不行了,因为我们已经对那个线程取消挂钩(unhook)了。你可以这么做:<BR>   
○在你想要卸载这个DLL之前再安装一个钩子;<BR>   ○发送一个“特殊”的消息到远程线程;<BR>   ○在你的新钩子的钩子过程(hook 
procedure)中截获该消息,调用FreeLibrary 和 
(译者注:对新钩子调用)UnhookwindowsHookEx。<BR>  现在,钩子只在映射DLL到远程进程和从远程进程卸载DLL时使用,对被挂钩线程的性能没有影响。也就是说,我们找到了一种(相比第二部分讨论的LoadLibrary技术)WinNT和Win9x下都可以使用的,不影响目的进程性能的DLL映射机制。<BR>  <BR>   
但是,我们应该在何种情况下使用该技巧呢?通常是在DLL需要在远程进程中驻留较长时间(比如你要子类[subclass]另一个进程中的控件)并且你不想过于干涉目的进程时比较适合使用这种技巧。我在HookSpy中并没有使用它,因为那个DLL只是短暂地注入一段时间――只要能取得密码就足够了。我在另一个例子HookInjEx中演示了这种方法。HookInjEx把一个DLL映射进“explorer.exe”(当然,最后又从其中卸载),子类了其中的开始按钮,更确切地说我是把开始按钮的鼠标左右键点击事件颠倒了一下。<BR>  <BR>   
你可以在本文章的开头部分找到HookSpy和HookInjEx及其源代码的下载包链接。<BR>  <BR>  <BR>  Ⅱ. 
CreateRemoteThread 和 LoadLibrary 技术<BR>  示例程序:LibSpy<BR>   
通常,任何进程都可以通过LoadLibrary动态地加载DLL,但是我们如何强制一个外部进程调用该函数呢?答案是CreateRemoteThread。<BR>  让我们先来看看LoadLibrary和FreeLibrary的函数声明:<BR>  <BR>  HINSTANCE 
LoadLibrary(<BR>   LPCTSTR lpLibFileName // address of filename of library 
module<BR>  );<BR>  <BR>  BOOL FreeLibrary(<BR>   HMODULE hLibModule // handle 
to loaded library module<BR>  );<BR>  <BR>  再和CreateRemoteThread的线程过程(thread 
procedure)ThreadProc比较一下:<BR>  DWORD WINAPI ThreadProc(<BR>   LPVOID lpParameter 
// thread data<BR>  );<BR>  <BR>   你会发现所有的函数都有同样的调用约定(calling 
convention)、都接受一个32位的参数并且返回值类型的大小也一样。也就是说,我们可以把LoadLibrary/FreeLibrary的指针作为参数传递给CrateRemoteThread。<BR>  <BR>   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -