Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def check_rtti_magic(view, magic):
- if view.address_size == 4:
- return magic == 0
- if view.address_size == 8:
- return magic == 1
- return False
- def get_rtti_address(view, offset):
- if view.address_size == 4:
- return offset
- if view.address_size == 8:
- return view.start + offset
- return None
- def read_pointer(view, reader):
- if view.address_size == 4:
- return reader.read32le()
- if view.address_size == 8:
- return reader.read64le()
- return None
- def read_rtti_pointer(view, reader):
- offset = reader.read32le()
- if view.address_size == 8:
- offset = view.start + offset
- return offset
- def check_offset(view, offset):
- return view.start <= offset < view.end
- def read_cstring(reader):
- buf = bytearray()
- while True:
- b = reader.read8()
- if b is None or b == 0:
- return str(buf)
- else:
- buf.append(b)
- class RTTICompleteObjectLocator:
- def read(self, view, reader, offset):
- reader.seek(offset)
- magic = reader.read32le()
- if not check_rtti_magic(view, magic):
- return False
- unk0 = read_rtti_pointer(view, reader)
- cd_offset = read_rtti_pointer(view, reader)
- type_desc_offset = read_rtti_pointer(view, reader)
- class_desc_offset = read_rtti_pointer(view, reader)
- if not check_offset(view, type_desc_offset):
- print (('Bad Type Desc'), type_desc_offset)
- return False
- if not check_offset(view, class_desc_offset):
- print (('Bad Class Desc'), class_desc_offset)
- return False
- self.type_descriptor = RTTITypeDescriptor()
- if not self.type_descriptor.read(view, reader, type_desc_offset):
- return False
- return True
- class RTTITypeDescriptor:
- def read(self, view, reader, offset):
- reader.seek(offset)
- self.vtable_addr = read_pointer(view, reader)
- if not check_offset(view, self.vtable_addr):
- return False
- read_pointer(view, reader)
- self.decorated_name = read_cstring(reader)
- if not self.decorated_name.startswith('.?'):
- return False
- # Currently binja doesn't demangle the vtable name
- self.name = decorated_name[1:]
- return True
- class RTTIClassHierarchyDescriptor:
- def __init__(self):
- pass
- class RTTIBaseClassArray:
- def __init__(self):
- pass
- class RTTIBaseClassDescriptor:
- def __init__(self):
- pass
- class PMD:
- def __init__(self):
- pass
- def scan_for_rtti(view, start, end):
- reader = BinaryReader(view)
- for i in range(start, end, view.address_size):
- reader.seek(i)
- pCompleteObject = read_pointer(view, reader)
- if start < pCompleteObject < end:
- rtti = RTTICompleteObjectLocator()
- if rtti.read(view, reader, pCompleteObject):
- view.define_user_symbol(Symbol(SymbolType.DataSymbol, i + view.address_size, 'vtable_' + rtti.type_descriptor.name ))
- rdata = bv.sections['.rdata']
- scan_for_rtti(bv, rdata.start, rdata.end)
Add Comment
Please, Sign In to add comment