逆向学习litevm篇
乾為天
要不要寫這篇文章我是想了很久的,本來不想再寫;寫文章看似簡單,實際上合理的組織語言寫一篇即有點深度又易懂的文章是很難的;但自己許下的愿就這樣半途而廢有悖天地法則,所謂天圓地方,圓圓滿滿,做事需有頭有尾,乃為規律。
我同樣秉著和上篇文章一樣的態度,盡量用淺顯的語言讓更多的人了解它。
地水師
?????? 想研究無線保鏢中的安全特性,你就不得不弄懂litevm;如avmp、安全對抗、數據收集等,很多核心安全的實現被內置在這個litevm中,sgmain6.3.80對應sgavmp6.3.29中還沒有litevm,由此可以看出litevm和avmp是獨立的,兩者并不存在直接關系。avmp的時間早于litevm,litevm是一個較新版本的安全組件。
?????? 其實義如其名litevm就是一個小的輕量的vm,下面是我給它的一個定義:
?
火天大有
說什么都沒有直接撥開它更具說服力,我們先看看它的sdk中暴露的組件包結構形式:
?
在看看sdk中接口形式:
?
看看sdk中litevm包裝類:
?
我們在看看最接近sgmain的部分:
?
看了這么多可以反過來證實一下我上面說的話了吧,他們預期將來對外提供一系列的安全方法,這些暴露給上層調用的方法是基于dex的方法(至于它將來內部想通過什么方式提供,如dex vmp、 jni反射、或者elf vmp、直接字節碼,這都不重要);不過它可不僅僅提供dex方式的方法,它內部是個虛擬機,它可以提供任何方式的方法,并且保鏢內部調用lvm完全和上層沒有關系,vm執行的是字節碼,vm還可以vmp化。sgavmp的字節碼加載、簽名計算都調用了lvm?;蛟S在不久的將來你將無法在無線保鏢中找到sgavmp的蹤影。
山天大畜
?????? 就我研究的版面目前還未能提供它上層暴露的所有功能,上層也沒有顯著調用lvm的地方,應該是目前版本還未實現那些功能。目前只提供內部調用,在無線保鏢內部其他組件通過lvm command方式調用lvm相關邏輯,這個后面再說。
?????? 想研究lvm首先需要了解它的創建過程,我們大致看一下它的創建過程。
初九:有厲、利己
我們就以從上到下的次序來看它的創建過程,首先通過代理調用創建lvm實例:
?
?
?
九二:輿說輹
在通過doCommand調用底層sgmain的command方法:
?
而0x30d5=12501,對應native層的command是1,0x19,1,這也恰好是創建lvm的地方。
?????? 不過從下層看你會發現更多,你會發現1,0x19,x是一系列和lvm相關的命令:
?
九三:良馬遂,利艱貞。日閑輿衛,利有攸往
創建過程比較復雜,會生成很多的數據結構,如外層litevm,實例lvm_inst、lvm context等、同時初始化這些結構,如計數、索引、實例方法等。
?
注冊lvm方法,這些方法包含系統方法,jni方法,和sgmain內部方法。
?
總之為lvm準備先決條件。
風火家人
初九:閑在家,悔亡
在執行command時,sgmain優先在lvm_command中查找command,找不到在去普通的command中查找。lvm command查找主要存在兩個主鏈; 分別由0x2261、0x2622作為表頭,沒找到返回0, 外層返回0x52。找到后即跳轉到指定的command處。
但lvm字節碼最終的執行入口都是command1,0x19,2; 執行過程是調用lvm獲取lvm_runtime、打開runtime,拷貝外部參數到lvm棧,進入lvm執行字節碼,關閉lvm_runtime開關,得到返回結果。
?
六四:富家,大吉
?????? 真正的程序邏輯影射的是lvm對應的字節碼,字節碼的解釋執行就對應著程序邏輯的前進。lvm執行字節碼工作大致如下:
?
九五:王假有家,勿恤,吉
這里有一個比較有意思的地方,在執行字節碼前先解碼,這個解碼不是解密,而是把外部的字節碼轉換為lvm內部能夠解釋執行的code,我把這種code稱之為lvm_vcode;每條vcode都對應一個handler,vcode的handler可以相同,也可以不同;它還可以是lvm_method。lvm是基于棧的。
如這里列舉一條字節碼的解密過程(字節碼好像也是32位):
?
上九:有孚威如。終吉
?????? 每個vcode對應的handler都很短,handler的主要責任就是執行vcode,vcode中標明了該執行的操作,如完成類似寄存器移動呀、兩個數的累加呀、調用外部函數等。vcode運算都是基于lvm棧進行的,你認為它有寄存器也可以,認為沒有也可以。下面是一個短小的handler的圖示:
?
坎為水
我們以第一條vcode的執行過程為例,字節碼執行的第一步就是找到第一個vcode的handler(第一個handler一般都是保存棧信息):
?
然后更新vm的pc:
?
保存棧信息(第一vcode的handler):
?
進入下一個vcode:
?
雷澤歸妹
就像jvm虛擬機一樣,java字節碼中可以調用java方法(自己實現的)、java庫方法、native方法,lvm也提供了類似的方法調用,調用lvm自實現方法,調用外部方法(庫函數如libc的方法、JNI方法)、調用sgmain方法。大致如下圖:
?
bridge列表,有我單獨標識的:
?
如調用lvm方法入口:
?
根據解析vcode對應調用外部方法的類型調用真正的外部方法:
?
外部方法部分截圖:
?
火水未濟
好,雖然寫的有些急促和不再狀態,但我感覺我應該描述清楚了,最后贈上幾個數據結構(不保證完全準確性):
lvm_method:
?
lvm_vcode:
?
lvm_runtime:
?
好,手工,累壞我了。
本人該項目github地址: https://github.com/ylcangel/crack_litevm
?
該文檔僅僅用來學習交流,用來提高安全門檻,不能用來做惡意事情,否則后果自付!轉載需標明出處,否則發現必究!!!
?
總結
以上是生活随笔為你收集整理的逆向学习litevm篇的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 使用scrapy框架爬取斗鱼图片
- 下一篇: IOS系统通话录音功能的实现方案
