Skip to content

Debug code injection

Zorg edited this page Nov 20, 2022 · 6 revisions

Code Injection

  • debug.bytesBeforeInjection(sourceAddress, destinationAddress)

Returns a buffer of bytes from sourceAddress that will be overridden if you plan to later call debug.injectCode with both sourceAddress and destinationAddress. sourceAddress should be a memory address pointing to the instruction you'd like to create a hook to inject into, and destinationAddress should be pointing to where the you want the new code to be inserted.

Raises bitslicer.DebuggerError if the call fails.

For Apple Silicon, this API is supported on native (non-Rosetta) targets on Bit Slicer 1.7.12 and later. On Intel Macs, this API is supported everywhere.


  • debug.injectCode(sourceAddress, destinationAddress, codeBuffer)

Creates a hook that starts at sourceAddress and jumps to destinationAddress. At destinationAddress, a new codeBuffer is written to plus a jump back to the program's normal execution (an instruction following after sourceAddress). The instructions at sourceAddress are not preserved; if you want to preserve them, use debug.bytesBeforeInjection. If you want to insert them into the new code, concatenate the original buffer to your new code and pass it into codeBuffer. destinationAddress should most likely be retrieved by using vm.allocate. codeBuffer can be created by using debug.assemble.

Raises bitslicer.DebuggerError if unable to inject code or BufferError if buffer length is 0 or non-contiguous.

For Apple Silicon, this API is supported on native (non-Rosetta) targets on Bit Slicer 1.7.12 and later. On Intel Macs, this API is supported everywhere.

Example:

#Inject Useless Code!
import bitslicer

ADDRESS_TO_HOOK_INTO = 0x41E3 #pointing to some instruction in memory

class Script(object):
    def __init__(self):
        self.destinationAddress = vm.allocate()
        self.originalBytes = debug.bytesBeforeInjection(ADDRESS_TO_HOOK_INTO, self.destinationAddress)
        debug.injectCode(ADDRESS_TO_HOOK_INTO, self.destinationAddress, self.originalBytes + debug.assemble('nop'))
    def finish(self):
        debug.writeBytes(ADDRESS_TO_HOOK_INTO, self.originalBytes)
        vm.deallocate(self.destinationAddress)

Another Example:

#Inject our code
from bitslicer import VirtualMemoryError, DebuggerError

class Script(object):
    def __init__(self):
        ADDRESS_TO_HOOK_INTO = vm.base() + 0x969FA #pointing to some instruction in memory
        self.destinationAddress = vm.allocate()
        self.originalBytes = debug.bytesBeforeInjection(ADDRESS_TO_HOOK_INTO, self.destinationAddress)
        debug.injectCode(ADDRESS_TO_HOOK_INTO, self.destinationAddress, self.originalBytes + debug.assemble("\n".join(['add edx, 0x1','mov [ecx+0x18],edx','mov edx, [ecx+0x8]'])))
    def finish(self):
        debug.writeBytes(ADDRESS_TO_HOOK_INTO, self.originalBytes)
        vm.deallocate(self.destinationAddress)