欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

利用IDAPython靜態(tài)分析函數(shù)調(diào)用路徑-創(chuàng)新互聯(lián)

在挖掘設(shè)備的固件漏洞時(shí),會(huì)面臨沒有源代碼、無法動(dòng)態(tài)跟蹤調(diào)試的情況,此時(shí)就需要進(jìn)行靜態(tài)的人工分析。在靜態(tài)人工分析過程中,往往需要圍繞危險(xiǎn)函數(shù)、用戶輸入提取需要重點(diǎn)分析的執(zhí)行路徑,以有效縮小分析范圍。本文利用IDA Python腳本,實(shí)現(xiàn)了自動(dòng)提取函數(shù)正、反向調(diào)用關(guān)系的功能,可有效輔助分析危險(xiǎn)函數(shù)調(diào)用路徑,用戶輸入流向等。

創(chuàng)新互聯(lián)建站是專業(yè)的網(wǎng)站建設(shè)公司,提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)站設(shè)計(jì)等網(wǎng)站開發(fā)一體化解決方案;包括H5響應(yīng)式網(wǎng)站,小程序設(shè)計(jì),網(wǎng)站定制,企業(yè)網(wǎng)站建設(shè),商城網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),建網(wǎng)站,PHP網(wǎng)站建設(shè),軟件開發(fā),軟文發(fā)布平臺(tái),網(wǎng)站營銷。歡迎做網(wǎng)站的企業(yè)前來合作洽談,創(chuàng)新互聯(lián)建站將竭誠為您服務(wù)!

一、問題描述
近期在研究某款設(shè)備,由于該設(shè)備使用MIPS架構(gòu),IDA Pro的F5無法使用,安裝的RetDec插件也不給力,給出的偽代碼不忍直視;還有不少代碼IDA Pro沒有識(shí)別出來,且無法識(shí)別庫函數(shù);此外,固件使用傳統(tǒng)的嵌入式操作系統(tǒng)(非類Linux)實(shí)現(xiàn),不存在進(jìn)程等高級(jí)概念,因此也沒有解決動(dòng)態(tài)調(diào)試的問題。在這種情況下,似乎只能人工靜態(tài)分析了。

進(jìn)行初步分析之后,發(fā)現(xiàn)需要先解決兩個(gè)問題:一是將IDA pro無法識(shí)別的代碼強(qiáng)制轉(zhuǎn)換成代碼,以完善IDA pro的交叉引用關(guān)系;二是以文本方式提取函數(shù)調(diào)用關(guān)系(正向、反向),取IDA pro的Xrefs graph to和Xrefs graphp from功能,IDA pro的這兩個(gè)功能對(duì)稍微復(fù)雜一定的文件根本不存在實(shí)用性——顯示的圖形根本看不清。

二、強(qiáng)制轉(zhuǎn)換未解析的代碼
針對(duì)第一個(gè)問題,考慮到MIPS的指令均為32bit,可利用IDAPython遍歷指定的地址空間,把未定義的部分全部轉(zhuǎn)換成代碼。具體的代碼如下:

def define_func(beg, end):

cur = beg

if beg%4 != 0:

    cur = beg + 4 - beg%4 # 對(duì)齊

end = end - end%4

while cur < end:

    if ida_kernwin.user_cancelled():

        print('Cancelled')

        break

    cur_func = ida_funcs.get_func(cur)

    print("cur 0x%08x" % cur)

    if cur_func is None:

        if ida_funcs.add_func(cur):

            cur = ida_funcs.get_func(cur).endEA

        else:

            cur = cur + 4

    else:

        cur = cur_func.endEA

使用時(shí)步驟如下:

1、按shift+f2,在Execute script窗口中,Script language選擇Python

2、把上述代碼粘貼到Please enter script body中

3、點(diǎn)擊Run,關(guān)閉Execute script窗口。

4、在Output window下方的Python【IDC】按鈕右側(cè),執(zhí)行define_func(0x8000000,0x80002000),參數(shù)僅作示例,根據(jù)實(shí)際情況調(diào)整

三、獲取函數(shù)調(diào)用樹
1、正向調(diào)用樹
正向調(diào)用樹以指定函數(shù)為起點(diǎn),根據(jù)指定遞歸深度,獲取其所有子函數(shù),通常應(yīng)用于跟蹤用戶輸入數(shù)據(jù)的流向。實(shí)現(xiàn)思路如下:遍歷指定函數(shù)(由參數(shù)指定)代碼,如果當(dāng)前指令為函數(shù)調(diào)用,則遞歸,直到達(dá)到遞歸深度或者沒有子函數(shù)的函數(shù)。具體代碼如下:

import idautils

call_chain = [] # 存放正向調(diào)用鏈信息

def gen_call_chain(func_name, osintneting):

del call_chain[:]

f_call_out = open('d:\\call.csv', 'w')

get_my_callee(func_name, osintneting, f_call_out)

f_call_out.close()

def get_my_callee(func_name, osintneting, fl):

#print('call %s %d' % (func_name, osintneting))

if ida_kernwin.user_cancelled():

    print('Cancelled')

    fl.close()

    exit()

str = '{0}\t'.format(func_name)

call_chain.append(str)

addr = get_name_ea(0, func_name)

# 獲取所有子函數(shù)

dism_addr = list(idautils.FuncItems(addr))

xref_froms = []

for ea in dism_addr:

    if ida_idp.is_call_insn(ea) is False:

        continue

    else:

        callee = get_first_fcref_from(ea)

        if callee != addr:

            xref_froms.append(callee)

xref_froms = set(xref_froms)

# 嵌套結(jié)束條件

osinteneting_end = False

if len(xref_froms) == 0:

    osinteneting_end = True

elif osintneting == -1:

    osinteneting_end = False

elif osintneting == 1:

    osinteneting_end = True

if osinteneting_end is True:

    for callee in call_chain:

        sys.stdout.write(callee)

        fl.write(callee)

    sys.stdout.write('\r\n')

    fl.write('\r\n')

    call_chain.pop()

    return

# 深度優(yōu)先

for xref_from in xref_froms:

    callee_name = get_func_name(xref_from)

    if osintneting == -1:

        get_my_callee(callee_name, -1, fl)

    else:

        get_my_callee(callee_name, osintneting - 1, fl)

call_chain.pop()

使用方法參照“強(qiáng)制轉(zhuǎn)換未解析的代碼”一節(jié)中的方法,調(diào)用gen_call_chain函數(shù)即可。gen_call_chain函數(shù)的第一個(gè)參數(shù)是函數(shù)名,第二參數(shù)是遞歸的次數(shù)限制,如果為-1,則會(huì)一直遞歸到葉子函數(shù)(無子函數(shù)的函數(shù))。在生成調(diào)用樹時(shí),每條調(diào)用路徑對(duì)應(yīng)一行文本,在IDA pro的Output window的輸出如下

Python>gen_call_chain('start', 5)

start sub_4010E0 sub_400DD0 sub_401B40 sub_401B80

start sub_4010E0 sub_400DD0 sub_401B40 sub_401A00

start sub_4010E0 sub_400DD0 sub_444750 sub_472EB0

start sub_4010E0 sub_400DD0 sub_444750 sub_43F8C0

start sub_4010E0 sub_400DD0 sub_444750 sub_472FE0

start sub_4010E0 sub_400DD0 sub_444750 sub_43F920

start sub_4010E0 sub_400DD0 sub_40EFF0 sub_40EE10

2、反向調(diào)用樹
反向調(diào)用樹以指定函數(shù)為起點(diǎn),根據(jù)指定遞歸深度,獲取其所有父函數(shù),通常應(yīng)用于跟蹤危險(xiǎn)函數(shù)被調(diào)用的路徑。實(shí)現(xiàn)思路如下:先獲取引用指定函數(shù)(由參數(shù)指定)的函數(shù),然后依次遞歸,直到達(dá)到遞歸深度或者沒有父函數(shù)的函數(shù)。具體代碼如下:

import idautils

r_call_chain = [] # 存放反向調(diào)用鏈信息

def gen_r_call_chain(func_name, osintneting):

del r_call_chain[:]

f_r_call_out = open('d:\\r_call.csv', 'w')

get_my_caller(func_name, osintneting, f_r_call_out)

f_r_call_out.close()

def get_my_caller(func_name, osintneting, fl):

if ida_kernwin.user_cancelled():

    print('Cancelled')

    fl.close()

    exit()

str = '{0}\t'.format(func_name)

r_call_chain.append(str)

addr = get_name_ea(0, func_name)

addr_ref_to = get_first_fcref_to(addr)

# 嵌套結(jié)束條件 

osinteneting_end = False

if addr_ref_to == BADADDR:

    osinteneting_end = True

elif osintneting == -1:

    osinteneting_end = False

elif osintneting == 1:

    osinteneting_end = True

if osinteneting_end is True:

    length = len(r_call_chain)

    for idx in range(length):

        fl.write(r_call_chain[length - idx - 1])

        sys.stdout.write(r_call_chain[length - idx - 1])

    fl.write("\n")

    sys.stdout.write('\r\n')

    r_call_chain.pop()

    return

# 深度優(yōu)先

while (addr_ref_to != BADADDR) and (addr_ref_to != addr):

    parent_func_name = get_func_name(addr_ref_to)

    get_my_caller(parent_func_name, osintneting - 1, fl)

    addr_ref_to = get_next_fcref_to(addr, addr_ref_to)

    if addr_ref_to == BADADDR:

        r_call_chain.pop() # 如果沒有引用函數(shù),彈出當(dāng)前函數(shù)

        break

使用方法參照“強(qiáng)制轉(zhuǎn)換未解析的代碼”一節(jié)中的方法,調(diào)用gen_r_call_chain函數(shù)即可。gen_r_call_chain函數(shù)的第一個(gè)參數(shù)是函數(shù)名,第二參數(shù)是遞歸的次數(shù)限制,如果為-1,則會(huì)一直遞歸到頂層函數(shù)(無父函數(shù)的函數(shù))。在生成調(diào)用樹時(shí),每條調(diào)用路徑對(duì)應(yīng)一行文本,在IDA pro的Output window的輸出如下:

Python>gen_r_call_chain('sub_4432E0', 5)

start sub_4010E0 sub_400DD0 sub_4432E0

sub_47D3F0 sub_4767D0 sub_474770 sub_4432E0

sub_496370 sub_4767D0 sub_474770 sub_4432E0

sub_480930 sub_47D020 sub_4432E0

sub_48C450 sub_47D020 sub_4432E0

sub_499C60 sub_47D020 sub_4432E0

sub_480930 sub_47D020 sub_4432E0

sub_48C450 sub_47D020 sub_4432E0

四、小結(jié)
通過上述IDAPython腳本,可方便獲取指定函數(shù)的調(diào)用樹。調(diào)用樹的輸出有兩處,一處IDA pro的Output window;另一處是指定的文件,文件路徑是硬編碼的,各位看官可自行修改。暫時(shí)沒有以插件方式實(shí)現(xiàn),有興趣的同學(xué)可以嘗試下。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

標(biāo)題名稱:利用IDAPython靜態(tài)分析函數(shù)調(diào)用路徑-創(chuàng)新互聯(lián)
URL鏈接:http://chinadenli.net/article44/dgpghe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號(hào)定制開發(fā)、網(wǎng)站營銷App設(shè)計(jì)、軟件開發(fā)網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)