Android10至16系统定制中实现同时打印JNI(Native)堆栈和Java堆栈

admin 2026-04-16 04:23:37 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 该文档详细介绍了在Android10至16系统定制中实现同时打印JNI(Native)堆栈和Java堆栈的技术方案。核心内容包括系统层定制(修改AOSP源码启用完整堆栈跟踪功能)和代码层实现(通过Java与Native代码桥接)。关键发现显示需修改Zygote配置、调整debuggerd输出,并提供了具体的代码示例和调试方法。可操作建议包括使用CallStack类进行Native堆栈打印、设置混合触发机制,并注意权限管理和性能优化。 综合评分: 85 文章分类: 移动安全,系统定制,漏洞分析,安全开发,技术标准


cover_image

Android10至16系统定制中实现同时打印JNI(Native)堆栈和Java堆栈

原创

云天实验室 云天实验室

哆啦安全

2025年6月20日 21:29 四川

在小说阅读器读本章

去阅读

在Android 12系统定制中实现同时打印JNI(Native)堆栈和Java堆栈,需结合系统底层机制与代码注入技术。

鸿蒙(HarmonyOS)应用的安全测试方法

Magisk和LSPosed特征魔改绕过检测的思路和方法

一、系统层定制(需修改AOSP源码)

  1. 启用完整堆栈跟踪功能

修改Zygote以支持Native堆栈打印

Android 4.2+默认关闭Native线程堆栈打印,需修改dalvik/vm/Thread.cpp

// 在dumpNativeThread函数中取消以下注释dvmDumpNativeStack(target, tid);  // 取消此行注释

重新编译Zygote后,

kill&nbsp;-3&nbsp;<pid>或Process.sendSignal(pid, SIGNAL_QUIT)

生成的/data/anr/traces.txt将同时包含Java和Native堆栈。

配置debuggerd增强输出

在debuggerd配置中启用混合堆栈收集

adb&nbsp;shell debuggerd -b <pid> &nbsp;# 输出到logcat

修改system/core/debuggerd源码,确保tombstone文件同时包含两类堆栈(默认已支持)。

  1. 内核与系统属性调整

确保内核支持堆栈转储

内核配置需启用:

CONFIG_DEBUG_KERNEL=yCONFIG_STACKTRACE=y

修改ANR存储策略

在system/core/libcutils中调整debuggerd的ANR写入路径,避免覆盖问题。

二、代码层实现(无需修改AOSP)

  1. Java层打印堆栈
// 主动触发Java堆栈Log.e("JAVA_STACK",&nbsp;Log.getStackTraceString(new&nbsp;Throwable()));

输出示例:

java.lang.Exception: Stack traceat com.example.MyClass.method(MyClass.java:10)
  1. JNI/Native层打印堆栈

C++代码(推荐CallStack类)

#include&nbsp;<utils/CallStack.h>void&nbsp;dumpNativeStack()&nbsp;{&nbsp; &nbsp; &nbsp;CallStack&nbsp;stack("NATIVE_STACK");&nbsp; &nbsp; &nbsp;stack.update();&nbsp; &nbsp; &nbsp;stack.dump(); &nbsp;// 输出到logcat&nbsp;}

Android.bp依赖

shared_libs: ["libutilscallstack"] &nbsp;// Android 10+

Android.mk和Android.bp

Android系统定制之Android.mk和Android.bp语法详解(精通版)

Android系统定制之Android.mk内置第三方apk和资源文件的方法总结

纯C代码(兼容底层库)

通过libcorkscrew动态加载(需系统支持):

#include&nbsp;<dlfcn.h>#define&nbsp;LIB_PATH&nbsp;"/system/lib/libcorkscrew.so"void&nbsp;dump_stack()&nbsp;{&nbsp; &nbsp; &nbsp;&nbsp;void* handle =&nbsp;dlopen(LIB_PATH, RTLD_NOW);&nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(handle) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 获取unwind_backtrace等函数指针并调用&nbsp;&nbsp; &nbsp; &nbsp; }}
  1. 同时打印JNI和Java堆栈的桥接方法
// Java层public&nbsp;static&nbsp;void&nbsp;dumpFullStack()&nbsp;{&nbsp; &nbsp; dumpJavaStack();&nbsp; &nbsp; nativeDumpStack();}
// JNI层extern&nbsp;"C"&nbsp;JNIEXPORT&nbsp;void&nbsp;JNICALLJava_com_example_StackUtils_nativeDumpStack(JNIEnv*, jobject) {&nbsp; &nbsp; dumpNativeStack(); &nbsp;// 调用上述Native打印&nbsp; &nbsp; __android_log_print(ANDROID_ERROR,&nbsp;"HYBRID",&nbsp;"JNI/Native Stack Printed");}

三、调试与日志整合

  1. 日志统一收集

所有堆栈输出至logcat,通过Tag过滤(如JAVA_STACK/NATIVE_STACK)。

  1. 动态触发机制

按键触发:重载KeyEvent监听,组合键触发dumpFullStack()。

异常捕获:在Thread.setDefaultUncaughtExceptionHandler中调用混合堆栈方法。

  1. ADB命令集成

定制系统命令脚本:

adb&nbsp;shell custom_dumpstack <pid> &nbsp;# 内部调用kill -3和debuggerd -b

四、各场景推荐方案

下表总结了不同需求下的最佳实践:

五、注意事项

  1. 权限问题

/data/anr目录需SELinux放行策略。

非root设备需签名platform密钥或使用`adb root。

  1. 性能影响

堆栈收集阻塞线程,避免高频调用(如循环中)。

  1. 版本兼容性

CallStack类在Android 10后迁移至libutilscallstack(旧版在libutils)。

Android 12的JNI类型检查更严格,需确保JNICALL规范正确。

  1. 日志淹没预防

添加开关控制

if&nbsp;(BuildConfig.DEBUG)&nbsp;dumpFullStack(); &nbsp;// 仅调试版生效

完整实现需基于AOSP 12源码环境编译验证。测试时可通过强制触发ANR(如主线程死循环)观察traces.txt内容,或直接调用混合堆栈接口。

推荐阅读

Android7至Android16系统定制篇(魔改)

Android15无需解锁就能Root的解决方案

KernelSU全面解析:安卓内核级Root解决方案

Android7至16系统PMS提升开机速度优化解决方案

Android7至16系统ROM魔改和安全研究篇(建议收藏)

KernelSU Next是Android新兴的内核级Root解决方案

Root检测对抗指南:魔改su命令实现静默安装与权限隐藏

从零定制Android15:修改Build.prop与内核态绕过设备指纹检测


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:哆啦安全 云天实验室 云天实验室《Android10至16系统定制中实现同时打印JNI(Native)堆栈和Java堆栈》

一人AI公司的市场洼地 网络安全文章

一人AI公司的市场洼地

文章总结: 本文探讨了一人AI公司的市场机会,指出其核心不在于技术本身,而在于利用AI切入那些需求稳定、流程重复但传统服务成本高、效率低的细分市场。作者将这类市
评论:0   参与:  0