Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Using IDA Python to statically analyze the function call path

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)06/01 Report--

When mining the firmware loopholes of the device, it will be faced with the situation that there is no source code and can not dynamically track and debug, so static manual analysis is needed. In the process of static manual analysis, it is often necessary to extract the execution paths that need to focus on analysis around the hazard function and user input, in order to effectively narrow the scope of analysis. In this paper, the function of automatically extracting the positive and reverse call relationship of function is realized by using IDA Python script, which can effectively analyze the calling path of dangerous function and the flow direction of user input.

I. description of the problem

Recently, in the study of a certain device, because the device uses MIPS architecture, IDA Pro F5 can not be used, the installed RetDec plug-in is not powerful, and the pseudo code given can not bear to look directly at; there are a lot of code IDA Pro does not recognize, and can not identify library functions; in addition, the firmware is implemented using traditional embedded operating system (non-Linux-like), and there are no advanced concepts such as processes, so it does not solve the problem of dynamic debugging. In this case, it seems that only manual static analysis can be done.

After preliminary analysis, it is found that two problems need to be solved first: one is to forcibly convert the code that can not be recognized by IDA pro into code in order to improve the cross-reference relationship of IDA pro; the other is to extract the function call relationship (forward and reverse) by text, and take the Xrefs graph to and Xrefs graphp from functions of IDA pro, these two functions of IDA pro are not practical for slightly complex files-the displayed graphics can not be seen clearly at all.

Second, cast unparsed code

For the first problem, considering that the instructions of MIPS are all 32bit, we can use IDAPython to traverse the specified address space and convert all the undefined parts into code. The specific code is as follows:

Def define_func (beg, end):

Cur = begif beg%4! = 0: cur = beg + 4-beg%4 # alignment end = end-end%4while cur

< end: if ida_kernwin.user_cancelled(): print('Cancelled') break cur_func = ida_funcs.get_func(cur) print("cur 0xx" % 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 使用时步骤如下: 1、按shift+f2,在Execute script窗口中,Script language选择Python 2、把上述代码粘贴到Please enter script body中 3、点击Run,关闭Execute script窗口。 4、在Output window下方的Python【IDC】按钮右侧,执行define_func(0x8000000,0x80002000),参数仅作示例,根据实际情况调整 三、获取函数调用树 1、正向调用树 正向调用树以指定函数为起点,根据指定递归深度,获取其所有子函数,通常应用于跟踪用户输入数据的流向。实现思路如下:遍历指定函数(由参数指定)代码,如果当前指令为函数调用,则递归,直到达到递归深度或者没有子函数的函数。具体代码如下: import idautils call_chain = [] # 存放正向调用链信息 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)# 获取所有子函数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)# 嵌套结束条件osinteneting_end = Falseif len(xref_froms) == 0: osinteneting_end = Trueelif osintneting == -1: osinteneting_end = Falseelif osintneting == 1: osinteneting_end = Trueif 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# 深度优先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() 使用方法参照"强制转换未解析的代码"一节中的方法,调用gen_call_chain函数即可。gen_call_chain函数的第一个参数是函数名,第二参数是递归的次数限制,如果为-1,则会一直递归到叶子函数(无子函数的函数)。在生成调用树时,每条调用路径对应一行文本,在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. Reverse call tree

The reverse call tree takes the specified function as the starting point and obtains all its parent functions according to the specified recursive depth, which is usually applied to track the path where the dangerous function is called. The idea of implementation is as follows: first get the function that refers to the specified function (specified by the parameter), and then recursively until it reaches the recursive depth or the function that has no parent function. The specific code is as follows:

Import idautils

R_call_chain = [] # store reverse call chain information

Def gen_r_call_chain (func_name, osintneting):

Del r_call_chain [:] f_r_call_out = open ('d:\\ ringing call.csvents,'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) # nesting end condition osinteneting_end = Falseif addr_ref_to = = BADADDR: osinteneting_end = Trueelif osintneting = =-1: osinteneting_end = Falseelif osintneting = = 1: osinteneting_end = Trueif osinteneting_end is True: length = len (r_call_chain) for idx in range (length): fl.write (ringing call _ length [idx-1]) Sys.stdout.write (ringing call1) fl.write ("\ n") sys.stdout.write ('\ r\ n') r_call_chain.pop () return# depth first 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 () # if no function is referenced Pop up the current function break

Use the method to refer to the method in the section "casting unparsed code" and call the gen_r_call_chain function. The first argument to the gen_r_call_chain function is the function name, and the second argument is the number of times of recursion, which, if-1, is recursive all the way to the top-level function (a function without a parent). When the call tree is generated, each call path corresponds to a line of text. The output of the Output window in IDA pro is as follows:

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

IV. Summary

Through the above IDAPython script, you can easily get the call tree of the specified function. The output of the call tree has two places, one is the Output window; of IDA pro and the other is the specified file, the file path is hard-coded, you can modify it by yourself. It is not implemented as a plug-in for the time being. Students who are interested can try it.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report