Skip to content

Commit

Permalink
Added support for using pre-generated CFG in detourbackends
Browse files Browse the repository at this point in the history
  • Loading branch information
dnivra committed Nov 19, 2023
1 parent b27c2e1 commit 5661c2d
Show file tree
Hide file tree
Showing 10 changed files with 28 additions and 20 deletions.
4 changes: 2 additions & 2 deletions patcherex/backends/detourbackend.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import importlib

def DetourBackend(filename, data_fallback=None, base_address=None, try_pdf_removal=True, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False, variant=None):
def DetourBackend(filename, data_fallback=None, base_address=None, try_pdf_removal=True, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False, variant=None, cfg=None):
with open(filename, "rb") as f:
start_bytes = f.read(0x14)
if start_bytes.startswith(b"\x7fCGC"):
Expand Down Expand Up @@ -31,7 +31,7 @@ def DetourBackend(filename, data_fallback=None, base_address=None, try_pdf_remov
detourbackendclass = getattr(importlib.import_module("patcherex.backends.detourbackends.avr"), "DetourBackendAVR")
else:
raise Exception("Unsupported architecture.")
return detourbackendclass(filename, base_address=base_address, try_reuse_unused_space=try_reuse_unused_space, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg)
return detourbackendclass(filename, base_address=base_address, try_reuse_unused_space=try_reuse_unused_space, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg, cfg=cfg)
else:
raise Exception("Unsupported file type.")

Expand Down
12 changes: 10 additions & 2 deletions patcherex/backends/detourbackends/_elf.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,22 @@ class Perm(IntFlag):

class DetourBackendElf(Backend):
# how do we want to design this to track relocations in the blocks...
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False):
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False, cfg=None):
super().__init__(filename, project_options={"main_opts": {"base_addr": base_address}})

self.elf = ELFFile(open(filename, "rb"))
self.modded_segments = self.dump_segments() # dump_segments also set self.structs

self.try_without_cfg = try_without_cfg
self.cfg = self._generate_cfg() if not self.try_without_cfg else None
if self.try_without_cfg:
self.cfg = None
elif cfg is not None:
# Use pre-generated CFG provided
self.cfg = cfg
else:
# Generate CFG of binary
self.cfg = self._generate_cfg()

self.ordered_nodes = self._get_ordered_nodes(self.cfg) if not self.try_without_cfg else None

# header stuff
Expand Down
4 changes: 2 additions & 2 deletions patcherex/backends/detourbackends/aarch64.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@

class DetourBackendAarch64(DetourBackendElf):
# how do we want to design this to track relocations in the blocks...
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False):
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False, cfg=None):
if try_reuse_unused_space:
raise NotImplementedError()
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg)
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg, cfg=cfg)

def get_block_containing_inst(self, inst_addr):
index = bisect.bisect_right(self.ordered_nodes, inst_addr) - 1
Expand Down
4 changes: 2 additions & 2 deletions patcherex/backends/detourbackends/arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
class DetourBackendArm(DetourBackendElf):
# how do we want to design this to track relocations in the blocks...
def __init__(self, filename, base_address=None, try_reuse_unused_space=False,
replace_note_segment=False, try_without_cfg=False):
replace_note_segment=False, try_without_cfg=False, cfg=None):
if try_without_cfg:
raise NotImplementedError()
super().__init__(filename, base_address=base_address, try_reuse_unused_space=try_reuse_unused_space,
replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg)
replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg, cfg=cfg)
# Override code and data segment address since it fails for ARM
self.added_code_segment = 0x0600000
self.added_data_segment = 0x0700000
Expand Down
4 changes: 2 additions & 2 deletions patcherex/backends/detourbackends/arm_stm32.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
class DetourBackendArmStm32(DetourBackendArm):
# =========== WIP =============
# Not yet tested, designed for Nucleo-32 board
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False):
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False, cfg=None):
if try_reuse_unused_space:
raise NotImplementedError()
if try_without_cfg:
raise NotImplementedError()
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg)
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg, cfg=cfg)
self.name_map.force_insert("ADDED_DATA_START", self.modded_segments[1]['p_paddr'] + self.modded_segments[1]['p_filesz'])
self.added_data_file_start = self.modded_segments[1]['p_offset'] + self.modded_segments[1]['p_filesz']
self.sections = self.dump_sections()
Expand Down
4 changes: 2 additions & 2 deletions patcherex/backends/detourbackends/avr.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ class DetourBackendAVR(DetourBackendElf):
# =========== WIP =============
# Designed for ATMega328p, not tested for other chips
# how do we want to design this to track relocations in the blocks...
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False):
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False, cfg=None):
if try_reuse_unused_space:
raise NotImplementedError()
if replace_note_segment:
raise NotImplementedError()
if try_without_cfg:
raise NotImplementedError()
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg)
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg, cfg=cfg)
# we don't care about segments, we only care sections
self.sections = self.dump_sections()
for section in self.sections:
Expand Down
4 changes: 2 additions & 2 deletions patcherex/backends/detourbackends/cgc.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@

class DetourBackendCgc(Backend):
# how do we want to design this to track relocations in the blocks...
def __init__(self, filename, data_fallback=None, try_pdf_removal=True):
def __init__(self, filename, data_fallback=None, try_pdf_removal=True, cfg=None):
super().__init__(filename,try_pdf_removal)

self.cfg = self._generate_cfg()
self.cfg = cfg if cfg is not None else self._generate_cfg()
self.ordered_nodes = self._get_ordered_nodes(self.cfg)

# header stuff
Expand Down
4 changes: 2 additions & 2 deletions patcherex/backends/detourbackends/i386.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@

class DetourBackendi386(DetourBackendElf):
# how do we want to design this to track relocations in the blocks...
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False):
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False, cfg=None):
if try_reuse_unused_space:
raise NotImplementedError()
if try_without_cfg:
raise NotImplementedError()
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg)
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg, cfg=cfg)

def apply_patches(self, patches):
# deal with stackable patches
Expand Down
4 changes: 2 additions & 2 deletions patcherex/backends/detourbackends/mips.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@

class DetourBackendMips(DetourBackendElf):
# how do we want to design this to track relocations in the blocks...
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False):
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False, cfg=None):
if try_reuse_unused_space:
raise NotImplementedError()
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg)
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg, cfg=cfg)
if self.structs.elfclass == 64:
self.added_code_segment = 0x120600000
self.added_data_segment = 0x120700000
Expand Down
4 changes: 2 additions & 2 deletions patcherex/backends/detourbackends/ppc.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@

class DetourBackendPpc(DetourBackendElf):
# how do we want to design this to track relocations in the blocks...
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False):
def __init__(self, filename, base_address=None, try_reuse_unused_space=False, replace_note_segment=False, try_without_cfg=False, cfg=None):
if try_reuse_unused_space:
raise NotImplementedError()
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg)
super().__init__(filename, base_address=base_address, replace_note_segment=replace_note_segment, try_without_cfg=try_without_cfg, cfg=cfg)
self.added_code_segment = 0x10600000
self.added_data_segment = 0x10700000
self.name_map.update(ADDED_DATA_START = (len(self.ncontent) % 0x1000) + self.added_data_segment)
Expand Down

0 comments on commit 5661c2d

Please sign in to comment.