From 13320374d9d0f86a6b0fdc1f91292a1436f88423 Mon Sep 17 00:00:00 2001 From: Dobin Date: Sun, 2 Jun 2024 13:17:40 +0100 Subject: [PATCH] refactor: cleanup --- app/views_project.py | 2 +- model/rangemanager.py | 12 ++++++++++++ observer.py | 2 +- pe/derbackdoorer.py | 35 ++--------------------------------- pe/superpe.py | 6 +++--- phases/injector.py | 4 ++-- 6 files changed, 21 insertions(+), 40 deletions(-) diff --git a/app/views_project.py b/app/views_project.py index 484fb8a..5cc6989 100644 --- a/app/views_project.py +++ b/app/views_project.py @@ -84,7 +84,7 @@ def project(name): if superpe.get_section_by_name(".rdata") != None: data_sect_size = superpe.get_section_by_name(".rdata").virt_size else: - logger.warn("No .rdata section found in {}".format(project.settings.inject_exe_in)) + logger.warning("No .rdata section found in {}".format(project.settings.inject_exe_in)) has_rodata_section = superpe.has_rodata_section() if has_rodata_section: diff --git a/model/rangemanager.py b/model/rangemanager.py index 6f376f2..4993b58 100644 --- a/model/rangemanager.py +++ b/model/rangemanager.py @@ -16,6 +16,12 @@ class RangeManager: self.intervals.merge_overlaps(strict=False) + def print_all(self): + logger.info("Min: {} Max: {}".format(self.min, self.max)) + for i in self.intervals: + logger.info("Interval: {}-{}".format(i.begin, i.end)) + + def add_range(self, start, end): if start < self.min or end > self.max: raise ValueError("Ranges must be within 0x{:X} and 0x{:X}, not 0x{:X}/0x{:X}".format( @@ -32,6 +38,12 @@ class RangeManager: if start - last_end >= hole_size: return (last_end + 1, start - 1) last_end = max(last_end, end) + + # at the end + if last_end < self.max: + return last_end + + return None def find_holes(self, hole_size): diff --git a/observer.py b/observer.py index e9831b3..e782b50 100644 --- a/observer.py +++ b/observer.py @@ -59,7 +59,7 @@ class Observer(): try: f.write(line + "\n") except Exception as e: - logger.warn("Error: {}".format(e)) + logger.warning("Error: {}".format(e)) # Stdout of executed commands with open(f"{working_dir}log-cmdoutput.log", "w") as f: diff --git a/pe/derbackdoorer.py b/pe/derbackdoorer.py index 449dacf..e52cc87 100644 --- a/pe/derbackdoorer.py +++ b/pe/derbackdoorer.py @@ -45,10 +45,10 @@ class FunctionBackdoorer: it = IntervalTree() it.addi(addr, addr+len(compiled_trampoline)) if it.overlap(shellcode_addr, shellcode_addr+shellcode_len): - logger.warn("Attempt to patch jump (0x{:X}-0x{:X}) to shellcode (0x{:X}-0x{:X}) but they overlap and probably dont work".format( + logger.warning("Attempt to patch jump (0x{:X}-0x{:X}) to shellcode (0x{:X}-0x{:X}) but they overlap and probably dont work".format( addr, addr+len(compiled_trampoline), shellcode_addr, shellcode_addr+shellcode_len )) - logger.warn("Text section too small?") + logger.warning("Text section too small?") # write #logger.info("Trampoline: {}".format(compiled_trampoline)) @@ -108,34 +108,3 @@ class FunctionBackdoorer: return None - - def get_trampoline(self, addr, shellcode_addr): - addrOffset = -1 - - if not self.superpe.is_64(): - raise Exception("Not 64 bit") - reg = random.choice(['rax', 'rbx', 'rcx', 'rdx', 'rsi', 'rdi']).upper() - full_shellcode_addr = shellcode_addr + self.superpe.pe.OPTIONAL_HEADER.ImageBase - - enc, count = self.ks.asm(f'MOV {reg}, 0x{full_shellcode_addr:X}') - for instr2 in cs.disasm(bytes(enc), 0): - addrOffset = len(instr2.bytes) - instr2.addr_size - break - - jump = random.choice([ - f'CALL {reg}', - - # - # During my tests I found that CALL reg works stabily all the time, whereas below two gadgets - # are known to crash on seldom occassions. - # - - #f'JMP {reg}', - #f'PUSH {reg} ; RET', - ]) - - trampoline_text = f'MOV {reg}, 0x{full_shellcode_addr:X} ; {jump}' - trampoline_compiled, count = ks.asm(trampoline_text) - - return trampoline_compiled, trampoline_text, addrOffset - \ No newline at end of file diff --git a/pe/superpe.py b/pe/superpe.py index f72c9d7..6413c16 100644 --- a/pe/superpe.py +++ b/pe/superpe.py @@ -199,8 +199,8 @@ class SuperPe(): sizeOfReloc = 2 * len(relocs) + 2 * 4 if sizeOfReloc >= self.getRemainingRelocsDirectorySize(): - self.logger.warn('WARNING! Cannot add any more relocations to this file. Probably TLS Callback execution technique wont work.') - self.logger.warn(' Will try disabling relocations on output file. Expect corrupted executable though!') + self.logger.warning('WARNING! Cannot add any more relocations to this file. Probably TLS Callback execution technique wont work.') + self.logger.warning(' Will try disabling relocations on output file. Expect corrupted executable though!') self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0 self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0 @@ -269,7 +269,7 @@ class SuperPe(): if self.pe.DIRECTORY_ENTRY_EXPORT.symbols == 0: return [] except Exception as e: - logger.warn("get_exports_full(): No exports found in PE") + logger.debug("get_exports_full(): No exports found in PE") return [] res = [] for e in self.pe.DIRECTORY_ENTRY_EXPORT.symbols: diff --git a/phases/injector.py b/phases/injector.py index 3f73615..a34f5cd 100644 --- a/phases/injector.py +++ b/phases/injector.py @@ -60,13 +60,13 @@ def inject_exe(main_shc: bytes, settings: Settings, carrier: Carrier): # Special case: DLL exported function direct overwrite if superpe.is_dll() and settings.dllfunc != "" and carrier_invoke_style == CarrierInvokeStyle.ChangeEntryPoint: - logger.warn("---[ Inject DLL: Overwrite exported function {} with shellcode".format(settings.dllfunc)) + logger.warning("---[ Inject DLL: Overwrite exported function {} with shellcode".format(settings.dllfunc)) rva = superpe.getExportEntryPoint(settings.dllfunc) # Size and sanity checks function_size = superpe.get_size_of_exported_function(settings.dllfunc) if shellcode_len >= function_size: - logger.warn("Shellcode larger than function: {} > {} exported function {}".format( + logger.warning("Shellcode larger than function: {} > {} exported function {}".format( shellcode_len, function_size, settings.dllfunc ))