在 AVD 上使用 KernelSU - 第二回 -
编译兼容内核模块的版本前篇 已经成功编译出了适合 avd 使用的内核,然而同时需要编译兼容的内核模块,过于复杂。经过一番探索,发现只要找到正确的源码,还是能编译出与发布的 avd 镜像兼容的内核。
认识版本号还是回到 /proc/version 上,内核的版本号提供了很多信息,比如 -g 后跟着的是一个 12 位 16 进制数,表示编译的内核的源码树的提交 hash ,此外还有编译器版本。
1Linux version 6.1.23-android14-4-00257-g7e35917775b8-ab9964412 (build-user@build-host) (Android (9796371, based on r487747) clang version 17.0.0 (https://android.googlesource.com/toolchain/llvm-project d9f89f4d16663d5012e5c09495f3b30ece3d2362), LLD 17.0.0) #1 SMP PREEMPT Mon Apr 17 20:50:58 ...
在 AVD 上使用 KernelSU
在 AVD 上使用 KernelSU曾经尝试过给 AVD 构建带有 KernelSU 的内核,方便开发测试,但是发现内核模块不兼容,现在的方法是同时构建内核模块,略为复杂。
构建内核https://source.android.com/docs/setup/build/building-kernels?hl=zh-cn
Android 14 的 AVD 内核版本:
1Linux version 6.1.23-android14-4-00257-g7e35917775b8-ab9964412 (build-user@build-host) (Android (9796371, based on r487747) clang version 17.0.0 (https://android.googlesource.com/toolchain/llvm-project d9f89f4d16663d5012e5c09495f3b30ece3d2362), LLD 17.0.0) #1 SMP PREEMPT Mon Apr 17 20:50:58 UTC 2023
根据 KernelSU C ...
记一次 LSPosed Native Hook 偶现崩溃
记一次 LSPosed Native Hook 偶现崩溃发现故障昨天(12-05)调试 HMA 的时候重启手机,发现某些加载了 LSPosed 模块的 app 总是无法启动,除非禁用作用于它的所有模块,它们的 tombstone 全指向了同一处地址的 SIGSEGV 。
重启后恢复正常,于是我赶紧去翻查 tombstone ,发现 backtrace 来自某个 zygisk 模块,并且堆栈回溯到这里断掉了。
12345signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7196fa5224backtrace: #00 pc 00000000000859b0 /apex/com.android.runtime/lib64/bionic/libc.so (__memcpy+96) (BuildId: a790cdbd8e44ea8a90802da343cb82ce) #01 pc 000000000001c57c /memfd:jit-cache (deleted)
既然是 LSPosed 模块导致了 ...
Android 安装系统证书
Android 安装系统证书抓包的时候通常需要安装特定的 CA 证书以便中间人解密,本文以安装 mitmproxy 证书为例介绍如何准备证书文件和临时安装(挂载)证书到特定的 app 。
准备证书这里可以直接参考 mitmproxy 给出的流程
System CA on Android Emulator
mitmproxy CA 证书位于 ~/.mitmproxy/mitmproxy-ca-cert.cer (Windows: %UserProfile%\.mitmproxy\mitmproxy-ca-cert.cer) ,Android 接受这种格式的证书,不过需要重命名为特定的名字。
命令 openssl x509 -inform PEM -subject_hash_old -in mitmproxy-ca-cert.cer 第一行输出证书的 hash ,本例中为 c8750f0d ,因此复制一份 mitmproxy-ca-cert.cer ,将其重命名为 c8750f0d.0 ,即可得到 Android 上可用的证书。
挂载到系统目录对于 Android 13 和之前的版本, ...
在树莓派上部署 Tachidesk Server
在树莓派上部署 Tachidesk Server & Suwayomi 插件体验最近想在手机上看本子,但是想看的内容重达 8G ,即使处理成 webp ,压缩到了 600M ,但几千张也不是小数目,实在不太好放在手机上。突然想到自己尘封数个月的三手树莓派,于是拿出来搭建了个 WebDAV ,把本子传上去,这样就能舒服地躺在床上用手机看了。剩下的问题就是阅读器。手机上支持 WebDAV 的文件管理器普遍看图效果差,而 Tachiyomi 虽然看漫画好用却没有 WebDAV 源。现在发现 Tachidesk 通过 Suwayomi 插件可以作为 Tachiyomi 的图源,决定在树莓派上部署。
安装Suwayomi/Tachidesk-Server: A rewrite of Tachiyomi for the Desktop
首先安装 makedeb
makedeb - A simplicity-focused packaging tool for Debian archives
1bash -ci "$(wget -qO - 'https:// ...
My new blog ...
My new blog …终于还是用 hexo + gh pages 搭了个博客。
原本希望用 my-notes 作博客,用 github 自带的 actions 生成,然而效果不佳,最大的问题是没有首页,自己又懒于研究,于是就一直挂在那了,想必没人会看吧(笑)。
开这个新的博客,也是希望另起炉灶,因为原先的 my-notes 堆积了大量的口水话,我还是希望新的 blog 内容更有质量一些,少一些记录性的内容。
现在我已经从 my-notes 搬运了一些我认为相对来说好一些的内容到这里。也许将来 my-notes 的作用就是草稿箱,如果有成品就会放到这里来。
LSPass 学习
LSPass 学习前置知识ART 对象表示在 ART 中,一个 Java 对象与一个 art::mirror::Object 一一对应,此外一些系统的特殊类会和 mirror Object 的派生类对应,如 java/lang/Class 对应 art::mirror::Class 。
mirror::Object 对象所包含的内容就是 instance field 的内容,因此它的大小和类的 instance field 有关。之所以叫 mirror ,是因为这些 mirror 类中定义的成员和 Java 类的字段(field)是一致的。
一般的类的对象对应的都是 art::mirror::Object ,访问 field 是通过对象地址 + field offset 实现的。如果一个类继承另一个类,则内存布局上子类的 field 排在父类的后面,这和结构体继承的内存布局是一致的。
例如 art::mirror::Object 只有两个成员:
12345// art/runtime/mirror/object.h // The Class representin ...
LSPlant 学习
LSPlanthttps://github.com/LSPosed/LSPlant
基本原理修改 ArtMethod 的 entry_point_from_quick_compiled_code_ ,这里原先是 dex2oat 优化后的本机代码,现在指向我们控制的代码。同时通过各种手段使调用方法时走本机代码 。
为此,hook 一个 method 需要另外两个 method ,一个作为 hook 的 stub ;另一个 method 用于备份被 hook 的方法。LSPlant 使用 DexBuilder 生成包含这两个方法的辅助类。
ArtMethod 调用约定我们可以从反射执行看 oat 后 ArtMethod 的本机代码是如何调用的。
ArtMethod::Invoke
根据方法是否为 static ,执行一段汇编编写的代码 art_quick_invoke_stub 或 art_quick_invoke_static_stub ,其代码位于:
art/runtime/arch/{arch}/quick_entrypoints_{arch ...
Android 系统属性
系统属性Android Property 实现解析与黑魔法 - 残页的小博客
bionic属性系统概述bionic/libc/bionic/system_property_api.cpp
bionic/libc/include/sys/_system_properties.h
属性系统实际上就是一个整个系统共享的键值对存储器,通过共享文件内存映射实现。
存放属性的文件位于 /dev/__properties__ ,这下面的多个文件,实际上是将属性按照前缀划分为不同的 SELinux 上下文,存放在对应的文件中。
划分的规则可以在 /{system,vendor,...}/etc/selinux/{plat,...}_property_contexts 等文件找到。
init 进程负责初始化属性存储区域,且是系统中唯一能够修改属性的进程(当然,只要某个进程能 rw 映射存放属性的文件,也是可以修改的),其他进程通过属性服务(一个名为 property_service 的 sock ...
Android ptrace
Android 上的 ptrace 实践前篇
dlopen获取 dlopen 有两种方法:
从 linker 获取 __loader_dlopen (或者 __dl___loader_dlopen),需要提供 caller_addr
从 libdl.so 获取 dlopen
详细代码:
https://github.com/5ec1cff/ptrace-examples/tree/android
实现了注入到任意进程,调用 __loader_dlopen 打开指定路径的 lib ,或者调用 __loader_dlclose 关闭指定 handle 的 lib 。目前只支持 x86-64 和 arm64 。
对齐问题一开始总是得到 SIGSEGV ,并且 fault addr 为 0 。出现问题的时候注入信号并 detach ,观察 crash dump :
123456789101112131415161718192005-02 13:13:59.534 18907 18907 F DEBUG : *** *** *** *** *** *** *** *** *** * ...