360加固之libjiagu.so dump修復

一、elfheader修復

dump出來的內存如下圖所示,elf header結構有缺失

下面是正常elf頭的對比圖

下面是010editor對正常elf header的解析

    由上圖可知,dump出來的elf header除了e_phoff、e_phentsize、e_phum三個值,其它都爲0。

   不過這裏缺失的,除了e_shoff, e_shnum, e_shtrndx三個是變量,其它都是固定值。而實際上e_shoff, e_shnum, e_shtrndx這三個值在dlopen時並沒有用到,全部填0,也可以正常使用。

   那麼這裏elf header把固定值填上,e_shoff, e_shnum, e_shtrndx三個值留空,elf header就修復好了。

   elf header修復完成後的dump就跟一個so經過dlopen後,dump出來的內存是一樣的了。但是這樣的dump是不能直接加載的,很多情況下用IDA分析也會缺失導入函數的解析。

 

二、so及其dump差異分析

    爲了修復這個dump出來的so,我們寫一個so來做個測試。

將測試so加載後,dump出來進行加載前後的對比


    後面一大塊數據不一樣。首先有個問題就是內存裏的對齊跟文件是有差異的。

    看下elf Loadable Segment


    可以發現第二個Loadable Segmentp_offsetp_vadder是一樣的,相差了0x1000,dump出來的內存在這個位置會比file0x1000

 

   Dynamic Segment同樣存在這樣的差異。

三、so dump修復

   由於dump的數據是跟內存加載後是一致的,把上面兩個Segment裏的p_offset都改成跟p_vaddr一樣的值。

   完成這樣的修改後,IDA就可以正常解析導入函數了,因爲IDA對導入函數的解析依賴於Dynamic Segment裏的數據。

   如果要能讓dump能正常被dlopen起來,還需要繼續對重定位數據進行修復

下面是DynamicSegmentrel對應的數據


可知rel對應的數據開始於0x6aa8,大小爲0xf30


0x6aa8指向的elf32_rel結構體數組

typedef structelf32_rel {
       Elf32_Addr   r_offset;
       Elf32_Word  r_info;
} Elf32_Rel;

r_offset指向的地址會被重定位

下圖是原始so的數據:


下圖是dump內經過重定位的數據:


    可以發現dump裏的數據被加上了so的加載基址,修復的時候,減去基址就可以恢復原始數據

    除了rel還有plt_rel需要修復,修復方法跟rel一樣

    由於relplt_rel需要修復的數據量比較大,手動修復不太現實,需要編寫個工具來完成這樣的修復。可以把dlopen裏的源碼扣出來做一些修改完成這樣的操作。

    下面是兩張IDA分析的截圖:




    修復後的so,跟普通so已經沒什麼區別了,導入函數和字符串暴露無遺。居然沒有對字符串做加密,這樣給分析者帶來很大方便,對於加固核心so來說有點太依賴so加固了。

  (創建了一個Android逆向分析羣,歡迎有興趣的同學加入,羣號碼:376745720)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章