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?
2 Answers
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 usingidc.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 sSep 8, 2016 at 5:46
-
-
@NirIzr "because I want to extract a list of cross references to each global variables" . He probably didn't know about other segments.– w sSep 8, 2016 at 7:09
-
@ws Thanks, edited to include your remark and a possible generic solution.– NirIzrSep 8, 2016 at 15:13
-
is there a way to do this AND get the name of global? (dword_########) Oct 21, 2019 at 18:47
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