天天看点

一种隐藏注入DLL的方式,DLL重定位

from 老外的一款war3的外挂,呵呵,就是WUtil啦

不得不PF,居然可以把魔法值像血条那样显示,其实这个愿望以前想过,但真的不知道如何去实现。

不知道是war3本身就有这个功能,还是老外确实那么BT地实现了,这个是后话,正在研究中~~~

对Mh.Pdll分析了下,发现他是注入dll实现的,因为有些功能必须是在DLL中完成,不像以前的全图,只是小小地patch下game.dll。而我发现war3运行后不能发现注入的dll模块(比如processExplorer不能发现),难道他用了我的lpk.dll同样的trick?

非也,lpk.dll隐藏技术是基于peb的,仔细分析了MH.pdll后,发现他注入的思路还有点特别。虽然它也是基于远线程的。

一般远线程dll注入都是把dll路径写入目标进程,然后CreateRemoteThread中把LoadLiberaryA/W作为线程起始地址。因为加载dll用的标准的LoadLiberaryA/W,所以用processExplorer之类会在目标进程发现这个dll。

WUtil的伎俩是:Loader本身会加载Mh.pdll,这样mh.pdll里面IAT已经构建完成——这个不好说的,就是所有需要用的系统API都得到了的意思。其次就是重定位,在目标进程VirtualAllocEx一段跟本DLL相同大小的内存空间,得到其内存起始地址,A。在本进程也VirtualAlloc一段跟本dll相同大小的空间,B。对本进程分配的内存进行重定位操作,注意基址是按A计算,差值是本DLL基址和A之差。重定位当然需要读重定位表,也就是dlll中.reloc那段,相关结构可以参考一些资料,我这里没有去查,不过不难,直接张贴IDA中分析的吧。

dwXXX = v10 - v6;                                             // 差值

do

{

    pBlockRVA = *(_DWORD *)pcurReloc;

    dwBlockSize = *(_DWORD *)(pcurReloc + 4);

    dwCurSize = 8;

    pcurReloc += 8;

    if ( dwBlockSize > 8 )

    {

      do

      {

        itemRVA = *(_WORD *)pcurReloc;

        pcurReloc += 2;

        dwCurSize += 2;

        if ( itemRVA >> 12 )

        {

          if ( itemRVA >> 12 != 3 )

            return 4;

          *(_DWORD *)((char *)modBase + pBlockRVA + (itemRVA & 0xFFF)) += dwXXX;

        }

      }

      while ( dwCurSize < dwBlockSize );

    }

}

while ( dwBlockSize );

最后把B全部WriteProcessMemory到目标进程然后CreateRemoteThread调用某个函数地址就OK拉。一般CreateRemoteThread用了就玩完了,可以设置下Wait下远线程的句柄,函数调用实现后马上就释放内存,什么痕迹也没留下。最后,就是dll导出接口的函数需要自己确定下地址。不知道时候是不是可以过某些杀软的反远线程DLL注入。

哎,表达能力太差,大概只有自己看得懂。

一种隐藏注入DLL的方式,DLL重定位

要点说下:差不多就是模拟系统的LoadLiberary,不过由于loader中已经加载了dll,所以IAT部分不用考虑了,只需解决重定位问题。

相关代码我已经开源:

http://lynnmh.googlecode.com/files/manabars 1.4.zip

FROM:http://hi.baidu.com/lynnux/blog/item/581c69365bb4293a0b55a914.html/cmtid/b4026e1f48d75dfbe1fe0b9d#b4026e1f48d75dfbe1fe0b9d