Guest User

Untitled

a guest
May 24th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.05 KB | None | 0 0
  1. def check_rtti_magic(view, magic):
  2. if view.address_size == 4:
  3. return magic == 0
  4. if view.address_size == 8:
  5. return magic == 1
  6. return False
  7.  
  8. def get_rtti_address(view, offset):
  9. if view.address_size == 4:
  10. return offset
  11. if view.address_size == 8:
  12. return view.start + offset
  13. return None
  14.  
  15. def read_pointer(view, reader):
  16. if view.address_size == 4:
  17. return reader.read32le()
  18. if view.address_size == 8:
  19. return reader.read64le()
  20. return None
  21.  
  22. def read_rtti_pointer(view, reader):
  23. offset = reader.read32le()
  24. if view.address_size == 8:
  25. offset = view.start + offset
  26. return offset
  27.  
  28. def check_offset(view, offset):
  29. return view.start <= offset < view.end
  30.  
  31. def read_cstring(reader):
  32. buf = bytearray()
  33. while True:
  34. b = reader.read8()
  35. if b is None or b == 0:
  36. return str(buf)
  37. else:
  38. buf.append(b)
  39.  
  40. class RTTICompleteObjectLocator:
  41. def read(self, view, reader, offset):
  42. reader.seek(offset)
  43. magic = reader.read32le()
  44. if not check_rtti_magic(view, magic):
  45. return False
  46. unk0 = read_rtti_pointer(view, reader)
  47. cd_offset = read_rtti_pointer(view, reader)
  48. type_desc_offset = read_rtti_pointer(view, reader)
  49. class_desc_offset = read_rtti_pointer(view, reader)
  50. if not check_offset(view, type_desc_offset):
  51. print (('Bad Type Desc'), type_desc_offset)
  52. return False
  53. if not check_offset(view, class_desc_offset):
  54. print (('Bad Class Desc'), class_desc_offset)
  55. return False
  56. self.type_descriptor = RTTITypeDescriptor()
  57. if not self.type_descriptor.read(view, reader, type_desc_offset):
  58. return False
  59. return True
  60.  
  61. class RTTITypeDescriptor:
  62. def read(self, view, reader, offset):
  63. reader.seek(offset)
  64. self.vtable_addr = read_pointer(view, reader)
  65. if not check_offset(view, self.vtable_addr):
  66. return False
  67. read_pointer(view, reader)
  68. self.decorated_name = read_cstring(reader)
  69. if not self.decorated_name.startswith('.?'):
  70. return False
  71. # Currently binja doesn't demangle the vtable name
  72. self.name = decorated_name[1:]
  73. return True
  74.  
  75. class RTTIClassHierarchyDescriptor:
  76. def __init__(self):
  77. pass
  78.  
  79. class RTTIBaseClassArray:
  80. def __init__(self):
  81. pass
  82.  
  83. class RTTIBaseClassDescriptor:
  84. def __init__(self):
  85. pass
  86.  
  87. class PMD:
  88. def __init__(self):
  89. pass
  90.  
  91. def scan_for_rtti(view, start, end):
  92. reader = BinaryReader(view)
  93. for i in range(start, end, view.address_size):
  94. reader.seek(i)
  95. pCompleteObject = read_pointer(view, reader)
  96. if start < pCompleteObject < end:
  97. rtti = RTTICompleteObjectLocator()
  98. if rtti.read(view, reader, pCompleteObject):
  99. view.define_user_symbol(Symbol(SymbolType.DataSymbol, i + view.address_size, 'vtable_' + rtti.type_descriptor.name ))
  100.  
  101. rdata = bv.sections['.rdata']
  102. scan_for_rtti(bv, rdata.start, rdata.end)
Add Comment
Please, Sign In to add comment