Created
November 11, 2024 09:30
-
-
Save in7egral/b336d24eb98d3e93300a43dd989a00c2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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