托管注入深入研究.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
托管注入深入研究.doc

  托管注入深入研究~教育资源库   这是我发表在《黑客防线》2008年12期上的一篇文章,这里是网络上的首发。   附件是我写的一个工具超级间谍(SuperSpy),主要包括一个窗口探测功能,甚至能够探测到VC自带的SPY++所不能探测到的窗口;当然,还包括这里提到的托管注入功能。   程序需运行在.Net2.0以上,如果需要使用注入功能,则需要.Net3.5以上。   超级间谍下载source/850509   网上关于dll注入的文章实在太多,但基本上都是针对ain,只要我们把代码放到DllMain里,就可以被调用了。   现在我们来看托管dll的注入:   用C#或VB.写的dll没有DllMain函数,我们自然想到了功能强大的C++。通常,我们把用C#或VB.写的dll,或者用C++写的,但编译为/clr:pure的dll称为托管dll   而把用C++编写的,但编译为/clr的dll称为混合dll。   混合dll也可以调用托管代码,所以也可以将其称为托管dll,本文所说的托管dll注入,实际上是混合dll的注入。   我们首先想到的是用常规方法来注入混合dll,结果会发现:只要在DllMain函数里调用了托管代码,程序就会崩溃。   也许你还会想到下面的方法:   定义一个类,在其构造函数里调用托管代码,然后在全局域里定义这个类的一个变量,当我们这样做了后会发现,注入后,什么也没有执行。   查阅MSDN,我们找到了答案:   DllMain不能直接或间接地调用托管代码,并且全局变量不会进行初始化。   这样的结果让人非常沮丧!   难道真的就没有办法了吗?   网友CiCi给出了一个解决方案:   写一个混合dll,在其中定义一个导出函数,在这个导出函数里可以调用托管代码。   然后写一个非托管dll(也就是ain函数里调用前面那个混合dll的导出函数。   这个方案能够解决问题,并且我在一段时间里,也一直使用这个方法。但总觉得不完美:必须使用两个dll。   有没有办法用一个dll就解决问题呢?答案是肯定的。   我在一次偶然的机会中,发现了一个现象:   如里用钩子来实现注入,则全局变量会得到初始化。这个发现让我非常困惑:为什么远程线程注入就不会初始化呢?   我考虑这两种方法的区别:钩子注入时,宿主会调用dll中的钩子回调函数。   于是我大胆设想,只要宿主调用了dll中的任意一个函数,全局变量就会得到初始化。   于是我在dll中定义了一个空实现的函数(因为我的目地是迫使全局变量初始化,而不是去执行这个函数)   结果正如我所料,全局变量被初始化了,其构造函数中的托管代码被调用了!   这里其实已经实现了托管代码的注入,当然,还远远不够完善。   这时候,我又觉得全局变量是多余的了:既然我能够使宿主调用dll中的一个特定函数,为什么不直接把托管代码放到这个函数中呢?   我马上进行了测试,也成功了。   之前我是这样实现让宿主调用dll中的一个特定函数的:   在dll被注入之后,我在DllMain函数里将这个特定函数的地址写到共享内存中(这时DllMain里没有调用托管代码,所以可以执行),然后主程序读取共享内存中的值,再通过远程线程迫使宿主调用这个特定函数。   于是我又想,既然可以在主程序中用远程线程迫使宿主调用dll中的特定函数,为什么不直接在dll中用相同的方法去调用呢?   我还没有来得及验证,马上又想到:dll跟宿主是一个进程,即使用远程线程,传给CreateRomoteThread函数的第一个参数也是-1(GetCurrentProcess()返回-1),为什么不直接用近程线程CreateThread呢?   需要着重强调地是:我当时用CreateThread的目的只是让它调用一个特定函数,而不是要去创建一个线程,虽然最终的确创建了一个线程,不过对于此目的,貌似只是一个副作用。   我非常兴奋,马上进行了验证,成功了!   现在我来总结一下托管代码注入的过程:   首先定义一个线程回调函数,可以在其中调用托管代码: Dain里调用CreateThread函数: BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: CreateThread(0,0,ThreadProc,0,0,0); break; case D

文档评论(0)

ggkkppp + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档