Created
June 1, 2024 08:55
-
-
Save d0now/36d861668750d55feb42ab1dd9f01786 to your computer and use it in GitHub Desktop.
Binary Ninja RTTI lookup for class name
This file contains 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
# | |
# | |
from binaryninja.binaryview import BinaryView | |
from binaryninja.lowlevelil import LowLevelILStore, LowLevelILOperation | |
from binaryninja.variable import RegisterValueType | |
from binaryninja.demangle import demangle_gnu3 | |
from binaryninja.exceptions import ILException | |
def get_llil_lifted(bv: BinaryView): | |
llils = bv.llil_instructions | |
while True: | |
try: | |
yield next(llils) | |
except ILException: | |
continue | |
except StopIteration: | |
break | |
def get_vftable_assignments(bv: BinaryView): | |
for llil in get_llil_lifted(bv): | |
llil: LowLevelILStore = llil | |
if llil.operation != LowLevelILOperation.LLIL_STORE: | |
continue | |
if llil.src.value.type != RegisterValueType.ConstantPointerValue: | |
continue | |
yield (llil, llil.src.value.value) | |
def get_vftable_end(bv: BinaryView, address: int): | |
now = address | |
while val := bv.read_pointer(now): | |
if not bv.get_function_at(val): | |
break | |
else: | |
now += bv.arch.address_size | |
return now | |
def get_rtti_symbol(bv: BinaryView, address: int): | |
rtti_address = bv.read_pointer(address - bv.arch.address_size) | |
mangled = bv.get_string_at(bv.read_pointer(rtti_address + bv.arch.address_size)) | |
if not mangled: | |
raise ValueError("No string") | |
else: | |
m_type, m_names = demangle_gnu3(bv.arch, "_Z" + mangled.value) | |
return "::".join(m_names) | |
def run(bv: BinaryView): | |
vftables: dict[int, str] = {} | |
for llil, vftable_start in get_vftable_assignments(bv): | |
try: | |
vftable_end = get_vftable_end(bv, vftable_start) | |
rtti_symbol = get_rtti_symbol(bv, vftable_start) | |
except ValueError: | |
continue | |
vftables[vftable_start] = rtti_symbol | |
if bv.get_tag_type("vftables"): | |
bv.remove_tag_type("vftables") | |
bv.create_tag_type("vftables", "🤪") | |
with bv.undoable_transaction(): | |
for addr, data in vftables.items(): | |
bv.add_tag(addr, "vftables", data) | |
run(bv) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment