AOSP源码定制-修改ART实现smali追踪

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

文章总结: 本文介绍通过修改AOSP的ART运行时实现smali指令追踪的技术方案。作者分析ART方法执行流程,在interpreter层强制启用解释模式并添加自定义追踪函数,可实时输出方法名、寄存器值及字符串参数。通过文件触发机制动态控制追踪范围,解决了加固APP的hook难题。 综合评分: 78 文章分类: 移动安全,逆向分析,安全开发,二进制安全


cover_image

AOSP源码定制-修改ART实现smali追踪

哆啦安全

2024年3月12日 08:32 四川

在小说阅读器读本章

去阅读

以下文章来源于gakki的童养夫 ,作者新垣结衣唯一丈夫

gakki的童养夫 .

emmmmm gakki是我的

AOSP源码定制-修改ART实现smali追踪

介绍

前面尝试了注入so来hook native层,也尝试了能否进行java层hook,结果并不理想。 这里为了尝试打印一个参数RSA加密的强加固APP的明文参数,尝试修改ART,打印smali指令,带出明文字符串。

源码分析

方法执行流程

查看源码分析执行流程,比较枯燥比较绕,我也只是看了个大概。 从invoke开始,这是一个native方法。 在源码/art/runtime/native/javalangreflect_Method.cc中,可以看到invoke调用了InvokeMethod方法 。

跟进查看,这里可以看到将javaMethod转换为了ArtMethod。 往下看,发现在InvokeWithArgArray传入了ArtMethod。 最后调用Invoke方法执行,另一个通过Jni的CallVoidMethod系列的方式去调用,同样最后也是走到这里。

解释流程

继续跟进Invoke方法分析解释流程,到art_method.cc下。 可以看到有一处判断是否走解释模式。 跟进查看。 往下有一处判断,当不是Native时,走Execute方法。 Execute方法中存在一个判断,走switch还是汇编。

我们希望是走switch模式的,跟进ExecuteSwitchImpl,这里获取指令等,关键就在这里了,这里还给出了一个他自己带的TraceExecution,可以用来追踪。

只不过他是默认不打印,打印很耗费资源。

修改源码

在 /art/runtime/instrumentation.h 中修改,强制走解释模式:

1. // Called by ArtMethod::Invoke to determine dispatch mechanism.
2. bool InterpretOnly() const {
3. return interpret_only_;
4. }

6. bool IsForcedInterpretOnly() const {
7. return forced_interpret_only_;
8. }

10. //改为
11. bool InterpretOnly() const {
12. return true;
13. }

15. bool IsForcedInterpretOnly() const {
16. return true;
17. }

在 /art/runtime/interpreter/interpreter.cc 中修改,使用switch模式:

1. enum InterpreterImplKind {
2. kSwitchImplKind,        // Switch-based interpreter implementation.
3. kMterpImplKind          // Assembly interpreter
4. };

6. //static constexpr InterpreterImplKind kInterpreterImplKind = kMterpImplKind;
7. static constexpr InterpreterImplKind kInterpreterImplKind = kSwitchImplKind;

在art/runtime/interpreter/interpreter_common.h 中修改,增加函数。

1. static inline void myTraceExecution(const ShadowFrame& shadow_frame, const Instruction* inst,
2. const uint32_t dex_pc)
3. REQUIRES_SHARED(Locks::mutator_lock_) {
4. std::ostringstream oss;
5. oss << "[FuncName] " << shadow_frame.GetMethod()->PrettyMethod() << "\t"
6. << android::base::StringPrintf("[Address] 0x%x: ", dex_pc)
7. << inst->DumpString(shadow_frame.GetMethod()->GetDexFile()) << "\t[Regs]";
8. for (uint32_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) {
9. uint32_t raw_value = shadow_frame.GetVReg(i);
10. ObjPtr<mirror::Object> ref_value = shadow_frame.GetVRegReference(i);
11. oss << android::base::StringPrintf(" vreg%u=0x%08X", i, raw_value);
12. if (ref_value != nullptr) {
13. if (ref_value->GetClass()->IsStringClass() &&
14. !ref_value->AsString()->IsValueNull()) {
15. oss << "/java.lang.String \"" << ref_value->AsString()->ToModifiedUtf8() << "\"";
16. } else {
17. oss << "/" << ref_value->PrettyTypeOf();
18. }
19. }
20. }

22. LOG(ERROR) << oss.str().c_str();
23. }

在interpreterswitchimpl.cc 中修改也加个判断。

1. bool enableTrace = false;
2. if(strstr(method->PrettyMethod().c_str(), "xxxxx")){
3. enableTrace = true;
4. }
5. do {
6. dex_pc = inst->GetDexPc(insns);
7. shadow_frame.SetDexPC(dex_pc);

9. //TraceExecution(shadow_frame, inst, dex_pc);
10. if(enableTrace){
11. myTraceExecution(shadow_frame, inst, dex_pc);
12. }

然后编译刷机,在执行到包含xxxx方法时,会打印指令。

优化

这样有一点不好,换一个匹配需要重新刷机,优化一下,加个文件判断(APP需要开启读写权限)。

1. bool enableTrace = false;
2. char traceFilePath[64] = {0};
3. char contents[64] = {0};
4. int result12 = 0;
5. int ftraceline = -1;
6. sprintf(traceFilePath,"/sdcard/trace.txt");
7. ftraceline = open(traceFilePath, O_RDONLY, 0644);
8. if(ftraceline>0){
9. result12 = read(ftraceline, contents, 64);
10. if(result12<0){
11. LOG(ERROR) << "fukuyamatrace123 open trace error!";
12. }
13. close(ftraceline);
14. }
15. if(contents[0]){
16. //      LOG(ERROR) << "fukuyamatrace123 "<< contents;
17. char* customString = (char*)malloc(result12-1);
18. strncpy(customString, contents, result12-1);
19. if(strstr(method->PrettyMethod().c_str(), customString)){
20. //          LOG(ERROR) << "fukuyamatrace123 " << "func now:" << method->PrettyMethod().c_str() <<" trace func:" << contents;
21. enableTrace = true;
22. }
23. free(customString);
24. }

在后面刷机就不演示了。

总结

参考各类资料,学习了art下方法执行解释流程,打印smali指令,用笨方法替代了无法hook的问题。


免责声明:

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

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

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

本文转载自:哆啦安全 《AOSP源码定制-修改ART实现smali追踪》

评论:0   参与:  0