借你一雙慧眼, Frida Native Trace

1、目標

李老闆: 奮飛呀,最近沒怎麼更新呀?python

奮飛: 最近的KPI定的合不合理你內心沒點AC數?我如今內捲到週三就開始寫週報了,否則被新來的就給卷失業了。ios

遙想在古典PC互聯網時代,咱也是 OD、IDA 玩的很溜的。git

一日飲酒樂甚,突發奇想,IDA識別出全部函數,而後導出來給OD,給這些函數下斷點,觸發以後先打日誌,再自動取消斷點。這樣程序運行的流程不就出來了?github

實際跑起來發現,有些函數會頻繁被調用,這樣致使程序容易假死或者崩潰,因此還須要有個方便的過濾措施,過濾掉頻繁調用的函數。安全

pestalker.png

搞出了PEStalker以後,程序的運行流程就無所遁形了。微信

不過期代變了,移動互聯網時代的AppStalker怎麼搞?markdown

2、步驟

frida-trace

大鬍子其實和咱們想到一塊去了,他搞了個frida-trace,能夠一次性監控一堆函數地址。python2.7

而後還能打印出比較漂亮的樹狀圖,不只能夠顯示調用流程,還能顯示調用層次。而且貼心的把不一樣線程調用結果用不一樣的顏色區分開了。函數

如今就缺個數據源,把IDA的識別結果導出來了。oop

trace_natives

github.com/Pr0214/trac… 是的,大佬已經寫好了,咱們又能夠白嫖了。

bp.png

跑起來

  • 下載traceNatives.py 放到ida的 plugins路徑下, 我是mac放在了 /Applications/IDA Pro 7.0/idabin/plugins 目錄

  • Pr0214可能用的是IDA 7.x+ 和 python 3.x 的環境, 在個人 IDA7.0和python2下須要微調下代碼

# search_result = [f"-a '{so_name}!{offset}'" for offset in search_result]
search_result = ["-a '{}!{}'".format(so_name,offset) for offset in search_result]

# with open(save_path, "w", encoding="utf-8")as F:
with open(save_path, "w")as F:

# print(f"frida-trace -UF -O {save_path}")
print("frida-trace -UF -O {} !".format(save_path))

複製代碼
  • IDA打開以前91fans.com.cn/post/ldqsig… 裏的 libxxbitmapkit.so, Edit -> Plugins -> traceNatives 。 而後在分析目錄下面會生成 libxxbitmapkit_16250177xx.txt 這就是frida-trace要導入的數據了

  • 先把某電商程序的App跑起來,而後命令

frida-trace -UF -O /Users/fenfei/Desktop/xx/armeabi-v7a_9_4_6/libjdbitmapkit_1625017920.txt
複製代碼

跑起來便可,請注意 這裏不要出現中文路徑, 可能個人 frida-trace 是在python2.7下跑的,出現中文路徑就會載入失敗。

最後 隨便點個商品詳情頁

rc.png

結果仍是很漂亮的。

加強一下

李老闆: Android的so Trace沒問題,ios的App咋不行?

奮飛: RTFS

Android so的代碼段name是 .text, ios的代碼段name是 __text ,因此咱們在 getSegAddr 里加個判斷

...
if (idc.get_segm_name(seg)).lower() == '.text' or (
        idc.get_segm_name(seg)).lower() == 'text' or (
        idc.get_segm_name(seg)).lower() == '__text' :
...
複製代碼

李老闆: 吾有一函數,第一個入參一定是2,可是不知道是哪一個?能夠Trace出來嗎?

奮飛: ……&*%¥%……)(%$

咱們能夠修改 handlers/libxxbitmapkit.so/xxx.js下面的腳原本完成一些特別的操做,好比在Trace的時候把第一個參數是2的函數挑出來。

onEnter(log, args, state) {
    log('sub_10d71()');
  },

// 改爲

  onEnter(log, args, state) {
	if(args[0] == 2){
		log(" ======== I am here! ========");
	}
    log('sub_10d71()');
  },
複製代碼

固然成千上萬個函數,手工去改,李老闆會笑話我很二的。

def alter(file,old_str,new_str):
    """
    替換文件中的字符串
    :param file:文件名
    :param old_str:就字符串
    :param new_str:新字符串
    :return:
    
    """
    file_data = ""
    with open(file, "r", encoding="utf-8") as f:
        for line in f:
            if old_str in line:
                line = line.replace(old_str,new_str)
            file_data += line
    with open(file,"w",encoding="utf-8") as f:
        f.write(file_data)

def findAllFile(base):
    for root, ds, fs in os.walk(base):
        for f in fs:
            yield f

def main():
    strPath = '/Users/fenfei/Desktop/work/blogCode/trace/__handlers__/libxxbitmapkit.so'
    
    for i in findAllFile(strPath):
        print(i)
        alter(strPath +"/" + i, "onEnter(log, args, state) {", 'onEnter(log, args, state) { if(args[0] == 2){ log(" ======== I am here! ========");}')

複製代碼

人生苦短,快用Python。 收工。

3、總結

和PEStalker的遇到的問題是同樣的,hook的函數太多,App很容易崩潰,必須有個方便的過濾措施,把一些頻繁調用的,不重要的函數過濾掉。 這個還沒想好怎麼搞。

大鬍子還有個玩具叫 github.com/oleavr/art-… 聽說比較牛叉,能夠研究下。

不說了,寫週報去了。

ffshow.png

我平生開車最恨兩種人,一種是隨意加塞的,另外一種是不讓我加塞的。[吃瓜]

TIP: 本文的目的只有一個就是學習更多的逆向技巧和思路,若是有人利用本文技術去進行非法商業獲取利益帶來的法律責任都是操做者本身承擔,和本文以及做者不要緊,本文涉及到的代碼項目能夠去 奮飛的朋友們 知識星球自取,歡迎加入知識星球一塊兒學習探討技術。有問題能夠加我wx: fenfei331 討論下。

關注微信公衆號: 奮飛安全,最新技術乾貨實時推送

相關文章
相關標籤/搜索