IDA 脚本 - 按名称获取局部变量

逆向工程 艾达 Python
2021-06-22 00:27:24

在调试期间,我可以在选项卡Locals (Debugger -> Debugger Windows -> Locals(HEXRAYS)) 中看到所有函数的局部变量例如我有一个结构变量

a1    0x891E1160:{pBuf=0x7FC52F20,size=0x100}

我想编写一个 python 脚本来将这些数据转储到一个文件中。我唯一不明白的是如何通过名称获取局部变量的值。它应该是这样的

fdump = open(filename, 'wb')
ptr = get_var('a1')['pBuf']
size = get_var('a1')['size']
buf = idc.GetManyBytes(ptr, size, True)
fdump.write(buf)
fdump.close()

是否有类似get_varidautils、idc 或 idaapi 的函数?

2个回答

这不是完整的解决方案,但可能会有所帮助(假设您有 IDA 6.6+ 版本)

# Display user-defined local variable information
# First defined the visitor class
class dump_lvar_info_t(idaapi.user_lvar_visitor_t):

    def __init__(self):
        idaapi.user_lvar_visitor_t.__init__(self)
        self.displayed_header = False
        return

    def get_info_qty_for_saving(self):
        return 0

    def get_info_for_saving(self, lv):
        return False

    def handle_retrieved_info(self, lv):

        try:
            if not self.displayed_header:
                self.displayed_header = True;
                print "------- User defined local variable information"

            print "Lvar defined at %x" % (lv.ll.defea, )

            if len(str(lv.name)):
                print "  Name: %s" % (str(lv.name), )

            if len(str(lv.type)):
                #~ print_type_to_one_line(buf, sizeof(buf), idati, .c_str());
                print "  Type: %s" % (str(lv.type), )

            if len(str(lv.cmt)):
                print "  Comment: %s" % (str(lv.cmt), )
        except:
            traceback.print_exc()
        return 0

    def handle_retrieved_mapping(self, lm):
        return 0

    def get_info_mapping_for_saving(self):
        return None

# Now iterate over all user definitions
dli = dump_lvar_info_t();
idaapi.restore_user_lvar_settings(entry_ea, dli)

我不记得这段代码究竟来自哪里,可能来自谷歌代码上的 IDAPython 源代码。在这里,您对变量进行了迭代,其余的都应该是可行的。

您可以使用以下函数通过名称(IDA 7+)获取局部变量值:

import idc 
import ida_frame 
import ida_struct 

def get_local_var_value_64(loc_var_name):
    frame = ida_frame.get_frame(idc.here())
    loc_var = ida_struct.get_member_by_name(frame, loc_var_name)
    loc_var_ea = loc_var.soff + idc.GetRegValue("RSP")
    # In case the variable is 32bit, use get_wide_dword() instead:
    loc_var_value = idc.read_dbg_qword(loc_var_ea) 
    return loc_var_value