mirror of
https://github.com/dobin/SuperMega
synced 2026-06-03 01:27:11 +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 capstone
|
||||||
import keystone
|
import keystone
|
||||||
import logging
|
import logging
|
||||||
|
from intervaltree import *
|
||||||
|
|
||||||
from utils import hexdump
|
from utils import hexdump
|
||||||
from pe.superpe import SuperPe
|
from pe.superpe import SuperPe
|
||||||
from model.defs import *
|
from model.defs import *
|
||||||
from intervaltree import *
|
from pe.pehelper import assemble_relative_call, assemble_relative_jmp
|
||||||
|
|
||||||
logger = logging.getLogger("DerBackdoorer")
|
logger = logging.getLogger("DerBackdoorer")
|
||||||
|
|
||||||
|
|
||||||
@@ -40,10 +42,11 @@ class FunctionBackdoorer:
|
|||||||
if addr is None:
|
if addr is None:
|
||||||
raise Exception("Couldn't find a suitable instruction to backdoor")
|
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(
|
logger.info("--[ Backdoor 0x{:X}: {}".format(
|
||||||
addr, text_trampoline))
|
addr, compiled_trampoline.hex()))
|
||||||
|
|
||||||
|
# Check for overlap
|
||||||
it = IntervalTree()
|
it = IntervalTree()
|
||||||
it.addi(addr, addr+len(compiled_trampoline))
|
it.addi(addr, addr+len(compiled_trampoline))
|
||||||
if it.overlap(shellcode_addr, shellcode_addr+shellcode_len):
|
if it.overlap(shellcode_addr, shellcode_addr+shellcode_len):
|
||||||
@@ -55,13 +58,6 @@ class FunctionBackdoorer:
|
|||||||
# write
|
# write
|
||||||
self.superpe.pe.set_bytes_at_rva(addr, bytes(compiled_trampoline))
|
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):
|
def find_suitable_instruction_addr(self, startOffset, length=256):
|
||||||
"""Find a instruction to backdoor. Recursively."""
|
"""Find a instruction to backdoor. Recursively."""
|
||||||
|
|||||||
+10
-4
@@ -77,10 +77,8 @@ def assemble_lea(current_address: int, destination_address: int, reg: str) -> by
|
|||||||
machine_code = bytes(encoding)
|
machine_code = bytes(encoding)
|
||||||
return machine_code
|
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(
|
def assemble_relative_call(current_address: int, destination_address: int) -> bytes:
|
||||||
# current_address, destination_address
|
|
||||||
#))
|
|
||||||
# Calculate the relative offset
|
# Calculate the relative offset
|
||||||
# For a near jump, the instruction length is typically 5 bytes (E9 xx xx xx xx)
|
# For a near jump, the instruction length is typically 5 bytes (E9 xx xx xx xx)
|
||||||
offset = destination_address - current_address
|
offset = destination_address - current_address
|
||||||
@@ -98,6 +96,14 @@ def assemble_and_disassemble_jump(current_address: int, destination_address: int
|
|||||||
return machine_code
|
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
|
## Utils
|
||||||
|
|
||||||
def remove_trailing_null_bytes(data: bytes) -> bytes:
|
def remove_trailing_null_bytes(data: bytes) -> bytes:
|
||||||
|
|||||||
+2
-2
@@ -139,10 +139,10 @@ def injected_fix_iat(superpe: SuperPe, carrier: Carrier, exe_host: ExeHost):
|
|||||||
|
|
||||||
offset_from_code = code.index(iatRequest.placeholder)
|
offset_from_code = code.index(iatRequest.placeholder)
|
||||||
instruction_virtual_address = offset_from_code + exe_host.image_base + exe_host.code_section.VirtualAddress
|
instruction_virtual_address = offset_from_code + exe_host.image_base + exe_host.code_section.VirtualAddress
|
||||||
logger.info(" Replace {} at VA 0x{:X} with call to IAT at VA 0x{:X}".format(
|
logger.info(" Replace {} at VA 0x{:X} with: call to IAT at VA 0x{:X}".format(
|
||||||
iatRequest.placeholder.hex(), instruction_virtual_address, destination_virtual_address
|
iatRequest.placeholder.hex(), instruction_virtual_address, destination_virtual_address
|
||||||
))
|
))
|
||||||
jmp = assemble_and_disassemble_jump(
|
jmp = assemble_relative_call(
|
||||||
instruction_virtual_address, destination_virtual_address
|
instruction_virtual_address, destination_virtual_address
|
||||||
)
|
)
|
||||||
code = code.replace(iatRequest.placeholder, jmp)
|
code = code.replace(iatRequest.placeholder, jmp)
|
||||||
|
|||||||
Reference in New Issue
Block a user