Skip to content

Instantly share code, notes, and snippets.

@Cr4sh
Created September 3, 2014 19:55
Show Gist options
  • Select an option

  • Save Cr4sh/fe910f0d1b0559efd43d to your computer and use it in GitHub Desktop.

Select an option

Save Cr4sh/fe910f0d1b0559efd43d to your computer and use it in GitHub Desktop.

Revisions

  1. Cr4sh created this gist Sep 3, 2014.
    56 changes: 56 additions & 0 deletions gistfile1.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,56 @@
    void **find_sys_call_table(void *kernel_addr, int kernel_size)
    {
    /*
    Check for the system_call_fastpath() signature, hand-written piece of
    assembly code from arch/x86/kernel/entry_64.S:
    ja badsys
    mov rcx, r10
    call sys_call_table[rax * 8]
    mov [rsp + 20h], rax
    ret_from_sys_call:
    mov edi, 1000FEFFh
    This instructions are unchanged for the last 7 years (and maybe even more, haven't
    older kernels on my test machines), so, looks reliable enough.
    */
    unsigned char *mask = "\xff\xff\x00\x00\x00\x00"
    "\xff\xff\xff"
    "\xff\xff\xff\x00\x00\x00\x00"
    "\xff\xff\xff\xff\xff"
    "\xff\xff\xff\xff\xff";

    unsigned char *sign = "\x0f\x87\x00\x00\x00\x00"
    "\x4c\x89\xd1"
    "\xff\x14\xc5\x00\x00\x00\x00"
    "\x48\x89\x44\x24\x20"
    "\xbf\xff\xfe\x00\x10";

    int i = 0, n = 0, sign_len = 26;

    for (i = 0; i < kernel_size; i += 1)
    {
    unsigned char *p = (unsigned char *)kernel_addr + i;
    char matched = 1;

    for (n = 0; n < sign_len; n += 1)
    {
    // match signature byte
    if ((*(p + n) & mask[n]) != sign[n])
    {
    matched = 0;
    break;
    }
    }

    if (matched > 0)
    {
    // get sys_call_table address
    return (void **)(((unsigned long long)kernel_addr & 0xffffffff00000000) + *(unsigned long *)(p + 0x0c));
    }
    }

    return NULL;
    }