Created
September 3, 2014 19:55
-
-
Save Cr4sh/fe910f0d1b0559efd43d to your computer and use it in GitHub Desktop.
Revisions
-
Cr4sh created this gist
Sep 3, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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; }