问题描述
我正在尝试开发一个挂钩系统调用的内核模块。我正在运行RaspBerry Buster Linux 4.19.97-v7 + armv7l的RaspBerry Pi 3B上进行测试。
因此,通常在x86上,我们可以覆盖CR0寄存器,但是在ARM体系结构上没有类似的寄存器。我尝试通过set_memory_rw进行操作,然后启用它,然后退出使用set_memory_ro,就像在Cannot use set_memory_rw in Linux kernel on ARM64上对类似问题的一个答案 但这不起作用。
我的代码:
up down left right up down left right
[0,0] NaN NaN NaN NaN Nan NaN NaN NaN
[0,40] NaN NaN NaN NaN NaN NaN NaN NaN
[0,80] NaN NaN NaN NaN NaN NaN NaN NaN
[0,120] NaN NaN NaN NaN NaN NaN NaN NaN
[0,160] NaN NaN NaN NaN NaN NaN NaN NaN
.......
Dmesg跟踪错误如下
// SPDX-License-Identifier: GPL-3.0
#include <linux/init.h> // module_{init,exit}()
#include <linux/module.h> // THIS_MODULE,MODULE_VERSION,...
#include <linux/kernel.h> // printk(),pr_*()
#include <linux/kallsyms.h> // kallsyms_lookup_name()
#include <asm/syscall.h> // syscall_fn_t,__NR_*
#include <asm/ptrace.h> // struct pt_regs
#include <asm/tlbflush.h> // flush_tlb_kernel_range()
#include <asm/pgtable.h> // {clear,set}_pte_bit(),set_pte()
#include <linux/vmalloc.h> // vm_unmap_aliases()
#include <linux/mm.h> // struct mm_struct,apply_to_page_range()
#include <linux/kconfig.h> // IS_ENABLED()
#ifdef pr_fmt
#undef pr_fmt
#endif
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
static struct mm_struct *init_mm_ptr;
static void* *syscall_table;
#define MAGIC "mamaliga"
#define SIZEOF_MAGIC 8
#define ROOTKIT_SYS_CALL_TABLE 0x801011c4
int pos;
// static void* original_read;
asmlinkage long (*original_read)(unsigned int fd,char __user *buf,size_t count);
/********** HELPERS **********/
// From arch/arm/mm/pageattr.c.
struct page_change_data {
pgprot_t set_mask;
pgprot_t clear_mask;
};
static int change_page_range(pte_t *ptep,pgtable_t token,unsigned long addr,void *data)
{
struct page_change_data *cdata = data;
pte_t pte = *ptep;
pte = clear_pte_bit(pte,cdata->clear_mask);
pte = set_pte_bit(pte,cdata->set_mask);
set_pte_ext(ptep,pte,0);
return 0;
}
void (*flush)(unsigned long start,unsigned long end);
// From arch/arm64/mm/pageattr.c.
static int __change_memory_common(unsigned long start,unsigned long size,pgprot_t set_mask,pgprot_t clear_mask)
{
struct page_change_data data;
int ret;
data.set_mask = set_mask;
data.clear_mask = clear_mask;
ret = apply_to_page_range(init_mm_ptr,start,size,change_page_range,&data);
flush = (void*)kallsyms_lookup_name("flush_tlb_kernel_range");
flush(start,start + size);
return ret;
}
// Simplified set_memory_rw() from arch/arm/mm/pageattr.c.
static int set_page_rw(unsigned long addr)
{
vm_unmap_aliases();
return __change_memory_common(addr,PAGE_SIZE,__pgprot(0),__pgprot(L_PTE_RDONLY));
}
// Simplified set_memory_ro() from arch/arm/mm/pageattr.c.
static int set_page_ro(unsigned long addr)
{
vm_unmap_aliases();
return __change_memory_common(addr,__pgprot(L_PTE_RDONLY),__pgprot(0));
}
/********** ACTUAL MODULE **********/
asmlinkage long myread(unsigned int fd,size_t count)
{
long ret;
/* Call original read_syscall */
ret = original_read(fd,buf,count);
pr_info("Hooked!\n");
return ret;
}
static int __init modinit(void)
{
int res;
pr_info("init\n");
// Shouldn't fail.
init_mm_ptr = (struct mm_struct *)kallsyms_lookup_name("init_mm");
syscall_table = (void* *)kallsyms_lookup_name("sys_call_table");
printk(KERN_INFO "syscall_table: 0xx%llx\n",syscall_table);
original_read = syscall_table[__NR_read];
res = set_page_rw(((unsigned long)syscall_table + __NR_read) & PAGE_MASK);
if (res != 0) {
pr_err("set_page_rw() Failed: %d\n",res);
return res;
}
else {
pr_info("set_page_rw() OK");
}
syscall_table[__NR_read] = myread;
res = set_page_ro(((unsigned long)syscall_table + __NR_read) & PAGE_MASK);
if (res != 0) {
pr_err("set_page_ro() Failed: %d\n",res);
return res;
}
else {
pr_info("set_page_ro() OK");
}
pr_info("init done\n");
return 0;
}
static void __exit modexit(void)
{
int res;
pr_info("exit\n");
res = set_page_rw(((unsigned long)syscall_table + __NR_read) & PAGE_MASK);
if (res != 0) {
pr_err("set_page_rw() Failed: %d\n",res);
return;
}
syscall_table[__NR_read] = original_read;
res = set_page_ro(((unsigned long)syscall_table + __NR_read) & PAGE_MASK);
if (res != 0)
pr_err("set_page_ro() Failed: %d\n",res);
pr_info("goodbye\n");
}
module_init(modinit);
module_exit(modexit);
MODULE_VERSION("0.1");
MODULE_DESCRIPTION("Syscall hijack on arm64.");
MODULE_AUTHOR("marco Bonelli");
MODULE_LICENSE("GPL");
我还尝试了ARM64 - Linux Memory Write protection won't disable的其他一些建议,这些建议通过使用Linux内核功能通过相应的PTE禁用了对虚拟地址的内存写保护。它也不起作用。
[ 89.767769] interceptor: loading out-of-tree module taints kernel.
[ 89.771442] interceptor: init
[ 89.806435] syscall_table: 0xx75c5dda175c5dda1
[ 89.812886] interceptor: set_page_rw() OK
[ 89.812898] Unable to handle kernel paging request at virtual address 801011d0
[ 89.822616] pgd = c9de9ec3
[ 89.826529] [801011d0] *pgd=0001141e(bad)
[ 89.831760] Internal error: Oops: 80d [#1] SMP ARM
[ 89.837763] Modules linked in: interceptor(O+) cmac bnep hci_uart btbcm serdev bluetooth ecdh_generic binfmt_misc evdev brcmfmac brcmutil sha256_generic cfg80211 raspBerrypi_hwmon rfkill hwmon bcm2835_codec(C) bcm2835_v4l2(C) snd_bcm2835(C) v4l2_mem2mem snd_pcm bcm2835_mmal_vchiq(C) v4l2_common videobuf2_dma_contig snd_timer videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_common snd videodev media vc_sm_cma(C) fixed uio_pdrv_genirq uio ip_tables x_tables ipv6
[ 89.887532] cpu: 1 PID: 981 Comm: insmod Tainted: G C O 4.19.97-v7+ #1293
[ 89.898046] Hardware name: BCM2835
[ 89.902693] PC is at modinit+0xb0/0x1000 [interceptor]
[ 89.909084] LR is at (null)
[ 89.913214] pc : [<7f7430b0>] lr : [<00000000>] psr: 60000013
[ 89.920704] sp : b20e5d80 ip : 80d0517c fp : b20e5d9c
[ 89.927176] r10: b5ab3340 r9 : 00000002 r8 : b5ab3300
[ 89.933650] r7 : 00000000 r6 : fffff000 r5 : 00000000 r4 : 801011c4
[ 89.941469] r3 : 7f73e068 r2 : 75c5dda1 r1 : 00000000 r0 : 0000001d
[ 89.949256] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
[ 89.957653] Control: 10c5383d Table: 320ec06a DAC: 00000055
[ 89.964666] Process insmod (pid: 981,stack limit = 0x322dc319)
[ 89.971873] Stack: (0xb20e5d80 to 0xb20e6000)
[ 89.977495] 5d80: 7f740000 7f743000 80d04d48 00000000 b20e5e14 b20e5da0 8010312c 7f74300c
[ 89.988192] 5da0: 802821d4 8085dffc 00000000 006000c0 b20e5dcc b20e5dc0 8085dffc 802ba274
[ 89.998889] 5dc0: b20e5e14 b20e5dd0 802ba274 802c7118 802bb6cc 802bab54 00000001 00003c76
[ 90.009578] 5de0: 00000000 a0000013 bccc8000 75c5dda1 7f740000 7f740000 7f740000 b7c04880
[ 90.020281] 5e00: 80d04d48 b5ab3300 b20e5e3c b20e5e18 801ba19c 801030e8 b20e5e3c b20e5e28
[ 90.031099] 5e20: 802a8250 b20e5f30 7f740000 00000002 b20e5f0c b20e5e40 801b9114 801ba134
[ 90.042029] 5e40: 7f74000c 00007fff 7f740000 801b6100 00000000 80ae4f00 7f7401fc 7f740114
[ 90.053063] 5e60: 7f740130 00000000 b5ab3308 7f740048 b20e5e94 80afd2d0 802d061c 802d0488
[ 90.064243] 5e80: b20e5ea0 b21029c0 00000000 00000000 00000000 00000000 00000000 00000000
[ 90.075471] 5ea0: 6e72656b 00006c65 00000000 00000000 00000000 00000000 00000000 00000000
[ 90.086778] 5ec0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 75c5dda1
[ 90.098119] 5ee0: 7fffffff 80d04d48 00000000 00000003 0002d064 7fffffff 00000000 0000017b
[ 90.109451] 5f00: b20e5fa4 b20e5f10 801b9974 801b7360 7fffffff 00000000 00000003 00000000
[ 90.120790] 5f20: 00000000 bccc8000 0000209c 00000000 bccc84e2 bccc89c0 bccc8000 0000209c
[ 90.132121] 5f40: bccc9a5c bccc98a8 bccc92a0 00003000 000032c0 00000000 00000000 00000000
[ 90.143457] 5f60: 000018d8 00000025 00000026 0000001d 0000001b 00000017 00000000 75c5dda1
[ 90.154784] 5f80: 010d6c00 7e9317d4 0003fce8 0000017b 801011c4 b20e4000 00000000 b20e5fa8
[ 90.166119] 5fa0: 80101000 801b98c4 010d6c00 7e9317d4 00000003 0002d064 00000000 00000004
[ 90.177457] 5fc0: 010d6c00 7e9317d4 0003fce8 0000017b 01355818 00000000 00000002 00000000
[ 90.188783] 5fe0: 7e931608 7e9315f8 00022cb8 76cadaf0 60000010 00000003 00000000 00000000
[ 90.200155] [<7f7430b0>] (modinit [interceptor]) from [<8010312c>] (do_one_initcall+0x50/0x218)
[ 90.212033] [<8010312c>] (do_one_initcall) from [<801ba19c>] (do_init_module+0x74/0x220)
[ 90.223280] [<801ba19c>] (do_init_module) from [<801b9114>] (load_module+0x1dc0/0x2404)
[ 90.234455] [<801b9114>] (load_module) from [<801b9974>] (sys_finit_module+0xbc/0xcc)
[ 90.245459] [<801b9974>] (sys_finit_module) from [<80101000>] (ret_fast_syscall+0x0/0x28)
[ 90.256813] Exception stack(0xb20e5fa8 to 0xb20e5ff0)
[ 90.263464] 5fa0: 010d6c00 7e9317d4 00000003 0002d064 00000000 00000004
[ 90.274748] 5fc0: 010d6c00 7e9317d4 0003fce8 0000017b 01355818 00000000 00000002 00000000
[ 90.286023] 5fe0: 7e931608 7e9315f8 00022cb8 76cadaf0
[ 90.292627] Code: eb28f040 e594400c e30e3068 e3473f73 (e584300c)
[ 90.300277] ---[ end trace 9daed852fe9a568f ]---
此刻我真的很卡住,您的建议将不胜感激!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)