|
13 | 13 | BinaryView,
|
14 | 14 | ILRegister,
|
15 | 15 | SymbolType,
|
16 |
| - ILException, |
17 | 16 | BinaryReader,
|
18 | 17 | RegisterValueType,
|
19 | 18 | LowLevelILOperation,
|
|
24 | 23 | from capa.features.insn import API, MAX_STRUCTURE_SIZE, Number, Offset, Mnemonic, OperandNumber, OperandOffset
|
25 | 24 | from capa.features.common import MAX_BYTES_FEATURE_SIZE, Bytes, String, Feature, Characteristic
|
26 | 25 | from capa.features.address import Address, AbsoluteVirtualAddress
|
27 |
| -from capa.features.extractors.binja.helpers import DisassemblyInstruction, visit_llil_exprs |
| 26 | +from capa.features.extractors.binja.helpers import DisassemblyInstruction, visit_llil_exprs, get_llil_instr_at_addr |
28 | 27 | from capa.features.extractors.base_extractor import BBHandle, InsnHandle, FunctionHandle
|
29 | 28 |
|
30 | 29 | # security cookie checks may perform non-zeroing XORs, these are expected within a certain
|
|
37 | 36 | # 2. The function must only make one call/jump to another address
|
38 | 37 | # If the function being checked is a stub function, returns the target address. Otherwise, return None.
|
39 | 38 | def is_stub_function(bv: BinaryView, addr: int) -> Optional[int]:
|
40 |
| - funcs = bv.get_functions_at(addr) |
41 |
| - for func in funcs: |
42 |
| - if len(func.basic_blocks) != 1: |
43 |
| - continue |
44 |
| - |
45 |
| - call_count = 0 |
46 |
| - call_target = None |
47 |
| - try: |
48 |
| - llil = func.llil |
49 |
| - except ILException: |
50 |
| - return None |
| 39 | + llil = get_llil_instr_at_addr(bv, addr) |
| 40 | + if llil is None or llil.operation not in [ |
| 41 | + LowLevelILOperation.LLIL_CALL, |
| 42 | + LowLevelILOperation.LLIL_CALL_STACK_ADJUST, |
| 43 | + LowLevelILOperation.LLIL_JUMP, |
| 44 | + LowLevelILOperation.LLIL_TAILCALL, |
| 45 | + ]: |
| 46 | + return None |
51 | 47 |
|
52 |
| - if llil is None: |
53 |
| - continue |
| 48 | + if llil.dest.value.type not in [ |
| 49 | + RegisterValueType.ImportedAddressValue, |
| 50 | + RegisterValueType.ConstantValue, |
| 51 | + RegisterValueType.ConstantPointerValue, |
| 52 | + ]: |
| 53 | + return None |
54 | 54 |
|
55 |
| - for il in llil.instructions: |
56 |
| - if il.operation in [ |
57 |
| - LowLevelILOperation.LLIL_CALL, |
58 |
| - LowLevelILOperation.LLIL_CALL_STACK_ADJUST, |
59 |
| - LowLevelILOperation.LLIL_JUMP, |
60 |
| - LowLevelILOperation.LLIL_TAILCALL, |
61 |
| - ]: |
62 |
| - call_count += 1 |
63 |
| - if il.dest.value.type in [ |
64 |
| - RegisterValueType.ImportedAddressValue, |
65 |
| - RegisterValueType.ConstantValue, |
66 |
| - RegisterValueType.ConstantPointerValue, |
67 |
| - ]: |
68 |
| - call_target = il.dest.value.value |
69 |
| - |
70 |
| - if call_count == 1 and call_target is not None: |
71 |
| - return call_target |
72 |
| - |
73 |
| - return None |
| 55 | + return llil.dest.value.value |
74 | 56 |
|
75 | 57 |
|
76 | 58 | def extract_insn_api_features(fh: FunctionHandle, bbh: BBHandle, ih: InsnHandle) -> Iterator[tuple[Feature, Address]]:
|
|
0 commit comments