Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
内核模块内存写入导致Android内核中的内核OOP_Android_C_Memory_Linux Kernel_Panic - Fatal编程技术网

内核模块内存写入导致Android内核中的内核OOP

内核模块内存写入导致Android内核中的内核OOP,android,c,memory,linux-kernel,panic,Android,C,Memory,Linux Kernel,Panic,我目前正试图调试股票android内核,但我遇到了一些问题,我需要帮助。我有内核的源代码,但我不想重建内核并将其闪存到手机中,我只希望对手机中现有的股票内核进行调试。Kprobes是在股票内核中启用的(我通过查看/proc/kallsyms中的符号列表确认了这一点) 首先,我尝试编译自己的内核模块来操作内核内存。我可以通过将物理地址映射到虚拟地址,然后将其分配给指针来读取内存,如下所示: unsigned char *my_ptr; my_ptr = (unsigned char *)phys_

我目前正试图调试股票android内核,但我遇到了一些问题,我需要帮助。我有内核的源代码,但我不想重建内核并将其闪存到手机中,我只希望对手机中现有的股票内核进行调试。Kprobes是在股票内核中启用的(我通过查看/proc/kallsyms中的符号列表确认了这一点)

首先,我尝试编译自己的内核模块来操作内核内存。我可以通过将物理地址映射到虚拟地址,然后将其分配给指针来读取内存,如下所示:

unsigned char *my_ptr;
my_ptr = (unsigned char *)phys_to_virt((unsigned long)0x001C1D50);
printk(KERN_INFO "%02X", *my_ptr);
static struct kprobe kp = {
    .symbol_name    = "do_fork",
    .pre_handler = handler_pre,
    .post_handler = handler_post,
    .fault_handler = handler_fault,
};

static int __init kprobe_init(void)
{
    int ret;    
    ret = register_kprobe(&kp);
    if (ret < 0) {
        printk(KERN_INFO "register_kprobe failed, returned %d\n", ret);
        return ret;
    }
    printk(KERN_INFO "Planted kprobe at %p\n", kp.addr);
    return 0;
}
但是当我尝试使用以下命令写入内存时:
my_ptr[0]=0,内核进入死机(oops)状态,然后重新启动手机。从/proc/last_kmsg,我得到以下日志:

<3>[  149.720085] RKP -> Inst bf3db69c out of cpu_v7_set_pte_ext range from c01159c4 to c0115a1c
<1>[  149.720233] Unable to handle kernel paging request at virtual address c01c1d50
<1>[  149.720355] pgd = eb760000
<1>[  149.720419] [c01c1d50] *pgd=0da00011
<0>[  149.720658] Internal error: Oops: 80f [#1] PREEMPT SMP ARM
<4>[  149.720749] Modules linked in: t_mod(O) wlan(PO) mhi(O)
<4>[  149.720889] CPU: 0 PID: 5561 Comm: tmp-mksh Tainted: P        W  O 3.10.0-2413392 #1
<4>[  149.721007] task: eba75400 ti: eb01a000 task.ti: eb01a000
<4>[  149.721118] PC is at my_write+0x230/0x300 [t_mod]
<4>[  149.721216] LR is at _kstrtoull+0x28/0x74
<4>[  149.721298] pc : [<bf3db69c>]    lr : [<c03cbf4c>]    psr: 60010013
<4>[  149.721298] sp : eb01be78  ip : 0000003f  fp : 00000000
<4>[  149.721464] r10: 00000000  r9 : eb01a000  r8 : bf3dd270
<4>[  149.721550] r7 : 00000005  r6 : 00000008  r5 : eb01be7c  r4 : eb01be86
<4>[  149.721650] r3 : c01c1d48  r2 : 00000002  r1 : 00000000  r0 : 00000000
<4>[  149.721754] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
<4>[  149.721863] Control: 10c5787d  Table: 2b76006a  DAC: 00000015
<4>[  149.721954] 
<4>[  149.721954] LR: 0xc03cbecc:
<4>[  149.722038] becc  e00b3001 e1921003 0a000007 e3a01000 e1a04007 e1e00008 e1e01001 ebffbc2c
<4>[  149.722235] beec  e153000b 0152000a 33a06001 e083279a e2855001 e0233b97 e092a008 e2a3b000
<4>[  149.722439] bf0c  e7d93005 e3530000 1affffd8 eaffffde e1a00005 e8bd8ffe e92d407f e28d3010
<4>[  149.722641] bf2c  e1a06002 e523100c e1a01003 ebffffa6 e59d1004 e28d2008 e1a04000 ebffffc2
<4>[  149.722842] bf4c  e3500000 ba00000b e3d00102 0a00000b e7d42000 e0843000 e352000a 02833001
<4>[  149.723043] bf6c  e5d30000 e3500000 1a000004 e1cd40d8 e1c640f0 ea000002 e3e00021 ea000000
<4>[  149.723244] bf8c  e3e00015 e28dd010 e8bd8070 e5d03000 e353002b 02800001 eaffffde e92d4070
<4>[  149.723444] bfac  e1a06003 e59f30bc e24dd048 e1a0e000 e3510042 31a04001 23a04042 e1a05002
<4>[  149.723650] 
<4>[  149.723650] SP: 0xeb01bdf8:
<4>[  149.723745] bdf8  00000000 ed77d74c eb01be86 eb01be38 eb01be38 eb01be86 eb01be7c eb01be50
<4>[  149.723947] be18  bf3db69c 60010013 ffffffff eb01be64 bf3dd270 c0abd1d8 00000000 00000000
<4>[  149.724147] be38  00000002 c01c1d48 eb01be86 eb01be7c 00000008 00000005 bf3dd270 eb01a000
<4>[  149.724344] be58  00000000 00000000 0000003f eb01be78 c03cbf4c bf3db69c 60010013 ffffffff
<4>[  149.724526] be78  00000000 eb01be89 00000002 3230ea28 20303000 31203030 e82b0041 eb01a000
<4>[  149.724707] be98  00000800 00000000 c1219210 c024cfa4 eb01bebc e82ba000 00000002 eb7b7270
<4>[  149.724888] beb8  6400742d 00000000 ea277e50 e8e7a7f8 ed77d74c c0192094 eba75400 eb01bf78
<4>[  149.725069] bed8  00000001 e82ba000 ffffff9c c0106344 c036f940 00000002 e958e180 b85b0ab4
<4>[  149.725255] 
<4>[  149.725255] R3: 0xc01c1cc8:
<4>[  149.725339] 1cc8  e1a03007 e58db010 eb23c055 e3a01001 e5960008 eb0cee18 ebfd4d09 e1a01005
<4>[  149.725523] 1ce8  e58d7000 e1a02007 e1a0300b e5960008 eb0cf40e e1a05000 e1a01004 e5960008
<4>[  149.725706] 1d08  eb0cee0d e3550000 0a00000c e1a01005 e59f015c eb23c042 e59f0158 eb23c040
<4>[  149.725887] 1d28  e2860008 eb0cf52e e3500000 05864008 0a00003a e59f0140 eb23c039 ea000037
<4>[  149.726068] 1d48  e5981144 e3510000 00000000 e59f012c eb23c033 ea000032 e59f5124 e59f0124
<4>[  149.726251] 1d68  eb23c02f e30810d0 e3a02010 e5950018 eb01e34a e2506000 1a000003 e59f1108
<4>[  149.726451] 1d88  e59f0108 eb23c026 ea000024 e3a01010 e59f20fc e3e03000 eb081633 e5950020
<4>[  149.726651] 1da8  e30810d0 e3a02c01 e58d6020 eb01e33b e2505000 1a000004 e59f00d0 e59f10c8
<4>[  149.726857] 
<4>[  149.726857] R4: 0xeb01be06:
<4>[  149.726950] be04  eb01be38 eb01be38 eb01be86 eb01be7c eb01be50 bf3db69c 60010013 ffffffff
<4>[  149.727153] be24  eb01be64 bf3dd270 c0abd1d8 00000000 00000000 00000002 c01c1d48 eb01be86
<4>[  149.727353] be44  eb01be7c 00000008 00000005 bf3dd270 eb01a000 00000000 00000000 0000003f
<4>[  149.727552] be64  eb01be78 c03cbf4c bf3db69c 60010013 ffffffff 00000000 eb01be89 00000002
<4>[  149.727751] be84  3230ea28 20303000 31203030 e82b0041 eb01a000 00000800 00000000 c1219210
<4>[  149.727951] bea4  c024cfa4 eb01bebc e82ba000 00000002 eb7b7270 6400742d 00000000 ea277e50
<4>[  149.728151] bec4  e8e7a7f8 ed77d74c c0192094 eba75400 eb01bf78 00000001 e82ba000 ffffff9c
<4>[  149.728351] bee4  c0106344 c036f940 00000002 e958e180 b85b0ab4 eb01bf80 c03681d0 00000000
<4>[  149.728534] bf04  ef00e400 00000001 b85b0ab4 00000001 c0241a04 00000020 a8279bb7 eb05dcbc
<4>[  149.728719] 
<4>[  149.728719] R5: 0xeb01bdfc:
<4>[  149.728803] bdfc  ed77d74c eb01be86 eb01be38 eb01be38 eb01be86 eb01be7c eb01be50 bf3db69c
<4>[  149.728986] be1c  60010013 ffffffff eb01be64 bf3dd270 c0abd1d8 00000000 00000000 00000002
<4>[  149.729166] be3c  c01c1d48 eb01be86 eb01be7c 00000008 00000005 bf3dd270 eb01a000 00000000
<4>[  149.729347] be5c  00000000 0000003f eb01be78 c03cbf4c bf3db69c 60010013 ffffffff 00000000
<4>[  149.729528] be7c  eb01be89 00000002 3230ea28 20303000 31203030 e82b0041 eb01a000 00000800
<4>[  149.729710] be9c  00000000 c1219210 c024cfa4 eb01bebc e82ba000 00000002 eb7b7270 6400742d
<4>[  149.729891] bebc  00000000 ea277e50 e8e7a7f8 ed77d74c c0192094 eba75400 eb01bf78 00000001
<4>[  149.730072] bedc  e82ba000 ffffff9c c0106344 c036f940 00000002 e958e180 b85b0ab4 eb01bf80
<4>[  149.730256] 
<4>[  149.730256] R9: 0xeb019f80:
<4>[  149.730347] 9f80  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<4>[  149.730544] 9fa0  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<4>[  149.730742] 9fc0  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<4>[  149.730939] 9fe0  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<4>[  149.731136] a000  00000200 00000001 00000000 eba75400 c1240d78 00000000 00000015 eba75400
<4>[  149.731336] a020  c5151f00 eb01a000 c120df00 ed5fb500 00000000 ed2f1500 eb01be7c eb01bdf0
<4>[  149.731538] a040  c0abba1c 00000000 00000000 00000004 00000000 00000000 01010000 00000000
<4>[  149.731737] a060  b6f23f24 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<0>[  149.731944] Process tmp-mksh (pid: 5561, stack limit = 0xeb01a238)
<0>[  149.732053] Stack: (0xeb01be78 to 0xeb01c000)
<0>[  149.732145] be60:                                                       00000000 eb01be89
<0>[  149.732295] be80: 00000002 3230ea28 20303000 31203030 e82b0041 eb01a000 00000800 00000000
<0>[  149.732425] bea0: c1219210 c024cfa4 eb01bebc e82ba000 00000002 eb7b7270 6400742d 00000000
<0>[  149.732554] bec0: ea277e50 e8e7a7f8 ed77d74c c0192094 eba75400 eb01bf78 00000001 e82ba000
<0>[  149.732684] bee0: ffffff9c c0106344 c036f940 00000002 e958e180 b85b0ab4 eb01bf80 c03681d0
<0>[  149.732812] bf00: 00000000 ef00e400 00000001 b85b0ab4 00000001 c0241a04 00000020 a8279bb7
<0>[  149.732942] bf20: eb05dcbc eb05dc80 00000000 eb05dcbc 00000001 c0287c78 eb01bf80 e958e180
<0>[  149.733071] bf40: 00000005 b85b0ab4 eb01bf80 b85b0ab4 00000005 c0240328 e958e180 b85b0ab4
<0>[  149.733199] bf60: 00000005 00000000 00000000 e958e180 00000000 b85b0ab4 00000005 c0240680
<0>[  149.733325] bf80: 00000000 00000000 00000005 00000003 00000005 00000001 00000004 c0106344
<0>[  149.733454] bfa0: 00000200 c0106328 00000003 00000005 00000001 b85b0ab4 00000005 ffffffff
<0>[  149.733580] bfc0: 00000003 00000005 00000001 00000004 b85b0ab4 00000000 00000000 00000000
<0>[  149.733715] bfe0: 00000000 bef89528 b6f34d75 b6ed34ac 20010010 00000001 00000000 00000000
<4>[  149.733918] [<bf3db69c>] (my_write+0x230/0x300 [t_mod]) from [<c0287c78>] (proc_reg_write+0x60/0x90)
<4>[  149.734116] [<c0287c78>] (proc_reg_write+0x60/0x90) from [<c0240328>] (vfs_write+0xcc/0x174)
<4>[  149.734288] [<c0240328>] (vfs_write+0xcc/0x174) from [<c0240680>] (SyS_write+0x38/0x64)
<4>[  149.734457] [<c0240680>] (SyS_write+0x38/0x64) from [<c0106328>] (__sys_trace_return+0x0/0x18)
<0>[  149.734617] Code: e3a01010 eb3fc49f e5983004 e59d2008 (e7c32006) 
<4>[  149.738191] ---[ end trace dec6997083161644 ]---
<0>[  149.738295] Kernel panic - not syncing: Fatal exception

对此问题有何见解?

虚拟到物理映射由硬件控制。需要对硬件,特别是内存管理单元(MMU)进行编程,以了解虚拟到物理的映射是什么。此外,
phys\u to\u virt
没有使用MMU设置任何虚拟到物理映射。事实上,根据架构的不同,它只是进行一个简单的计算:

#define __phys_to_virt(x)       ((unsigned long)((x) - PHYS_OFFSET + PAGE_OFFSET))

static inline void *phys_to_virt(phys_addr_t x)
{
    return (void *)(__phys_to_virt(x));
}
这是从地图上截取的。我假设ARM64,因为我们谈论的是Android,但总体思路适用于x86和ARM32位

这个简单的偏移量计算是有效的,因为只有在内核映射中传递物理地址时,
phys\u to\u virt
才有效。摘自:

返回的虚拟地址是内存的当前CPU映射 地址。仅在以下地址上使用此函数有效: 有一个内核映射

此函数不处理DMA传输的总线映射。在里面 几乎所有可以想象的情况下,设备驱动程序都不应该使用此选项 作用

总之,您不能为物理地址传入任何随机值,而期望
phys\u to\u virt
工作

根据问题更新和评论进行更新:


如果您能够从内存位置读取,但不能写入,则很可能已使用MMU数据结构将其标记为只读。一些互联网搜索显示,有一些补丁和建议将ARM Linux内核的文本和只读部分设置为只读。

0x12345678是有效的物理地址吗?你从哪里得到这个地址的?内存保护是在硬件MMU(MPU)中实现的,但不是在Android系统中。。。实际上,只有当0x12345678属于内存的lowmem部分时,您所做的才是正确的。换句话说,你会得到你所拥有的。您想实现什么?抱歉,我使用0x12345678作为示例,我从/proc/kallsyms获取地址,并将其转换为物理地址。例如,如果它是0xc01c1d50,我需要从中减去0xc0008000,因为内核本身的起始偏移量为0x00008000,我将把它添加到结果中,因此它将是0x001C1D50。我可以读取地址,但写入地址会导致出现错误:无法处理虚拟地址c01c1d50处的内核分页请求。您的问题实际上是两个问题,让每篇文章都有一个问题是有益的。@csharpnewie为什么要从
proc/kallsyms
手动计算物理地址,然后使用
phys\u to\u virt
返回虚拟地址?还是我遗漏了什么?嗨,很抱歉我的帖子中出现了混乱,我编辑了它以使用一个合适的地址,我从/proc/kallsyms获得的地址,我做了一些计算以获得实际的物理地址。谢谢esm,但是我能问一下是否有任何方法绕过MMU数据结构所做的写保护?我试图按照原始帖子中的描述进行页面漫游,然后将获取的pte设置为启用写,但显然它没有按预期工作,内核仍然会死机并重新启动。@csharpnewie您最好的办法可能是问另一个问题,发布您已经尝试过的代码。如果我将代码作为另一个问题发布,这不算是双重邮寄吗?允许吗?
unsigned long my_addr = 0x1C1D50;
pgd = pgd_offset(mm, my_addr);
if (pgd_none(*pgd) || pgd_bad(*pgd))
    goto out;
prints("Valid pgd: [%08lx] *pgd=%08llx\n", my_addr, (long long)pgd_val(*pgd));

pud = pud_offset(pgd, my_addr);
if (pud_none(*pud) || pud_bad(*pud))
    goto out;
prints("Valid pud\n");

pmd = pmd_offset(pud, my_addr);
if (pmd_none(*pmd) || pmd_bad(*pmd))
    goto out;
prints("Valid pmd\n");

ptep = pte_offset_map(pmd, my_addr);
if (!ptep)
    goto out;
pte = *ptep;

page = pte_page(pte);
if (page)
    prints("page frame struct is @ %p\n", page);

if (pte_write(pte))
    prints("Pte is writable!\n");
else {
    prints("Pte is read-only!\n");
    pte = pte_mkwrite(pte);
    if (pte_write(pte)) {
        prints("Pte is now writable!\n");
        p[0] = 0x02;
        p[3] = 0x1A;
        pte = pte_wrprotect(pte);
    }
    else
        prints("Pte is still read-only!\n");
}
#define __phys_to_virt(x)       ((unsigned long)((x) - PHYS_OFFSET + PAGE_OFFSET))

static inline void *phys_to_virt(phys_addr_t x)
{
    return (void *)(__phys_to_virt(x));
}