Let's consider a code snippet:
I can get disassembler variables-
def get_function_vars(function) -> list:
frameId = idc.get_frame_id(function)
if frameId:
varStruct = ida_struct.get_struc(frameId)
if varStruct:
return [mem for mem in varStruct.members]
return []
And instruction references-
def get_variable_refs(function, mem) -> ida_frame.xreflist_t():
xrefs = ida_frame.xreflist_t()
ida_frame.build_stkvar_xrefs(xrefs, function, mem)
return [xref.ea for xref in xrefs]
This gives me instructions referred by say - "var_38" -> 2017BB
and 2017E6
.
I found that I can get hex rays variables by doing something like-
def get_hexrays_vars(ea) -> dict:
hexrays_types = {}
try:
decompiled = ida_hexrays.decompile(ea)
except ida_hexrays.DecompilationFailure:
return {}
if not decompiled:
return {}
for var in decompiled.get_lvars():
print(var.name)
This prints -
a1
a2
a3
v3
v4
v5
v6
Which aligns well with the decompiler view -
Now I want to get the instructions referred by these variables for e.g. one instruction reference for variable "V3" could be 2017D0
as "V3" is the register allocated variable in the register ebp
.
One way to do this in binary ninja is for e.g.
for var in ins.vars_read:
depd = [(func.mlil[i].address, ins.address)
for i in func.mlil.get_var_definitions(var)
if func.mlil[i].address != ins.address]
for var in ins.vars_written:
depd += [(ins.address, func.mlil[i].address)
for i in func.mlil.get_var_uses(var)
if func.mlil[i].address != ins.address]
My end goal is to do some data flow analysis. And I thought this might be possible as decompiler is doing this anyways.