我想要实现的是类似以下代码的代码: />
预先感谢。
#1 楼
有一个函数可以执行此操作:build_stkvar_xrefs
,用C ++定义,但通过Python SWIG绑定公开。 IDA会在您需要时动态构建堆栈外部参照。为了使用该功能,需要进行一些设置。您将需要使用一些功能来获得所需的功能:
get_func(ea)
:在func_t
处检索函数的ea
结构get_frame(func_t foo)
:为struct_t
指定的功能框返回
foo
结构/> DecodeInstruction(ea)
:返回代表inst_t
处的指令的ea
get_stkvar(op_t op, sval_t v)
:op
是对指令的引用,v
是操作数中的立即数。通常您只使用op.addr
。它返回一个元组(member_t, val)
。 member_t
是指向堆栈变量的指针,这是我们所需要的。 val
与堆栈var的soff
中的member_t
字段具有相同的值。稍后将对此进行更多介绍。在xreflist_t()
中。xreflist
:您可以使用此方法迭代框架中的所有堆栈变量以检索所有xreflist_entry_t
。如果要为所有堆栈变量构建外部参照,通常会更容易。 > build_stkvar_xrefs(xreflist_t xrefs, func_t func, member_t member)
不是堆栈偏移量。我认为这意味着“结构偏移”,它是框架结构的偏移,因此您可以检索其他信息。您需要此字段来使用其他与堆栈变量相关的功能,例如:SetMemberType,SetMemberName,GetMemberName,DelStrucMember等。做类似的事情:# 0x4012d0 is the function address
# 0x4012dc is an instruction address referencing
# a stack variable. It looks like:
# mov [ebp - 4], ecx
pFunc = get_func(0x4012d0)
pFrame = get_frame(pFunc)
inst = DecodeInstruction(0x4012dc)
op = inst[0] #first operand references stack var
pMember, val = get_stkvar(op, op.addr)
xrefs = xreflist_t()
build_stkvar_xrefs(xrefs, pFunc, pMember)
for xref in xrefs:
print hex(xref.ea) #print xref address
# Contrived member dictionary example.
dictMem = dict()
x = 0
while(x < pFrame.memqty):
dictMem[GetMemberName(pFrame.id, pFrame.get_member(x).soff)] = pFrame.get_member(x)
x = x+1
# given var name you can now use the
# dictionary to grab the member_t to pass
# to build_stkvar_xrefs
pMem = dictMem["var_4"]
xrefs = xreflist_t()
build_stkvar_xrefs(xrefs, pFunc, pMem)
for xref in xrefs:
print hex(xref.ea) #print xrefs to var_4
如果您想了解有关这些功能的更多信息,建议您阅读IDA SDK文档中的以下模块(不分先后顺序): .hpp
struct.hpp
参考:https://www.hex-rays.com/products/ida/support/sdkdoc/files.html
#2 楼
TL; DR:没有简单的API可以实现此目的,代码在答案的结尾或此处。据我所知,没有简单的方法来获取对堆栈结构的引用。似乎调用
idautils.XrefsTo(sid)
可以正常工作,其中sid
是帧ID(使用idc.GetFrame
检索到)应该可以,但是我在尝试中无法获得任何结果。该函数的指令并在遇到堆栈引用操作数时手动计算堆栈中的偏移量。我创建了一个摘要片段来说明这一点,尽管我认为这很不言自明,
首先,我们需要将堆栈偏移量映射到参数,这由
find_stack_members
函数负责,该函数使用上述的idc.GetFrame
API函数获取结构ID用于特定功能的堆栈。然后,它使用idautils.StructMembers
API遍历堆栈变量。函数被输入),稍后在find_stack_members
中将其用于基于当前堆栈增量和操作数立即值计算变量的堆栈偏移量。函数,并跳过除具有定义为引用堆栈的操作数的指令以外的任何指令(请注意,引用堆栈但未被IDA的自动分析或手动定义的参数将不被处理,因此将不视为交叉引用)。如果指令中存在堆栈偏移量操作数,则<space>r
函数将继续使用堆栈的基本偏移量(先前由find_stack_xrefs
检索)来计算其偏移量,即当前堆栈增量由IDA和可以使用API find_stack_xrefs
进行访问,并且立即数来自Operand结构。为方便起见,我也在此处添加了代码:
import idc, idaapi, idautils, ida_xref
def find_stack_members(func_ea):
members = {}
base = None
frame = idc.GetFrame(func_ea)
for frame_member in idautils.StructMembers(frame):
member_offset, member_name, _ = frame_member
members[member_offset] = member_name
if member_name == ' r':
base = member_offset
if not base:
raise ValueError("Failed identifying the stack's base address using the return address hidden stack member")
return members, base
def find_stack_xrefs(func_offset):
func_ea = ida_funcs.get_func(func_offset).startEA
members, stack_base = find_stack_members(func_ea)
for func_item in FuncItems(func_ea):
flags = idc.GetFlags(ea)
stkvar = 0 if idc.isStkvar0(flags) else 1 if idc.isStkvar1(flags) else None
if not stkvar:
continue
ida_ua.decode_insn(func_item)
op = ida_ua.cmd.Operands[stkvar]
stack_offset = op.addr + idc.GetSpd(func_item) + stack_base
member = members[stack_offset]
print("At offset {:x} stack member {} is referenced by operand number {}".format(func_item, member, stkvar))
if __name__ == "__main__":
find_stack_xrefs(idc.ScreenEA())