diff --git a/patcherex/backends/detourbackend.py b/patcherex/backends/detourbackend.py index eaf6c2d..be6835c 100644 --- a/patcherex/backends/detourbackend.py +++ b/patcherex/backends/detourbackend.py @@ -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"): @@ -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.") diff --git a/patcherex/backends/detourbackends/_elf.py b/patcherex/backends/detourbackends/_elf.py index fbba2d2..33226b7 100644 --- a/patcherex/backends/detourbackends/_elf.py +++ b/patcherex/backends/detourbackends/_elf.py @@ -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 diff --git a/patcherex/backends/detourbackends/aarch64.py b/patcherex/backends/detourbackends/aarch64.py index 49006c7..4571f83 100644 --- a/patcherex/backends/detourbackends/aarch64.py +++ b/patcherex/backends/detourbackends/aarch64.py @@ -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 diff --git a/patcherex/backends/detourbackends/arm.py b/patcherex/backends/detourbackends/arm.py index 8b95da7..4d924b4 100644 --- a/patcherex/backends/detourbackends/arm.py +++ b/patcherex/backends/detourbackends/arm.py @@ -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 diff --git a/patcherex/backends/detourbackends/arm_stm32.py b/patcherex/backends/detourbackends/arm_stm32.py index d097aeb..ef09339 100644 --- a/patcherex/backends/detourbackends/arm_stm32.py +++ b/patcherex/backends/detourbackends/arm_stm32.py @@ -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() diff --git a/patcherex/backends/detourbackends/avr.py b/patcherex/backends/detourbackends/avr.py index 8069c33..4c9c85f 100644 --- a/patcherex/backends/detourbackends/avr.py +++ b/patcherex/backends/detourbackends/avr.py @@ -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: diff --git a/patcherex/backends/detourbackends/cgc.py b/patcherex/backends/detourbackends/cgc.py index 4bb6c0a..dece30f 100644 --- a/patcherex/backends/detourbackends/cgc.py +++ b/patcherex/backends/detourbackends/cgc.py @@ -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 diff --git a/patcherex/backends/detourbackends/i386.py b/patcherex/backends/detourbackends/i386.py index dc23d22..c3040bb 100644 --- a/patcherex/backends/detourbackends/i386.py +++ b/patcherex/backends/detourbackends/i386.py @@ -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 diff --git a/patcherex/backends/detourbackends/mips.py b/patcherex/backends/detourbackends/mips.py index 8800611..fd18d28 100644 --- a/patcherex/backends/detourbackends/mips.py +++ b/patcherex/backends/detourbackends/mips.py @@ -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 diff --git a/patcherex/backends/detourbackends/ppc.py b/patcherex/backends/detourbackends/ppc.py index 4c2761f..5426b48 100644 --- a/patcherex/backends/detourbackends/ppc.py +++ b/patcherex/backends/detourbackends/ppc.py @@ -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)