问题描述
编写内核驱动,使用mmap
共享内存。发现读取到的数据不对。
联想到mmap
的length
会自动调整为PAGE_SIZE
的倍数,猜测是因为mmap
返回的是对应page
的起始地址,导致存在偏移。
修复方式:初始化时,单独申请一块大小为PAGE_SIZE
的内存,不使用数组。
并调用SetPageReserved
,保留该页。
某app使用了curl
+openssl
进行https
通信,并开启了证书校验。
通过分析curl
源码,定位到证书校验位置,Patch汇编代码,绕过证书校验。
SSL_CTX_set_verify
定义:openssl/ssl/ssl_lib.c#L3551
1 | void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, |
调用位置ossl_connect_step1
:curl/lib/vtls/openssl.c#L3200
相关变量verifypeer
:curl/lib/vtls/openssl.c#L2676
PC: Windows 10
NDK: 22.1.7171670
GDB 8.3
(位于<ndk>\toolchains\llvm\prebuilt\windows-x86_64\bin
)lldb version 11.0.5
(位于<ndk>\prebuilt\windows-x86_64\bin
)
<ndk>\prebuilt\android-arm64\gdbserver
<ndk>\toolchains\llvm\prebuilt\windows-x86_64\lib64\clang\11.0.5\lib\linux\arm\lldb-server
<ndk>\prebuilt\android-arm\gdbserver
<ndk>\toolchains\llvm\prebuilt\windows-x86_64\lib64\clang\11.0.5\lib\linux\aarch64\lldb-server
使用insmod
安装内核模块后,在app
的Native
层访问驱动,提示Permission Denied
。
设置驱动权限,绕过DAC
权限检查:chmod 666 /dev/helloworld
。
再次调用,仍然失败。
执行dmesg -w | grep "avc: denied"
,查看SELinux
日志。
1 | [23292:logd.auditd]type=1400 audit(1651503112.740:5320): avc: denied { read write } for comm="exp.hellokernel" name="helloworld" dev="tmpfs" ino=297747 scontext=u:r:priv_app:s0:c227,c256,c512,c768 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1 |
关闭SELinux
后,成功调用驱动。
添加allow
规则,调用仍失败,查阅资料得知需要设置为mlstrustedsubject
。
最终基于magiskpolicy
,实现了自定义SELinux
规则的添加。
PS:笔者将apk放到了system/priv-app
目录下,所以role
是priv_app
,而非untrusted_app
。
1 | logcat: Unexpected EOF! |
1 | Logd maybe crashed, retrying in 1s... |
开发者选项
-日志记录器缓冲区大小
修改为16M
。
process_vm_rw
->process_vm_rw_core
->process_vm_rw_single_vec
->process_vm_rw_pages
->copy_page_to_iter
->copy_page_to_iter_iovec
->copyout
common/mm/process_vm_access.c
common/lib/iov_iter.c
版本号:android-4.14-stable
process_vm_readv(2) - Linux manual page
1 | #include <sys/uio.h> |
Redmi K40 Gaming
、MIUI 12.5.8
查看文件名:
1 | ls -al /dev/block/by-name | grep boot |
提取boot.img
:
1 | dd if=$(readlink /dev/block/by-name/boot_a) of=/sdcard/boot.img |
自己编译或者使用affggh/magiskbootkitchen
1 | adb pull /sdcard/boot.img . |
1 | ./magiskboot unpack /sdcard/boot.img |
使用IDA64
打开kernel
,选择ARM processer
、64-Bit
。
执行Python脚本:
1 | import idc |
然后等待IDA
分析结束。
使用010Editor
搜索字符串disagrees about version of symbol
,复制地址。
在IDA64
中查看交叉引用,定位到的函数即为check_version
将函数体的第一个跳转Patch为B指令。然后F5,查看返回值是否为1。
例如:CBZ X2, loc_FB8A8
Patch为:B loc_FB8A8
相关代码:
1 | ROM:00000000000FB8A8 loc_FB8A8 ; CODE XREF: sub_FB804+14↑j |
1 | ROM:00000000000FB8D4 loc_FB8D4 ; CODE XREF: sub_FB804+74↑j |
Copy From: ChromiumOS Docs - Linux System Call Table
Also View: unistd.h - Android Code Search
arch | syscall NR | return | arg0 | arg1 | arg2 | arg3 | arg4 | arg5 |
---|---|---|---|---|---|---|---|---|
arm | r7 | r0 | r0 | r1 | r2 | r3 | r4 | r5 |
arm64 | x8 | x0 | x0 | x1 | x2 | x3 | x4 | x5 |
x86 | eax | eax | ebx | ecx | edx | esi | edi | ebp |
x86_64 | rax | rax | rdi | rsi | rdx | r10 | r8 | r9 |
Copy From: ChromiumOS Docs - Linux System Call Table
Also View: unistd.h - Android Code Search
arch | syscall NR | return | arg0 | arg1 | arg2 | arg3 | arg4 | arg5 |
---|---|---|---|---|---|---|---|---|
arm | r7 | r0 | r0 | r1 | r2 | r3 | r4 | r5 |
arm64 | x8 | x0 | x0 | x1 | x2 | x3 | x4 | x5 |
x86 | eax | eax | ebx | ecx | edx | esi | edi | ebp |
x86_64 | rax | rax | rdi | rsi | rdx | r10 | r8 | r9 |