MCPcopy Create free account
hub / github.com/CheckPointSW/Karta / analyzeFunction

Method analyzeFunction

src/disassembler/IDA/ida_analysis_api.py:102–214  ·  view source on GitHub ↗

Analyze a given function, and creates a canonical representation for it. Args: func_ea (int): effective address of the wanted function src_mode (bool): True iff analyzing a self-compiled source file, otherwise analyzing a binary function Return Value:

(self, func_ea, src_mode)

Source from the content-addressed store, hash-verified

100 return function_calls
101
102 def analyzeFunction(self, func_ea, src_mode):
103 """Analyze a given function, and creates a canonical representation for it.
104
105 Args:
106 func_ea (int): effective address of the wanted function
107 src_mode (bool): True iff analyzing a self-compiled source file, otherwise analyzing a binary function
108
109 Return Value:
110 FunctionContext object representing the analyzed function
111 """
112 func = sark.Function(func_ea)
113 if src_mode:
114 context = sourceContext()(self.funcNameInner(func.name), 0) # Index is irrelevant for the source analysis
115 else:
116 context = binaryContext()(func_ea, self.funcNameInner(func.name), 0) # The index will be adjusted later, manually
117
118 func_start = func.start_ea
119 instr_count = 0
120 call_candidates = set()
121 code_hash = md5()
122 for line in func.lines:
123 instr_count += 1
124 # Numeric Constants
125 data_refs = list(line.drefs_from)
126 for oper in [x for x in line.insn.operands if x.type.is_imm]:
127 if oper.imm not in data_refs:
128 context.recordConst(oper.imm)
129 # Data Refs (strings, fptrs)
130 for ref in data_refs:
131 # Check for a string (finds un-analyzed strings too)
132 str_const = self.disas.stringAt(ref)
133 if str_const is not None and len(str_const) >= MIN_STR_SIZE:
134 context.recordString(str_const)
135 continue
136 # Check for an fptr
137 called_func = self.disas.funcAt(ref)
138 if called_func is not None:
139 call_candidates.add(self.disas.funcStart(called_func))
140 elif src_mode:
141 call_candidates.add(ref)
142 continue
143 # Code Refs (calls and unknowns)
144 for cref in line.crefs_from:
145 called_func = self.disas.funcAt(cref)
146 if called_func is None:
147 continue
148 called_func_start = self.disas.funcStart(called_func)
149 if (cref == func_start and line.insn.is_call) or called_func_start != func_start:
150 call_candidates.add(called_func_start)
151 # in binary mode don't let the call_candidates expand too much
152 if not src_mode:
153 [context.recordCall(x) for x in call_candidates]
154 call_candidates = set()
155 # hash the instruction (only in source mode)
156 else:
157 # two cases:
158 # 1. No linker fixups, hash the binary - easy case
159 # 2. Linker fixups, hash the text (includes the symbol name that the linker will use too)

Callers

nothing calls this directly

Calls 15

funcNameInnerMethod · 0.95
sourceContextFunction · 0.85
binaryContextFunction · 0.85
recordConstMethod · 0.80
recordStringMethod · 0.80
recordCallMethod · 0.80
exportsMethod · 0.80
recordUnknownMethod · 0.80
setHashMethod · 0.80
setFrameMethod · 0.80
setInstrCountMethod · 0.80
recordBlockMethod · 0.80

Tested by

no test coverage detected