AssetHook:Android应用资源数据运行时编辑工具

简介: 本文讲的是AssetHook:Android应用资源数据运行时编辑工具,AssetHook是一个工具,它可以让Android安全研究人员和普通用户能够在无需修改APK本身的情况下随时修改Android应用程序的部分Asset。
本文讲的是 AssetHook:Android应用资源数据运行时编辑工具AssetHook是一个工具,它可以让Android安全研究人员和普通用户能够在无需修改APK本身的情况下随时修改Android应用程序的部分Asset。这样的修改使研究人员可以改变嵌入式数据,以更好地评估和测试移动应用程序。目前来看AssetHook比现有方法更容易使用,且比传统方法更有效。

背景

去年年底,我开始关注Android启用React Native 后 Facebook的新框架,它将跨平台移动开发统一到JavaScript,显然JavaScript是一种不需要介绍的语言。在React Native之前,在JavaScript中构建跨平台移动应用程序的主要方法是使用PhoneGap(…或者现在是Cordova吗?甚至不让我从Ionic开始)。这些都是基于将JavaScript加载到Webview中(UIWebView在iOS上,WebView在Android上)的主要应用程序逻辑。然后,开发人员可以在平台的“本机”语言中编写一些平台特定的代码,并将它们与幽灵一般的webview魔术FFI连接在一起。

React Native将这种设计(也可能是理由)一脚踢开,然后颠覆了传统。它不是使用webview和HTML / CSS进行渲染,它将JavaScript声明的UI映射到平台的本地UI工具包,并嵌入WebKit的JavaScriptCore(JSC)库来运行该JavaScript,完全避免了平台的Webview实现。JSC支持在没有JIT的情况下解释JavaScript,这在iOS上是必需的,因为它的安全模型是基于不允许任何人生成可执行内存的(而且人们说OpenBSD的人是Luddites for W ^ X …); 最后我检查过,V8只是JIT(新的ignition interpreter似乎并没有改变,因为“ JIT代码生成仍然是IC和代码存根 ”)。

作为我最初在Android上进行React Native的一部分,我试图在应用程序中注入额外的JavaScript代码,以将开发控制台REPL加载(并执行janky函数hook)。所以,我在这种情况下做了一个通常的工作,并为Android的android.content.res.AssetManager类写了一个Xposed函数hook。..之后我再没有做什么。

Android使用AssetManager该类作为应用程序的界面来访问嵌入在其APK中的特定类型的文件资源(特别是APK中的assets/目录中)。鉴于我知道(从开放一个发布版本的React Native应用程序)主要的后处理JavaScript软件包作为资产存储,所以hook不起作用是非常奇怪的。然后,我通过React Native的Android代码库开始测试,很快就发现使用C API为Android的资产管理器加载了C ++代码,这解释了为什么Java函数挂起不起作用。

因为我想要修改这些软件包的内容,而不需要创建和签名修改的APK(然后需要更多的hook来欺骗他们的签名),我设置了构建一个工具来hook这些资源负载。我在C ++中写了最初的POC,然后在Rust中重写。

(A)AssetHook

AssetHook是一款LD_PRELOAD用于Android应用程序的函数hook库。它hook了Android的内部资产管理代码,并将资产文件加载从合法(即签名的)APK重定向到设备本地文件系统上的单独位置。(A)AssetHook的初始版本“AAssetHook”(两个“A”)拦截了Android 公共 AAssetManager C API的调用,其实际上是用extern "C"C ++编写的。然而,由于这个API只是一个直接由Java 类使用的Android 内部类的封装,所以我把它重写为“AssetHook”(一个'A')来代替底层的C ++ API。 AssetManagerandroid.content.res.AssetManager

如果没有像AssetHook这样的东西的话,替换Android资产将需要解压APK,替换资产文件,重新打包APK,可能会重新对齐,签署新的APK文件,然后安装它。这不但是一个繁琐和缓慢的过程(特别是APK复制到设备并为更大的应用程序安装过程),还必须处理新的签名打破跨应用程序签名检查的后果。对于使用自定义权限,共享用户ID或自定义IPC访问控制的应用程序组,此新签名将阻止修改的应用程序与其他应用程序进行交互或完全不起作用。然后需要额外的hook来欺骗修改后的APK的签名证书以匹配原来的APK。此外,如果没有更多根深蒂固和灵活的功能hook基础架构(例如修改系统分区二进制文件的Xposed),这种hook在Android上可能是不可能的。使用这种框架的一个关键问题是由于需要移植工作,因此必然会延迟支持新的Android版本。

C API Hooking 使用了 LD_PRELOAD

C API hooking变体(“AAssetHook”)是由vanilla的 LD_PRELOADhook来实现的,它声明了一些重复的函数符号,尽管动态链接的魔力 – 在从其二进制文件外部访问时重写对这些函数的调用。然后在dlopen(3)/ dlsym(3)(在Unix上)使用一个Rust包装库来根据需要代理对原始函数的调用。之后,它会检查一个APK中的给定文件路径是否与设备文件系统上的现有路径匹配,并欺骗C API返回磁盘文件的文件内容,而不是in-

C++ API Hooking 使用了 LD_PRELOAD

由于资产管理器的C ++实现不是公共API,C ++ APIhook变体(“AssetHook”)稍微复杂一点,这在很大程度上依赖于多态性,并且在较小的Android版本中可能会发生变化。当在C ++中使用多态时,通常将通过动态调度处理虚拟方法调用。在大多数“平稳”平台上,通过将虚拟表(vtable)指针作为类的内存结构的第一个元素之一来实现。该指针在构造期间设置,并指向一个填充有该类使用的特定虚拟方法的函数指针的表。LD_PRELOAD在这种情况下,函数hook非常有限,因为它只能挂接导出符号的二进制函数调用,而动态调度调用则使用直接函数指针。这样可以避免基于vtable的呼叫被LD_PRELOAD符号覆盖直接挂起。此外,这些函数指针的顺序很可能会在次级类定义更改时发生更改。在不同的编译器之间也是不一致的,通常可能难以推断出多个版本的二进制文件。

注意:这完全取决于编译器,但是这一点在Unix上的Clang和GCC(至少对于x86 / amd64和ARM / AArch64来说都是一致的)。

例如,下面的代码片段的对象可以被布置,如下图所示:

#include <stdio.h>struct Base {
  virtual void foo() {
    puts("base!");
  }
  size_t a = (size_t)-};struct Derived : public Base {
  virtual void foo() {
    puts("derived!");
  }
  size_t b = (size_t)-};struct DDerived : public Derived {
  void foo() final override {
    puts("dderived!");
  }
  size_t c = (size_t)-};void call_foo(Base& br.foo();}int main() {
  Base b;
  Derived d;
  DDerived dd;
  call_foo(b);
  call_foo(d);
  call_foo(dd);
  return 0;}

 AssetHook:Android应用资源数据运行时编辑工具

功能搜索和vtable插槽映射

处理vtable排序的波动的一种方法是将给定的类“vtable”与其二进制文件的符号表进行交叉引用(用binutils的GPL bfd.h或libelfin解析)。使用手中的函数地址,可以对vtable进行交叉引用以找到其偏移量。然而,这可能不起作用,因为一些虚拟方法函数可能没有符号,就像Android资产管理器的C ++实现一样。另一种方法是扫描这种不符号的函数的原始字节,但这不太可能跨越多个二进制版本。 

事实上,这是完全可能的(使用类似Capstone的东西)去解析调用目标类的虚拟方法并提取这些方法的vtable偏移量的符号符号函数的汇编。

vtable Slot Knocking

AssetHook的C ++ APIhook实现使用了最后一种方法的一个变体,依靠这样一个事实,即将虚拟方法调用的C API本身就是具有ABI稳定性保证的公共API。AssetHook不是分析C API函数的指令来剔除vtable偏移量,而是创建一个假的C ++对象,并使用它来配置vtable。该对象vtable指针指向一个虚构的vtable,其中包含一系列报告调用顺序的函数指针。AssetHook将该对象作为嵌入到void*掩码包装结构体中的指针传递给C API,然后C API通过编译器提供的偏移量调用关联的虚拟方法。执行此调用时,将触发嵌入式函数指针,暴露给定操作的vtable偏移量。这允许通过调用这个假的对象上已知的C API函数来逐个获取实际的vtable顺序,以获得它们包装的C ++方法的vtable偏移量。

注意:对于特殊的涉及 thunk的 “复杂”类,需要更加动态地分析vtable,因为类别的vtable段中的“正常”成员函数指针实际上是由编译器生成的包装函数。该函数相应地移动this指针,并从实际类的更大的vtable中的其他地方调用“真实”成员函数指针。

hook虚拟方法

之后,在返回对象指针LD_PRELOAD的AssetManager类的“公共”非虚拟方法的变形符号名称上创建一个类型的hookAsset。这个hook确定文件是否应该被hooking,如果是这样,返回一个指向一个修改后的Asset对象的指针,其中一个vtable包含了函数hook。

例子:

在这个例子中,我们将使用AssetHook将我们自己的JavaScript文件交换到Tic-tac-toe示例应用程序中(参考React Native文档,我必须传递–dev false给react-native build它来使其大部分应用程序成为最小化的)。我们假设您按照文件中的描述安装了它。

1、安装一个“release”版本的应用程序(为了尽可能的缩小,AssetHook可以同时发布和调试Android APK版本)在一个根深蒂固的测试设备上(AssetHook已知可以与Android 5.x,6.x和7.x一起用32位和64位ARM,以及32位x86上的Android O Developer Preview)。

2、从APK文件中提取assets/index.android.bundle(从嵌入的Android来源app/build目录或使用该设置adb shell pm list packages -f | grep <pkg>和adb pull)。

3、修改文件并注入JavaScript alert(…)。

4、运行以下命令:

$ adb push path/to/index.android.bundle /data/local/tmp/assethook/<pkg>/assets/
$ adb shell su -c 'setprop wrap.<pkg> LD_PRELOAD=/data/local/tmp/lib/libassethook_cppapi.so'

注意: React Native使用32位二进制文件,甚至在64位Android上。因此,32位模式下进程加载,我们需要使用32位版本的AssetHook。

5、启动应用程序(如果已经打开,请先关闭它)。

AssetHook:Android应用资源数据运行时编辑工具

未来的工作

主要优先事项是在执行模式下完全启用SEAndroid时支持Android。现在,AssetHook要求将SELinux置于允许模式,因为替换文件存在于Google试图通过SELinux限制访问现代Android版本的共享临时目录中。我正在寻求支持从应用程序自己的内部目录加载替换资产文件,但这可能需要额外的工具来将文件上传到设备上。




原文发布时间为:2017年6月3日
本文作者:Change
本文来自云栖社区合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。
目录
相关文章
|
3月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
291 4
|
6天前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
58 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
3天前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
21 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
2月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
87 14
|
2月前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
2月前
|
搜索推荐 前端开发 测试技术
打造个性化安卓应用:从设计到开发的全面指南
在这个数字时代,拥有一个定制的移动应用不仅是一种趋势,更是个人或企业品牌的重要延伸。本文将引导你通过一系列简单易懂的步骤,从构思你的应用理念开始,直至实现一个功能齐全的安卓应用。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你提供必要的工具和知识,帮助你将创意转化为现实。
|
3月前
|
前端开发 数据处理 Android开发
Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍
本文深入探讨了Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍,以及具体操作步骤、常见问题解决、高级调试技巧、团队协作中的调试应用和未来发展趋势,旨在帮助开发者提高调试效率,提升应用质量。
83 8
|
2月前
|
Java Android开发 开发者
探索安卓开发:构建你的第一个“Hello World”应用
在安卓开发的浩瀚海洋中,每个新手都渴望扬帆起航。本文将作为你的指南针,引领你通过创建一个简单的“Hello World”应用,迈出安卓开发的第一步。我们将一起搭建开发环境、了解基本概念,并编写第一行代码。就像印度圣雄甘地所说:“你必须成为你希望在世界上看到的改变。”让我们一起开始这段旅程,成为我们想要见到的开发者吧!
70 0
|
3月前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
Android开发
【Android 逆向】Android 逆向通用工具开发 ( Android 平台运行的 cmd 程序类型 | Android 平台运行的 cmd 程序编译选项 | 编译 cmd 可执行程序 )(二)
【Android 逆向】Android 逆向通用工具开发 ( Android 平台运行的 cmd 程序类型 | Android 平台运行的 cmd 程序编译选项 | 编译 cmd 可执行程序 )(二)
175 0
【Android 逆向】Android 逆向通用工具开发 ( Android 平台运行的 cmd 程序类型 | Android 平台运行的 cmd 程序编译选项 | 编译 cmd 可执行程序 )(二)

热门文章

最新文章