Linux - 内核破坏内核空间只读做到修改系统调用表完成拦截系统调用
本篇文章的目的是为了修改系统调用表,而不是修改指令做什么inline hook,这里浅浅提一下,在arm64安卓平台,在内核的inline hook可以通过aarch64_insn_write
实现,当然这个方法是不导出的需要使用kprobe去获取!
PS:
aarch64_insn_write
是一个用于在 AArch64架构(ARM 64位架构)中向指定内存地址写入机器指令(instruction)的低级函数。它通常出现在操作系统内核、虚拟机监控程序(Hypervisor)或其他需要直接操作机器指令的底层代码中。他还有两个兄弟,一个是aarch64_insn_read
:从内存中读取指令。还有一个是aarch64_insn_patch_text
:内核中更高级的指令修改接口,封装了权限检查和缓存刷新。#include <asm/insn.h> void patch_instruction(unsigned long addr, u32 new_insn) { // 修改内存权限为可写 set_memory_rw(addr & PAGE_MASK, 1); // 写入新指令 aarch64_insn_write((void *)addr, new_insn); // 刷新指令缓存 flush_icache_range(addr, addr + 4); // 不导出! // 恢复内存权限(可选) set_memory_ro(addr & PAGE_MASK, 1); }
详细请看项目:点我前往
系统调用表是只读的,正常情况下没办法修改,其中x86的那个破坏内核只读的方法烂大街了,对我们arm64的安卓设备没什么鸟用,大部分操作都会导致手机死机,然后丢失数据!其实我们还可以用kprobe
去hook系统调用,但是很奇怪啊,我的一加13这样玩会死机,别人又说不会死机,真奇怪!
最开始不知名的臭傻逼|我认识的人叫我用下面的这个方法
#include <linux/mm.h>
int modify_page_permissions(unsigned long addr) {
return set_memory_rw(addr, 1); // 需 CONFIG_STRICT_KERNEL_RWX 未启用
}
喜提死机啊,后面在github寻寻溺溺找到一个这个
// 将内核代码段的某页改为可写
update_mapping_prot(__pa_symbol(_text), PAGE_SIZE, PAGE_KERNEL);
巧了,这玩意也趋势了,直接死机!可是我看arm64的linux源代码就用的这个玩意,为什么我的会爆炸呢?望有大佬解惑!
当然你们也知道这玩意需要地址必须是通过 vmalloc
或 module_alloc
分配的,但是呢我看见别人的rootkit在pages里面给要改的page加了个VMALLOC的flag直接绕过了,hhh,((但是没什么用,调用就死机了,呜呜呜,你看他的源代码,他也flush了哎?
static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
phys_addr_t size, pgprot_t prot)
{
if (virt < PAGE_OFFSET) {
pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n",
&phys, virt);
return;
}
__create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL,
NO_CONT_MAPPINGS);
/* flush the TLBs after updating live kernel mappings */
flush_tlb_kernel_range(virt, virt + size);
}
最终解决方案
看我那个项目的源代码就好了((((