指令碼編寫 編寫 LLDB 偵錯程式指令碼

2021-10-14 19:42:10 字數 4407 閱讀 6153

lldb 偵錯程式提供對 python 指令碼的支援,可以執行一些自動化的操作,提供工作效率。本文從 helloworld 開始學習如何編寫 lldb 指令碼。

編寫第乙個 lldb 指令碼

下面我們來實際操作編寫 lldb 偵錯程式指令碼。在計算機上建立乙個目錄用於存指令碼檔案,比如我們在 /users/exchen/lldb 這個目錄下操作,新建乙個 helloworld.py 的檔案,輸入下面的**:

def test(debugger, command, result, internal_dict):  """  this is my first lldb script  """  print "hello, world"def __lldb_init_module(debugger, internal_dict):  debugger.handlecommand("command script add -f helloworld.test mycmd")
test 函式是我們準備要匯出的功能,裡面的 4 個引數是固定的,含義如下:

lldb_init_module 函式是在載入指令碼時會執行的,command script add -f 是用於將 python **匯出成自定義的命令,其中 helloworld 是指令碼的名稱,這個要和指令碼的檔名保持一致,test 是函式的名稱,mycmd 是匯出的命令名稱。啟動 lldb 載入這一段指令碼,輸入 mycmd 命令就可以執行 test 函式裡的**。

執行 command script import 將指令碼引入到偵錯程式,輸入 mycmd 命令可以看到列印出 hello, world,證明 test 函式的**得到執行。輸入 help mycmd 可以檢視到相應的提示資訊。

(lldb)command script import /users/exchen/lldb/helloworld.py(lldb)mycmdhello, world(lldb)help mycmdsyntax:  this is my frist lldb script
了解 lldb 配置檔案lldb開啟時會自動載入~/.lldbinit配置檔案,通過這個配置檔案可以設定載入的指令碼路徑等。上面我們編寫了第乙個指令碼,在啟動 lldb 需要手動執行 command script import 才能引入指令碼,如果將 command script import 新增到 ~/.lldbinit 每次啟動 lldb 時就會自動會引入指令碼。預設這個配置檔案是不存在的,我們手動建立乙個,然後新增下面的命令,這樣每次 lldb 啟動都會自動引入 helloworld.py。

command script import /users/exchen/lldb/helloworld.py
除了引入自定義指令碼,lldbinit配置檔案還可以設定命令的別名、命令提示符文字等等,比如我們新增下面的資訊:

setting set prompt "(exchen lldb)"command alias connect process connect connect:
此時再開啟 lldb 會發現命令列的提示文字顯示的是 "(exchen lldb)",輸入connect 命令別名就可以連線程式進行除錯,省去了每次煩瑣地輸入一大串命令。

編寫實際功能指令碼

在上面我們已經編寫了乙個 helloworld 指令碼,通過這個指令碼我們了解到 lldb 指令碼的大概框架,但是這個指令碼並沒有任何實際功能,接下面我們要編寫乙個有實際功能的指令碼,這個指令碼的功能是匯出三個命令,具體**如下:

#!/usr/bin/env python# -*- coding: utf-8 -*-import lldbimport reimport osimport shlexdef goto_main(debugger, command, result, internal_dict):    """    goto main    """    interpreter = lldb.debugger.getcommandinterpreter()    return_object = lldb.sbcommandreturnobject()     # 用來儲存結果    interpreter.handlecommand('dis', return_object)  # 執行dis命令    output = return_object.getoutput(); #獲取反彙編後的結果    br_index = output.rfind('br     x16') #查詢最後的 bx x16    br_index = br_index - 20 #位置減去20    addr_index = output.index('0x', br_index) #查詢0x開頭的字串    br_addr = output[br_index:br_index+11] #找到之後偏移11位    debugger.handlecommand('b ' + br_addr) #新增斷點    debugger.handlecommand('continue') #執行    debugger.handlecommand('si') #單步步入    def get_aslr():       interpreter = lldb.debugger.getcommandinterpreter()    return_object = lldb.sbcommandreturnobject()    interpreter.handlecommand('image list -o -f', return_object) #執行image list -o -f命令    output = return_object.getoutput(); #獲取命令的返回值    match = re.match(r'.+(0x[0-9a-fa-f]+)', output) #正則匹配(0x開頭)    if match:        return match.group(1)    else:        return nonedef aslr(debugger, command, result, internal_dict):    """    get aslr offset    """    aslr = get_aslr()    print >>result, "aslr offset is:", aslrdef breakpoint_address(debugger, command, result, internal_dict):    """    breakpoint aslr address    """    fileoff = shlex.split(command)[0] #獲取輸入的引數    if not fileoff:        print >>result, 'please input the address!'        return    aslr = get_aslr()    if aslr:        #如果找到了aslr偏移,就設定斷點        debugger.handlecommand('br set -a "%s+%s"' % (aslr, fileoff))    else:        print >>result, 'aslr not found!'def __lldb_init_module(debugger, internal_dict):    debugger.handlecommand('command script add -f myscript.aslr aslr')    debugger.handlecommand('command script add -f myscript.goto_main gm')    debugger.handlecommand('command script add -f myscript.breakpoint_address ba')
從上面的** lldb_init_module 可以看出匯出了三個命令,第乙個命令是 aslr,用於獲取 aslr 的位址,原理是呼叫 image list -f -o 命令,從返回的結果中匹配出括號中有 0x 開頭的就是第乙個模組的 aslr 位址。

第二個命令是 gm,用於跳轉到 main 函式的入口點,原理是 lldb 連線啟動的程序時,第一條指令是在 dyld 裡的 _dyld_start 函式,該函式最後一條指令是 br x16,會跳轉到 main 函式,使用 dis 命令檢視 _dyld_start 的反彙編**,從結果中查詢字串 br x16 得到這條指令所在的位址,然後呼叫 b 命令新增斷點,再呼叫 continue 命令讓程式繼續執行,斷點在 br x16 處會觸發,然後再執行 si 單步步入即可達到 main 函式,操作過程如下:

第三個命令是 ba,功能在偵錯程式裡給 ida 裡看到的位址新增斷點,省去了每次從 ida 裡看到位址,需要手動加上 aslr 位址才能和偵錯程式的位址對應上。

如有疑問,

推薦文章:

ios安全論壇軟體源

體驗 iphone 安裝 android 系統

【frida 實戰】遠端過程呼叫(rpc)

XCode偵錯程式LLDB

nslog whatisinsidethisthing nsnumber n 7 實際應該呼叫這個函式 foo if 1 thebooleanatstake int calculatethetrickyvalue help print expression 什麼是 print 命令 print is...

windows bat指令碼編寫

獲取當前所在目錄完全路徑 echo off echo 完全路徑 dp0 pause color設定控制台前景和背景顏色 可同時顯示各種顏色 echo off chcp 437 nul graftabl 936 nul if not exist config.nt copy windir system...

secureCRT指令碼編寫

securecrt支援三種指令碼語言 vbs,js,python。三種指令碼分別以一下三種形式開頭 vbs language vbscript inte ce 1.0 js language jscript inte ce 1.0 python language python inte ce 1.0...