使用 IDA python 获取全局变量列表

逆向工程 艾达 蟒蛇
2021-07-02 07:07:19

我正在尝试使用 IDA python 来获取 .data 部分中所有变量的列表,因为我想从 IDA 中提取对每个全局变量的交叉引用列表。是否可以使用 IDA python 来做到这一点?

2个回答

虽然Sark是一个很好的库/工具,但如果您只是在寻找一个小的实用程序脚本,您可能希望避免安装它的开销。无论如何,我建议您尝试一下。

以下代码将在不使用任何第三方代码的情况下完成此操作:

# get segment start and end EA by name
idata_seg_selector = idc.SegByName('.data')
idata_seg_startea = idc.SegByBase(idata_seg_selector)
idata_seg_endea = idc.SegEnd(idata_seg_startea)

# iterate EAs in range
for seg_ea in range(idata_seg_startea, idata_seg_endea):
  # iretate xrefs to specific ea
  for xref in idautils.xrefsto(ea):
    print("Found a cross reference {}: from {} to '.idata' variable {}".format(xref, xref.frm, seg_ea))

问题:

  • 使用此代码,您将看到所有交叉引用,而不仅仅是那些带有名称的交叉引用,尽管如果您愿意那样添加它是非常微不足道的。
  • 正如@ws提到的,你只能看到位于变量.data部分作为OP的要求,你应该考虑包括其他数据相关的部分(如.idata.rodata.bss,等)。或者,您可能需要考虑使用idc.isData(idc.GetFlags(ea))过滤掉部分或所有部分中的非数据偏移量。

有几种方法可以做到这一点。我使用Sark是因为它使编码更容易一些。

这里的第一个选项是迭代 IDA 的名称列表,并按地址进行过滤。第二个是检查一个段中的所有行,并显示那些有名字的行。在大多数情况下,第一个会更可取。

导入 sark 导入 idautils

# First option - names list
def get_segment_names(name):
    seg = sark.Segment(name=name)
    for ea, name in idautils.Names():
        if seg.startEA <= ea < seg.endEA:
            yield ea, name


# Second option - iteration over lines
def get_segment_names2(name):
    seg = sark.Segment(name=name)
    for line in seg.lines:
        if line.has_name:
            yield line.ea, line.name

要使用它们,只需传递段的名称:

for ea, name in get_segment_names('.data'):
    print '{} at 0x{:x}'.format(name, ea)

现在,如果您想要外部参照,您可以稍后执行以下操作:

def show_segment_xrefs(name):
    for ea, name in get_segment_names(name):
        print 'xrefs to {} at 0x{:x} from:'.format(name, ea)
        for xref in sark.Line(ea).xrefs_to:
            print '    0x{:x}'.format(xref.frm)


get_segment_xrefs('.data')

并获取变量的所有外部参照。