Open bb010g opened 1 year ago
Until this is resolved, here's a snippet you can run from the Python console that shouldn't break anything else:
with bv.undoable_transaction():
xfg_dispatch_icall_sym = bv.get_symbols_by_name('__guard_xfg_dispatch_icall_fptr')[0]
xfg_dispatch_icall_addr = xfg_dispatch_icall_sym.address
print('xdg_dispatch_icall_addr', hex(xfg_dispatch_icall_addr))
xfg_dispatch_icall_patch_call = bv.arch.assemble("call qword rax")
xfg_dispatch_icall_patch_jmp = bv.arch.assemble("jmp qword rax")
print('xfg_dispatch_icall_patch', xfg_dispatch_icall_patch)
for ref in bv.get_code_refs(xfg_dispatch_icall_addr):
print('ref', ref)
ref_bv = ref.function.view
ref_llil = ref.llil
if isinstance(ref.llil, LowLevelILCall) and isinstance(ref_dest := ref_llil.dest, LowLevelILLoad) and isinstance(ref_dest.src, LowLevelILConstPtr) and ref_dest.src.constant == xfg_dispatch_icall_addr and (ref_disasm := next(bv.disassembly_tokens(ref_address := ref_llil.address))) is not None and len(xfg_dispatch_icall_patch_call) <= ref_bv.get_instruction_length(ref_address):
ref_disasm = ref_disasm[0]
if len(ref_disasm) == 7 and ref_disasm[0].text.strip() == 'call' and ref_disasm[1].text.strip() == '' and ref_disasm[2].text.strip() == 'qword' and ref_disasm[3].text.strip() == '[' and ref_disasm[4].text.strip() == 'rel' and ref_disasm[5].type == InstructionTextTokenType.CodeRelativeAddressToken and ref_disasm[6].text.strip() == ']':
if ref_bv.convert_to_nop(ref_address):
ref_bv.write(ref_address, xfg_dispatch_icall_patch_call)
print('patched call', hex(ref_address))
elif isinstance(ref.llil, LowLevelILTailcall) and isinstance(ref_dest := ref_llil.dest, LowLevelILLoad) and isinstance(ref_dest.src, LowLevelILConstPtr) and ref_dest.src.constant == xfg_dispatch_icall_addr and (ref_disasm := next(bv.disassembly_tokens(ref_address := ref_llil.address))) is not None and len(xfg_dispatch_icall_patch_jmp) <= ref_bv.get_instruction_length(ref_address):
ref_disasm = ref_disasm[0]
if len(ref_disasm) == 7 and ref_disasm[0].text.strip() == 'jmp' and ref_disasm[1].text.strip() == '' and ref_disasm[2].text.strip() == 'qword' and ref_disasm[3].text.strip() == '[' and ref_disasm[4].text.strip() == 'rel' and ref_disasm[5].type == InstructionTextTokenType.CodeRelativeAddressToken and ref_disasm[6].text.strip() == ']':
if ref_bv.convert_to_nop(ref_address):
ref_bv.write(ref_address, xfg_dispatch_icall_patch_jmp)
print('patched jmp', hex(ref_address))
else:
continue
Version and Platform (required):
Bug Description:
Even with
analysis.experimental.translateWindowsCfgCalls
enabled,call qword [rel __guard_xfg_dispatch_icall_fptr]
lines in the assembly still translate to_guard_xfg_dispatch_icall_nop()
in HLIL after analysis. Manually editing an assembly line tocall rax
, as described in Vector35/binaryninja-api#1760, produces correct analysis.Steps To Reproduce:
Analyze
C:\Windows\System32\windows.storage.dll
from Windows version 10.0.22621 Build 22621 withanalysis.experimental.translateWindowsCfgCalls
enabled and look at the ILs forCAutoDestListParser::_GetDestListStream
. The HLIL should show multiple calls to_guard_xfg_dispatch_icall_nop()
.Expected Behavior:
These Windows CFG calls should be translated to direct calls.
Screenshots:
HLIL:
Disassembly:
Additional Information: