1+ #from __future__ import print_function
12"""vtable_dump.py: IDAPython script to dump a linux vtable (and a reconstructed windows one) from a binary."""
23
34"""
4344offsetdata = {}
4445
4546# Detect address size
47+ __EA64__ = ida_idaapi .BADADDR == 0xFFFFFFFFFFFFFFFF
4648adr_size = 8 if __EA64__ else 4
4749
4850def ExtractTypeInfo (ea , level = 0 ):
@@ -56,14 +58,14 @@ def ExtractTypeInfo(ea, level = 0):
5658 while len (Name (end )) == 0 :
5759 end += adr_size
5860
59- while Dword (end - adr_size ) == 0 :
61+ while (end - adr_size ) == 0 :
6062 end -= adr_size
6163
6264 # Skip vtable
6365 ea += adr_size
6466
6567 # Get type name
66- name = Demangle ("_Z" + GetString ( Dword ( ea )), GetLongPrm ( INF_LONG_DN ))
68+ name = idc . demangle_name ("_Z" + ida_bytes . get_strlit_contents ( ea ), ida_ida . inf_get_long_demnames ( ))
6769 ea += adr_size
6870
6971 if classname is None and level == 0 :
@@ -73,20 +75,20 @@ def ExtractTypeInfo(ea, level = 0):
7375 innerclass = name
7476 catchclass = False
7577
76- print " %*s%s" % (level , "" , name )
78+ print ( " %*s%s" % (level , "" , name ) )
7779
7880 if not ea < end : # Base Type
7981 pass
80- elif Dword ( ea ) != 0 : #elif isData(GetFlags(Dword(ea) )): # Single Inheritance
81- ExtractTypeInfo (Dword ( ea ) , level + 1 )
82+ elif ea != 0 : #elif isData(GetFlags(ea )): # Single Inheritance
83+ ExtractTypeInfo (ea , level + 1 )
8284 ea += adr_size
8385 else : # Multiple Inheritance
8486 ea += 8
8587 while ea < end :
8688 catchclass = True
87- ExtractTypeInfo (Dword ( ea ) , level + 1 )
89+ ExtractTypeInfo (ea , level + 1 )
8890 ea += adr_size
89- offset = Dword ( ea )
91+ offset = ea
9092 ea += adr_size
9193 #print "%*s Offset: 0x%06X" % (level, "", offset >> 8)
9294 if (offset >> 8 ) != 0 :
@@ -100,29 +102,29 @@ def twos_comp(val, bits):
100102 return val
101103
102104def Analyze ():
103- SetStatus (IDA_STATUS_WORK )
105+ ida_auto . set_ida_state (IDA_STATUS_WORK )
104106
105- if GetLongPrm ( INF_COMPILER ). id != COMP_GNU :
107+ if ida_ida . inf_get_cc_id () != COMP_GNU :
106108 Warning ("This script is for binaries compiled with GCC only." )
107- SetStatus (IDA_STATUS_READY )
109+ ida_auto . set_ida_state (IDA_STATUS_READY )
108110 return
109111
110- ea = ScreenEA ()
112+ ea = idc . get_screen_ea ()
111113
112114 end = ea + adr_size
113- while Demangle ( Name (end ), GetLongPrm ( INF_LONG_DN )) is None :
115+ while idc . demangle_name ( idc . get_name (end , ida_name . GN_VISIBLE ), ida_ida . inf_get_long_demnames ( )) is None :
114116 end += adr_size
115117
116- while Dword (end - adr_size ) == 0 :
118+ while (end - adr_size ) == 0 :
117119 end -= adr_size
118120
119- while Demangle ( Name (ea ), GetLongPrm ( INF_LONG_DN )) is None :
121+ while idc . demangle_name ( idc . get_name (ea , ida_name . GN_VISIBLE ), ida_ida . inf_get_long_demnames ( )) is None :
120122 ea -= adr_size
121123
122- name = Demangle ( Name (ea ), GetLongPrm ( INF_LONG_DN ))
123- if ea == BADADDR or name is None or not re .search (r"vf?table(?: |'\{)for" , name ):
124+ name = idc . demangle_name ( idc . get_name (ea , ida_name . GN_VISIBLE ), ida_ida . inf_get_long_demnames ( ))
125+ if ea == ida_idaapi . BADADDR or name is None or not re .search (r"vf?table(?: |'\{)for" , name ):
124126 Warning ("No vtable selected!\n Select vtable block first." )
125- SetStatus (IDA_STATUS_READY )
127+ ida_auto . set_ida_state (IDA_STATUS_READY )
126128 return
127129
128130 linux_vtable = []
@@ -135,22 +137,22 @@ def Analyze():
135137 # Extract vtable
136138 while ea < end :
137139 # Read thisoffs
138- offset = - twos_comp (Dword ( ea ) , 32 )
140+ offset = - twos_comp (ea , 32 )
139141 #print "Offset: 0x%08X (%08X)" % (offset, ea)
140142 ea += adr_size
141143
142144 # Read typeinfo address
143- typeinfo = Dword ( ea )
145+ typeinfo = ea
144146 ea += adr_size
145147
146148 if offset == 0 : # We only need to read this once
147- print "Inheritance Tree:"
149+ print ( "Inheritance Tree:" )
148150 ExtractTypeInfo (typeinfo )
149151
150- while ea < end and (isCode ( GetFlags ( Dword ( ea ))) or Name ( Dword ( ea ) ) == "___cxa_pure_virtual" ):
151- name = Name ( Dword ( ea ) )
152- demangled = Demangle (name , GetLongPrm ( INF_LONG_DN ))
153- #print "Name: %s, Demangled : %s" % (name, demangled)
152+ while ( ea < end ) and (ida_bytes . is_code ( ida_bytes . get_full_flags ( ea )) or idc . get_name ( ea , ida_name . GN_VISIBLE ) == "___cxa_pure_virtual" ):
153+ name = idc . get_name ( ea , ida_name . GN_VISIBLE )
154+ demangled = idc . demangle_name (name , ida_ida . inf_get_long_demnames ( ))
155+ #print "Name: %s, idc.demangle_named : %s" % (name, demangled)
154156
155157 name = demangled if demangled else name
156158
@@ -216,18 +218,18 @@ def Analyze():
216218 while len (overload_stack ) > 0 :
217219 windows_vtable .append (overload_stack .pop ())
218220
219- print "\n VTable for %s: (0, 0)" % (classname )
220- print " Lin Win Function"
221+ print ( "\n VTable for %s: (0, 0)" % (classname ) )
222+ print ( " Lin Win Function" )
221223 for i , v in enumerate (linux_vtable ):
222224 if "__cxa_pure_virtual" in v :
223- print "P%3d" % (i )
225+ print ( "P%3d" % (i ) )
224226 continue
225227
226228 winindex = windows_vtable .index (v ) if v in windows_vtable else None
227229 if winindex is not None :
228- print "%4d %4d %s" % (i , winindex , v )
230+ print ( "%4d %4d %s" % (i , winindex , v ) )
229231 else :
230- print "%4d %s" % (i , v )
232+ print ( "%4d %s" % (i , v ) )
231233
232234 for k in temp_other_windows_vtables :
233235 for i , v in enumerate (temp_other_windows_vtables [k ]):
@@ -260,20 +262,20 @@ def Analyze():
260262 prev_symbol = v
261263
262264 for k in other_linux_vtables :
263- print "\n VTable for %s: (%d, %d)" % (offsetdata [k ], offsetdata .keys ().index (k ) + 1 , k )
264- print " Lin Win Function"
265+ print ( "\n VTable for %s: (%d, %d)" % (offsetdata [k ], offsetdata .keys ().index (k ) + 1 , k ) )
266+ print ( " Lin Win Function" )
265267 for i , v in enumerate (other_linux_vtables [k ]):
266268 if "__cxa_pure_virtual" in v :
267- print "P%3d" % (i )
269+ print ( "P%3d" % (i ) )
268270 continue
269271
270272 winindex = other_windows_vtables [k ].index (v )
271273 if v not in other_thunk_linux_vtables [k ]:
272- print "%4d %4d %s" % (i , winindex , v )
274+ print ( "%4d %4d %s" % (i , winindex , v ) )
273275 else :
274- print "T%3d %4d %s" % (i , winindex , v )
276+ print ( "T%3d %4d %s" % (i , winindex , v ) )
275277
276- SetStatus (IDA_STATUS_READY )
278+ ida_auto . set_ida_state (IDA_STATUS_READY )
277279
278280if __name__ == '__main__' :
279281 Analyze ()
0 commit comments