From 28e9607d0f17948b053bc390fe560e1963cd8314 Mon Sep 17 00:00:00 2001 From: lordidiot <0xlordidiot@gmail.com> Date: Wed, 23 Feb 2022 23:21:31 +0800 Subject: [PATCH] Support native features on PIE bins (#37) * fix typo in filename * Support native features on PIE bins --- ..._runnner.py => manticore_native_runner.py} | 0 mui/mui.py | 61 +++++++++++++++---- 2 files changed, 49 insertions(+), 12 deletions(-) rename mui/{manticore_native_runnner.py => manticore_native_runner.py} (100%) diff --git a/mui/manticore_native_runnner.py b/mui/manticore_native_runner.py similarity index 100% rename from mui/manticore_native_runnner.py rename to mui/manticore_native_runner.py diff --git a/mui/mui.py b/mui/mui.py index 1276b31..69b6d94 100644 --- a/mui/mui.py +++ b/mui/mui.py @@ -17,6 +17,8 @@ get_open_filename_input, Architecture, SettingsScope, + TypedDataAccessor, + Endianness, ) from binaryninjaui import DockHandler, UIContext from crytic_compile import CryticCompile @@ -31,7 +33,7 @@ from mui.dockwidgets.state_graph_widget import StateGraphWidget from mui.dockwidgets.state_list_widget import StateListWidget from mui.manticore_evm_runner import ManticoreEVMRunner -from mui.manticore_native_runnner import ManticoreNativeRunner +from mui.manticore_native_runner import ManticoreNativeRunner from mui.notification import UINotification from mui.settings import MUISettings from mui.utils import highlight_instr, clear_highlight @@ -44,6 +46,39 @@ BinaryView.set_default_session_data("mui_is_running", False) BinaryView.set_default_session_data("mui_state", None) BinaryView.set_default_session_data("mui_evm_source", None) +BinaryView.set_default_session_data("mui_addr_offset", None) + + +def offset_address(bv: BinaryView, addr: int): + """Offsets addresses to take into consideration position independent executables (PIE)""" + # Addresses taken from https://github.com/trailofbits/manticore/blob/c3eabe03cf94f410bedd96d850df09cb0bda1711/manticore/platforms/linux.py#L954-L956 + BASE_DYN_ADDR = 0x555555554000 + BASE_DYN_ADDR_32 = 0x56555000 + + addr_off = bv.session_data.mui_addr_offset + if addr_off == None: + if bv.arch == Architecture["x86_64"]: + h_addr = bv.symbols["__elf_header"][0].address + h_type = bv.types["Elf64_Header"] + header = TypedDataAccessor(h_type, h_addr, bv, Endianness.LittleEndian) + if header["type"].value == 3: # ET_DYN + addr_off = BASE_DYN_ADDR + else: + addr_off = 0 + elif bv.arch == Architecture["x86"]: + h_addr = bv.symbols["__elf_header"][0].address + h_type = bv.types["Elf32_Header"] + header = TypedDataAccessor(h_type, h_addr, bv, Endianness.LittleEndian) + if header["type"].value == 3: # ET_DYN + addr_off = BASE_DYN_ADDR_32 + else: + addr_off = 0 + else: + addr_off = 0 + + bv.session_data.mui_addr_offset = addr_off + + return addr_off + addr def find_instr(bv: BinaryView, addr: int): @@ -53,7 +88,7 @@ def find_instr(bv: BinaryView, addr: int): highlight_instr(bv, addr, HighlightStandardColor.GreenHighlightColor) # Add the instruction to the list associated with the current view - bv.session_data.mui_find.add(addr) + bv.session_data.mui_find.add(offset_address(bv, addr)) def rm_find_instr(bv: BinaryView, addr: int): @@ -63,7 +98,7 @@ def rm_find_instr(bv: BinaryView, addr: int): clear_highlight(bv, addr) # Remove the instruction to the list associated with the current view - bv.session_data.mui_find.remove(addr) + bv.session_data.mui_find.remove(offset_address(bv, addr)) def avoid_instr(bv: BinaryView, addr: int): @@ -73,7 +108,7 @@ def avoid_instr(bv: BinaryView, addr: int): highlight_instr(bv, addr, HighlightStandardColor.RedHighlightColor) # Add the instruction to the list associated with the current view - bv.session_data.mui_avoid.add(addr) + bv.session_data.mui_avoid.add(offset_address(bv, addr)) def rm_avoid_instr(bv: BinaryView, addr: int): @@ -83,7 +118,7 @@ def rm_avoid_instr(bv: BinaryView, addr: int): clear_highlight(bv, addr) # Remove the instruction to the list associated with the current view - bv.session_data.mui_avoid.remove(addr) + bv.session_data.mui_avoid.remove(offset_address(bv, addr)) def solve(bv: BinaryView): @@ -148,8 +183,10 @@ def solve(bv: BinaryView): def edit_custom_hook(bv: BinaryView, addr: int): dialog = CodeDialog(DockHandler.getActiveDockHandler().parent(), bv) - if addr in bv.session_data.mui_custom_hooks: - dialog.set_text(bv.session_data.mui_custom_hooks[addr]) + off_addr = offset_address(bv, addr) + + if off_addr in bv.session_data.mui_custom_hooks: + dialog.set_text(bv.session_data.mui_custom_hooks[off_addr]) result: QDialog.DialogCode = dialog.exec() @@ -157,14 +194,14 @@ def edit_custom_hook(bv: BinaryView, addr: int): if len(dialog.text()) == 0: # delete the hook if empty input is provided - if addr in bv.session_data.mui_custom_hooks: + if off_addr in bv.session_data.mui_custom_hooks: clear_highlight(bv, addr) - del bv.session_data.mui_custom_hooks[addr] + del bv.session_data.mui_custom_hooks[off_addr] else: # add/edit the hook if input is non-empty highlight_instr(bv, addr, HighlightStandardColor.BlueHighlightColor) - bv.session_data.mui_custom_hooks[addr] = dialog.text() + bv.session_data.mui_custom_hooks[off_addr] = dialog.text() def load_evm(bv: BinaryView): @@ -208,12 +245,12 @@ def stop_manticore(bv: BinaryView): def avoid_instr_is_valid(bv: BinaryView, addr: int): """checks if avoid_instr is valid for a given address""" - return addr not in bv.session_data.mui_avoid + return offset_address(bv, addr) not in bv.session_data.mui_avoid def find_instr_is_valid(bv: BinaryView, addr: int): """checks if find_instr is valid for a given address""" - return addr not in bv.session_data.mui_find + return offset_address(bv, addr) not in bv.session_data.mui_find def solve_is_valid(bv: BinaryView):