Textobot-史上最另類的文本型GUI事件模型

劉柏江 發佈 2020-01-05T01:46:17+00:00

導讀0x00.交個朋友0x01.常規的GUI事件模型0x02.TB插件的GUI事件模型0x03.配置文件中的target0x04.TB_on_event事件回調0x05.TB_gui顯示與解析0x06.下篇再見0x07.定製服務0x08.關於劉柏江0x00.

導讀

0x00.交個朋友

0x01.常規的GUI事件模型

0x02.TB插件的GUI事件模型

0x03.配置文件中的target

0x04.TB_on_event事件回調

0x05.TB_gui顯示與解析

0x06.下篇再見

0x07.定製服務

0x08.關於劉柏江


0x00.交個朋友

手游從業者模擬器玩家請關注云游模擬器PantaWin;

Android開發者請關注云游模擬器PantaWin/PantaMac/PantaLinux;

iOS越獄開發者請關注曉文框架Textobot;

Android插件開發者請關注飛度框架Fridobot;

移動調試器重度用戶請關注利達調試器LidaDbg;

我們的產品推薦使用git下載和更新,在碼雲搜索geekneo即可。


0x01.常規的GUI事件模型

在有GUI的作業系統上面,系統都定義了一組非常細緻的GUI事件交給應用程式處理。如果是非常高層的SDK封裝,使用更是方便,通過重載函數就可以處理GUI事件了。比如iOS的UIEvent、Qt的QEvent、Windows的PeekMessage等相關接口或者虛函數就可以實時處理GUI事件。下圖是iOS的部分事件接口:


這類作業系統級GUI事件模型幾乎都是針對編譯型開發語言設計的,功能非常完備但是使用複雜。尤其是我們用動態語言封裝出來的運行時,要全部處理這些事件非常費勁同時也是沒有必要的。



0x02.TB插件的GUI事件模型

TB插件事務型流程推薦使用Python編寫,功能型流程推薦使用JavaScript編寫。這就要求我們封裝的GUI事件模型是平台無關的,並且簡單易懂,即便是沒有iOS SDK開發經驗的人也可以使用。如果用Python處理起來異常困難的話就失去了我們標榜的高效率開發iOS越獄插件的意義了。

編譯型語言比如C/C++/Objective-C擅長處理二進位數據結構,解釋型語言比如Python非常擅長處理文本型數據結構。從這個角度出發,我們就分配了一個關鍵任務給注入庫textobot.dylib-記錄介面文本以及坐標,然後生成GUI文本事件匯報給調度器。

這樣一來,TB插件就能感知當前介面顯示的文本內容,那麼結合文本分析,我們就可以編寫事務處理邏輯了。看到這裡,我想讀者也能明白Textobot名字的由來了-Text Robot。此處Text即指介面文本,也指TB插件形態,用文本代碼感知動態的介面內容。我們把收到的文本事件列印出來,如下:

只要觸發了GUI事件,textobot.dylib就會把當前最新的文本狀態匯報給調度器,從而交給TB插件處理。然後再加上一些點擊、滑動操作,那麼就源源不斷的形成了事件流。這就是Textobot插件體系的文本型GUI事件模型。職業測試專家不知道用不用得上,用Python這種全民程式語言寫帶複雜邏輯的自動化測試用例,如果還有更高級的方式請不要笑話我,畢竟我並不懂專業測試的玩法。

然後在Frida的加持下,TB插件是如此的強大以至於還有很多其他高級的玩法,但是切記:



0x03.配置文件中的target

打開TBROOT/Template/textobot.json模版項目配置文件,有一個關鍵欄位target如下:

打開TBROOT/Sample/TextCapture/textobot.json例子項目配置文件,同樣注意關鍵欄位target如下:


如前文所述,textobot.dylib會源源不斷的把文本型GUI事件匯報給調度器,進而交給TB插件處理。由於當前的介面可能來自不同的App,所以我們需要指明希望處理哪些App的文本型GUI事件,這就是target欄位的作用,它是一個BundleID數組,字符*代表處理所有的文本型GUI事件。



0x04.TB_on_event事件回調

def TB_on_event(dictarg)

插件腳本選擇性提供的事件回調函數,沒有則不會收到文本型GUI事件。dictarg是框架提供的Key-Value字符串參數,當插件處於運行狀態,則會在如下情況被調用:

  1. 彈出了對話框,對應的event為dlgtexts;
  2. 每隔10s或者UI事件被觸發了,對應的event為texts;

dictarg中還包含target,值為發送UI事件的App標誌符,剩下的就是文本控制項坐標和文本內容,類似於:

'89,98' : 'UILabel.iCloud'

前者是文本控制項『中心坐標』,後者是控制項『類名.文本』,中心坐標可以通過TB_touch_pair進行點擊操作。

模版代碼如下:

def TB_on_event(dictarg):
    target = dictarg['target']
    event = dictarg['event']
    if event == 'texts':
        pass
    elif event == 'dlgtexts':
        pass
    return {}


0x05.TB_gui顯示與解析

上一篇《用交互式TB插件在iPhone上砸殼更美滋滋》當中我們貼出了它GUI處理的部分,在這裡我們詳細解釋它的原理。先看TB_gui的說明。

def TB_gui(controls)

controls:GUI控制項描述文本;

通用格式為:控制項類型---提示標題[---初始參數]

當前支持的控制項如下:

  • label :文本字符串,控制項類型---提示標題---對齊方式包括空、center、right;
  • edit :多行編輯框,控制項類型---提示標題---初始文本;
  • combo :單選列表框,控制項類型---提示標題---初始列表,以逗號分隔;
  • spin :數據調節器,控制項類型---提示標題---初始參數,格式為「起始值,步長,終止值」;
  • padding :多加一些空白

TBMachoDumper選擇目標App的GUI顯示代碼:

def dump_selector():
    TB_gui(
'''
label---MachO Dumper---center
label---GeekNeo/AloneMonkey---center
label---%s---center
padding
combo---%s---%s
'''
 % (pkg_version, flag_apps, running_apps(idev)))

這樣調用就會藉助Textobot管理器顯示描述的GUI介面,然後用戶選擇完了點擊OK的話,Textobot管理器就會將結果格式化為一個方便解析的文本並彈出Textobot Submitting對話框,這樣再通過文本型GUI事件發送給TBMachoDumper插件的處理邏輯,我們就可以解析用戶到底選擇了哪一個App。

flag_tbsubmit = 'Textobot Submitting'
flag_sep = '---'
flag_apps = 'Applications'
#...
# parse result from TB commit dialog
def proc_event_texts(pts, txts):
    # 查找 Textobot Submitting 結果對話框標誌
    if contain_text(pts, txts, flag_tbsubmit):
        # 自動點擊OK關閉對話框
        TB_touch_pair(contain_text(pts, txts, '.OK'))
        time.sleep(1)
        for i in range(0, len(txts)):
            # 查找我們顯示GUI時設置的App列表標準 Applications
            if txts[i].find(flag_apps) > 0:
                # 將結果拆分成一行一行的結構
                lines = txts[i].split('\n')
                result = ''
                for l in lines:
                    # 將一行拆分成單一元素 --- 是Textobot定義的行分隔符
                    items = l.split(flag_sep)
                    if len(items) != 3:
                        continue
                    # 此處是 Applications
                    key = items[1]
                    # 此處是 pid-bid 鍵值對
                    value = items[2]
                    print('Dumping %s ...' % (value))
                    appinfo = value.split('\t')
                    # kill it before dump
                    if appinfo[0] != '-':
                        run_cmd('kill -9 ' + appinfo[0])
                        time.sleep(1)
                    dump_main(appinfo[1])
                break

# handler for event
def TB_on_event(dictarg):
    event = dictarg['event']
    if event == 'dlgtexts':
        proc_event_texts(dictarg.keys(), dictarg.values())
    return {}


0x06.下篇再見

到此,我們詳細解釋了Textobot定義的文本型GUI事件模型、TB_on_event事件處理回調、TB_gui的顯示與解析。可以看出,我們不需要iOS SDK的任何幫助就可以實現一個可交互式的TB插件,但是如果要寫出有意義的TB插件,iOS相關的知識還是必不可少的。下一篇文章,我們詳細介紹TB插件項目的其他內容,比如TB_main插件事件、當前導出的系統級API。


0x07.定製服務

我們團隊雖小,但個個都是一頂三的技術精英,因此技術能力是嚴重過剩的。所以如果您有任何關於iOS/Android底層的疑難雜症、雲遊模擬器掛機/二次開發、曉文/飛度插件定製等方面的個性化需求,歡迎通過私信聯繫我們。


0x08.關於劉柏江

8年移動網際網路從業經驗、精通iOS/Android底層開發/攻防對抗、GikDbg/KiwiVM原作者、幾維安全聯合創始人/股東。

我的自媒體帳號將圍繞PantaEmu、Textobot、Fridobot、LidaDbg為用戶朋友們傳道、授業、解惑。歡迎各位朋友關注、點讚、轉發,謝謝大家。

關鍵字: