Skip to content

Conversation

@Tr33NewBee
Copy link

之前没考虑到多个banner的场景,我重新分析了一下这个memmem的错误原因,发现是由于android的libc错误。你看下这个修改是不是可以,我测试了手机能正常解析和patch。

在崩溃前 记录下imgend ,banner的值

(lldb) p banner
(char *) $0 = 0xb400007d2a5c0d03 "Linux version %s (%s)"
(lldb) p img
(char *) $1 = 0xb400007d2876cff0 ""
(lldb) p imgend
(char *) $2 = 0xb400007d2ad57000 "" 
(lldb) p prefix_len
(size_t) $3 = 14
(lldb) n
Process 20431 stopped
* thread #1, name = 'kptools_android', stop reason = step over
    frame #0: 0x000000555555df8c kptools_android`find_linux_banner(info=0x0000007fffffeee8, img="", imglen=39755792) at kallsym.c:70:5
Target 0: (kptools_android) stopped.
(lldb) n
Process 20431 stopped
* thread #1, name = 'kptools_android', stop reason = step over
    frame #0: 0x000000555555ddf4 kptools_android`find_linux_banner(info=0x0000007fffffeee8, img="", imglen=39755792) at kallsym.c:72:23
Target 0: (kptools_android) stopped.
(lldb) n
Process 20431 stopped
* thread #1, name = 'kptools_android', stop reason = step over
    frame #0: 0x000000555555de04 kptools_android`find_linux_banner(info=0x0000007fffffeee8, img="", imglen=39755792) at kallsym.c:73:12
Target 0: (kptools_android) stopped.
(lldb) n
Process 20431 stopped
* thread #1, name = 'kptools_android', stop reason = step over
    frame #0: 0x000000555555de54 kptools_android`find_linux_banner(info=0x0000007fffffeee8, img="", imglen=39755792) at kallsym.c:77:9
Target 0: (kptools_android) stopped.
(lldb) n
[?] search size: 7955197 prefix_len: 14
Process 20431 stopped
* thread #1, name = 'kptools_android', stop reason = step over
    frame #0: 0x000000555555de8c kptools_android`find_linux_banner(info=0x0000007fffffeee8, img="", imglen=39755792) at kallsym.c:79:33
Target 0: (kptools_android) stopped.
(lldb) n
Process 20431 stopped
* thread #1, name = 'kptools_android', stop reason = signal SIGSEGV: address access protected (fault address: 0x7d2ad57000)
    frame #0: 0x0000007fbd4f8ca8 libc.so`twoway_memmem + 468
libc.so`twoway_memmem: =====================================》这里提示了崩溃
->  0x7fbd4f8ca8 <+468>: ldrb   w14, [x19, x9]。====》这里访问超过了内存错误
    0x7fbd4f8cac <+472>: lsr    x15, x14, #3
    0x7fbd4f8cb0 <+476>: and    x15, x15, #0x18
    0x7fbd4f8cb4 <+480>: ldr    x15, [x11, x15]
Target 0: (kptools_android) stopped.
(lldb) register read x19,x9
error: Invalid register name 'x19,x9'.
(lldb) register read x19
     x19 = 0xb400007d2ad56ff3
(lldb) register read x9
      x9 = 0x000000000000000d

这里的0x7fbd4f8ca8 <+468>: ldrb w14, [x19, x9] 读取的内存超过了imgend=0xb400007d2ad57000 +14,引发的内存segmentfault错误。我之前就发现在pc端就能正常patch,但是在手机内执行patch就失败。我查了一下源码https://android.googlesource.com/platform//bionic/+/02ed7ea425effff4ac7f729456e732304198b815/libc/upstream-openbsd/lib/libc/string/memmem.c#163

这里的内存就是调用的https://android.googlesource.com/platform//bionic/+/02ed7ea425effff4ac7f729456e732304198b815/libc/upstream-openbsd/lib/libc/string/memmem.c#69 对应了汇编提示的libc.sotwoway_memmem的错误。修正这个可以把linux的memmem替换为android内的memmem即可,我测试了一下可以正常完成patch。

sunfish:/data/local/tmp/test_patch $ chmod +x kptools_android_fix_148
/kptools_android_fix_148 -p -i kernel -S abcd1234 -k kpimg -K kpatch -o Image4                                                                 <
[+] kernel image_size: 0x025ea010
[+] kernel uefi header: false
[+] kernel load_offset: 0x00080000
[+] kernel kernel_size: 0x02e7a000
[+] kernel page_shift: 12
[+] new kernel image ...
[?] search size: 39755792 prefix_len: 14
[+] linux_banner 1: Linux version 4.19.157-perf+ (root@e9898debe832) (Android (10087095, +pgo, +bolt, +lto, -mlgo, based on r487747c) clang version 17.0.2 (https://android.googlesource.com/toolchain/llvm-project d9f89f4d16663d5012e5c09495f3b30ece3d2362), LLD 17.0.2) #1 SMP PREEMPT Mon Dec 2 23:38:24 UTC 2024

[+] linux_banner offset: 0x1580018
[?] search size: 17211384 prefix_len: 14
[?] search size: 7955197 prefix_len: 14
[+] start parsing...[+] kernel version major: 4, minor: 19, patch: 157
[+] kallsyms_token_table offset: 0x01c72e00
[+] endian: little
[+] kallsyms_token_index offset: 0x01c73200
[+] find arm64 relocation kernel_va: 0xffffff8008080000
[+] find arm64 relocation table range: [0x020a6218, 0x02376488), count: 0x0001e01a
[+] apply 0x0001e019 relocation entries
[+] kallsyms_markers range: [0x01c71e00, 0x01c72d40), count: 0x000001e8
[+] approximate kallsyms_offsets range: [0x01a594e0, 0x01ad3414) count: 0x0001e7cd
[+] kallsyms_names offset: 0x01ad3700
[+] kallsyms_num_syms offset: 0x01ad3600, value: 0x0001e7c5
[+] names table linux_banner index: 0x0000e746
[+] linux_banner index: 0
[+] kallsyms_offsets offset: 0x01a59500
[+] layout kimg: 0x0,0x25ea010, kpimg: 0x25eb000,0x27f80, extra: 0x2612f80,0x8ee0, end: 0x261be60, start: 0x2e7a000
[+] kpimg version: a07
[+] kpimg compile time: 19:05:39 Dec 12 2024
[+] kpimg config: linux, release
[+] tcp_init_sock: type: T, offset: 0x011ab958
[+] map_start: 0x11ab960, max_size: 0x800
[+] kallsyms_lookup_name: type: T, offset: 0x0010d304
[+] printk: type: T, offset: 0x000002e4
[+] memblock_reserve: type: T, offset: 0x001f8848
[+] memblock_free: type: T, offset: 0x001f87a8
[+] memblock_mark_nomap: type: T, offset: 0x001f8b14
[?] no symbol: memblock_phys_alloc_try_nid
[+] memblock_virt_alloc_try_nid: type: T, offset: 0x01fa2c80
[+] memblock_alloc_try_nid: type: T, offset: 0x01fa2904
[+] panic: type: T, offset: 0x00000040
[+] rest_init: type: t, offset: 0x013b4430
[+] kernel_init: type: t, offset: 0x013b4514
[?] no symbol: report_cfi_failure
[?] no symbol: __cfi_slowpath_diag
[?] no symbol: __cfi_slowpath
[+] copy_process: type: t, offset: 0x0003db3c
[?] no symbol: do_execveat_common
[+] __do_execve_file: type: t, offset: 0x00229bb8
[?] no symbol: do_execve_common
[+] do_faccessat: type: T, offset: 0x0021b8ec
[+] __arm64_sys_faccessat: type: T, offset: 0x0021bb34
[?] no symbol: __arm64_sys_faccessat2
[?] no symbol: sys_faccessat2
[+] __arm64_sys_newfstatat: type: T, offset: 0x002269ec
[+] vfs_statx: type: T, offset: 0x0022677c
[?] no symbol: vfs_fstatat
[+] avc_denied: type: t, offset: 0x003f8264
[+] slow_avc_audit: type: T, offset: 0x003f72a0
[+] input_handle_event: type: t, offset: 0x00a1fbbc
[+] root superkey hash: e9cee71ab932fde863338d08be4de9dfe39ea049bdafb342ce659ec5450b69ae
[+] paging_init: type: T, offset: 0x01f888b0
[+] embedding exec, name: kpatch, priority: 2147483647, event: , args: , size: 0x80+0x0+0x8de0
[+] patch done: Image4。

@bmax121
Copy link
Owner

bmax121 commented Jan 14, 2025

https://man7.org/linux/man-pages/man3/memmem.3.html

SYNOPSIS top
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <string.h>

   void *memmem(const void haystack[.haystacklen], size_t haystacklen,
                const void needle[.needlelen], size_t needlelen);

DESCRIPTION top
The memmem() function finds the start of the first occurrence of
the substring needle of length needlelen in the memory area
haystack of length haystacklen.

是不是 memmem 的用法用错了,改一下 haystacklen 的长度就可以了吧

@Tr33NewBee Tr33NewBee closed this Mar 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants