3

I am trying to use IDA python to get a list of all variables in .data section because I want to extract a list of cross references to each global variables from IDA. Is it possible to do this with IDA python?

5

Although Sark is a good library/tool, if you're only looking for a small utility script you might want to avoid the overhead of installing it. I do recommend you give it a try regardless.

The following code will do just that without using any third party code:

# 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))

Gotaches:

  • Using this code you'll see all cross references, not only those with a name, although adding that is quite trivial if you'd rather have it that way.
  • As mentioned by @ws, you'll only see variables located at the .data section as the OP requested, you should consider including other data related sections (such as .idata, .rodata, .bss, and others). Alternatively you might want to consider using idc.isData(idc.GetFlags(ea)) to filter out non-data offsets in some or all sections.
  • 1
    +1 but there are more segments that may contain global variables, .rodata and .bss in ELF for example – w s Sep 8 '16 at 5:46
  • @w s that is what the OP has asked for – NirIzr Sep 8 '16 at 6:49
  • @NirIzr "because I want to extract a list of cross references to each global variables" . He probably didn't know about other segments. – w s Sep 8 '16 at 7:09
  • @ws Thanks, edited to include your remark and a possible generic solution. – NirIzr Sep 8 '16 at 15:13
  • is there a way to do this AND get the name of global? (dword_########) – bravosierra99 Oct 21 at 18:47
2

There are several ways to do this. I am using Sark because it makes coding a bit easier.

The first option here is iterating over IDA's name list, and filtering by the addresses. The second one is going over all the lines in a segment, and showing those with names. In most cases, the first would be preferable.

import sark import 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

To use them, just pass the name of the segment:

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

Now, if you want xrefs, you can later do something like this:

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')

And get all the xrefs for the variables.

  • 1
    Upvoted to show my support for Sark :) – NirIzr Sep 7 '16 at 22:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.