Skip to content

Instantly share code, notes, and snippets.

@in7egral
Created November 11, 2024 09:30
Show Gist options
  • Save in7egral/b336d24eb98d3e93300a43dd989a00c2 to your computer and use it in GitHub Desktop.
Save in7egral/b336d24eb98d3e93300a43dd989a00c2 to your computer and use it in GitHub Desktop.
# IDA Python RTTI parser ~pod2g 06/2013
# Porting to the IDA and some new features ~in7egral 05/2024
from idaapi import *
from idc import *
# TODO: test on 64bit !!!
addr_size = 4
code_seg = code_seg_end = 0
first_seg = get_first_seg()
last_seg = first_seg
for seg in Segments():
if get_segm_name(seg) == '.text':
code_seg = seg
code_seg_end= get_segm_end(seg)
if seg > last_seg:
last_seg = seg
if seg < first_seg:
first_seg = seg
def get_pointer(ea):
if addr_size == 4:
return get_dword(ea)
else:
return get_qword(ea)
def in_image(ea):
if ea >= code_seg and ea <= code_seg_end: return 0
return ea >= first_seg and ea <= get_segm_end(last_seg)
def get_class_name(name_addr):
if not in_image(name_addr):
return 'bad_addr'
#print('name %x' % name_addr)
s = demangle_name((b'??_7' + get_strlit_contents(name_addr + 4) + b'6B@').decode('utf8'), 8)
if s != None:
return s[0:len(s)-11]
else:
return get_strlit_contents(name_addr)
start = first_seg
while True:
f = find_binary(start, SEARCH_DOWN, "2E 3F 41 56") # .?AV
start = f + addr_size
if f == BADADDR:
break
# RTTI Type Descriptor
rtd = f - 8
print("Found class: %s (rtd=0x%X)" % (get_class_name(f), rtd))
for xref in XrefsTo(rtd):
print('xref rtd %x' % xref.frm)
rbcd_pTypeDescriptor_name = ''
# reference to class hierarchy descriptor
rchd = get_pointer(xref.frm + addr_size)
if in_image(rchd):
rcol = xref.frm - 12
rchd_numBaseClasses = get_dword(rchd + 8)
rchd_pBaseClassArray = get_pointer(rchd + 12)
for i in range(rchd_numBaseClasses):
rbcd = get_pointer(rchd_pBaseClassArray + addr_size * i)
rbcd_pTypeDescriptor = get_pointer(rbcd)
rbcd_pTypeDescriptor_name = get_class_name(rbcd_pTypeDescriptor + 8)
if rbcd_pTypeDescriptor_name == 'bad_addr': break
print(" - base class: %s" % rbcd_pTypeDescriptor_name)
if rbcd_pTypeDescriptor_name == 'bad_addr': break
for xref in XrefsTo(rcol):
vtable = xref.frm + addr_size
break
print(" - vtable: 0x%X" % vtable)
if rbcd_pTypeDescriptor_name == 'std::exception':
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment