shithub: drawcpu

ref: 07665995b1973c612a8874badec060114393fa4d
dir: /posix-arm64/trampoline.c/

View raw version
#include <u.h>
#include <libc.h>
#include "mem.h"

void asm_syscall_hook(void)
{
	print("In hook somehow\n");
	__asm__ __volatile__ (
		"asm_syscall_hook:\r\n"
    	"stp x29, x30, [sp, #-16]!\r\n"  // Save frame pointer and link register
    	"mov x29, sp\r\n"                // Set up frame pointer
    	"sub sp, sp, #32\r\n"            // Allocate 32 bytes on stack
    	"stp x8, x0, [sp, #16]\r\n"      // Save x8 (syscall number) and x0
    	"stp x1, x2, [sp]\r\n"           // Save x1 and x2
    	"mov x1, x0\r\n"                 // Shift arguments: x0 -> x1
    	"mov x2, x1\r\n"                 // x1 -> x2
    	"mov x3, x2\r\n"                 // x2 -> x3
    	"mov x4, x3\r\n"                 // x3 -> x4
    	"mov x5, x4\r\n"                 // x4 -> x5
    	"mov x6, x5\r\n"                 // x5 -> x6
    	"mov x0, x8\r\n"                 // Move syscall number to x0
    	"bl _sysintercept\r\n"           // Call syscall function
    	"ldp x1, x2, [sp]\r\n"           // Restore original x1 and x2
    	"ldp x8, x3, [sp, #16]\r\n"      // Restore original x8 and load original x0 into x3
    	"mov x1, x3\r\n"                 // Restore original x0 to x1 (new x0 is return value)
    	"ldp x29, x30, [sp], #48\r\n"    // Restore frame pointer and link register, and deallocate stack
    	"ret\r\n"
	);
}

/**
 * based on https://github.com/yasukata/zpoline/blob/master/main.c
 * This will add NOP into the first 53 sections of text
 * When a syscall is patched, it will instead jump here
 * From the NOP slide, it then calls into asm_syscall_hook which in turn calls sysintercept
 */
void
trampoline(void *text)
{
	void *hook_address = (void*)&asm_syscall_hook;
    uint8_t code[] = {
        // 53 nop instructions to catch the 9 syscalls (0xd503201f each)
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5, 0x1f, 0x20, 0x03, 0xd5,
        0x1f, 0x20, 0x03, 0xd5,
        // Main code
        0xff, 0x43, 0x00, 0xd1,  // sub sp, sp, #0x80
        0x00, 0x00, 0x00, 0x90,  // adrp x11, 0 (placeholder)
        0x0b, 0x00, 0x00, 0x91,  // add x11, x11, :lo12:0 (placeholder)
        0x60, 0x01, 0x3f, 0xd6   // br x11
    };

    // Calculate the relative address for adrp
    uintptr_t adrp_offset = ((uintptr_t)hook_address >> 12) & 0x7FFFF;
    code[216] |= (adrp_offset & 0xFF);
    code[217] |= ((adrp_offset >> 8) & 0x7F) << 1;

    // Set the low 12 bits for add
    uintptr_t add_offset = (uintptr_t)hook_address & 0xFFF;
    code[220] |= (add_offset & 0xFF);
    code[221] |= (add_offset >> 8) << 2;

	memcpy(text, code, sizeof(code));
}