天天看點

一種隐藏注入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