Android应用程序:java / JNI调用挂钩策略

2024-05-04

我的目标是检测 AOSP,以便动态记录来自目标应用程序的所有 java 或 JNI 调用(带或不带参数和返回值)。我不想修改应用程序,这就是我想要修改 Android 源代码的原因。我对 AOSP 及其众多库和框架不是很有经验,所以我正在寻求建议,因为我不知道从哪里开始。此外,由于可能记录的行数,该过程必须高效(即我不相信类似调试的方法可以工作,其中必须为每个挂钩方法实现一个挂钩类)

到目前为止我所理解的:

使用相对较新的 ART 系统,它将 DEX 应用程序源代码编译为一种机器可执行代码(OAT?),并且与 Dalvik 相比,它的检测更加复杂。

执行流程:编译的应用程序的java字节码(取决于编译的Android API)+ libs.so -> DVM -> forked Zygote VM -> 应用程序的执行。

如果我尝试挂钩根(Android API + libs.so),它将需要大量的工作来挂钩每个调用。理想的情况是所有 java 调用都经过的地方。 ART 中是否存在这样的地方?

AOSP源代码很难理解,因为似乎没有文档说明全局架构中每个源文件的作用。那么在哪里挂接电话比较好呢?

EDIT(s)

这个主题没有得到很好的涵盖,所以我会向感兴趣的人展示信息。

我的研究发现了这个博客:http://blog.csdn.net/l173864930/article/details/45035521 http://blog.csdn.net/l173864930/article/details/45035521。 (+谷歌翻译) 谁链接到这个有趣的 Java 和 ELF (arm) 调用挂钩项目:https://github.com/boyliang/AllHookInOne https://github.com/boyliang/AllHookInOne

这并不完全是我想要的,但我会尝试实现一个适合我的需求的用于动态分析的 AOSP 补丁。


我已经成功回答我的问题了。 据我从源代码中可以理解,java 调用有 3 个可能的入口点:

  • ArtMethod::调用 (art/runtime/mirror/art_method.cc)
  • 执行(art/runtime/interpreter/interpreter.cc)
  • DoCall(艺术/运行时/解释器/interpreter_common.cc)

ArtMethod::Invoke 似乎用于反射并使用指向 OAT 代码部分的指针直接调用该方法。 (同样,没有文档,它可能不准确)。

一般执行最终都会调用DoCall。

ART 的一些优化使得 Java 调用的研究变得困难,例如方法内联和直接偏移地址调用。

第一步是禁用这些优化:

在 device/brand-name/model/device.mk 中(在我的例子中,nexus 5 的 device/lge/hammerhead/device.mk ):

将“仅解释”选项添加到 dex2oat。使用此选项,ART 仅编译引导类路径,因此应用程序不会在 OAT 中编译。

PRODUCT_PROPERTY_OVERRIDES := \
    dalvik.vm.dex2oat-filter=interpret-only

第二步是在 art/compiler/dex/frontend.cc 中禁用内联:

取消注释“kSuppressMethodInlined”。

/* Default optimizer/debug setting for the compiler. */
static uint32_t kCompilerOptimizerDisableFlags = 0 |  // Disable specific optimizations
  (1 << kLoadStoreElimination) |
  // (1 << kLoadHoisting) |
  // (1 << kSuppressLoads) |
  // (1 << kNullCheckElimination) |
  // (1 << kClassInitCheckElimination) |
  (1 << kGlobalValueNumbering) |
  // (1 << kPromoteRegs) |
  // (1 << kTrackLiveTemps) |
  // (1 << kSafeOptimizations) |
  // (1 << kBBOpt) |
  // (1 << kMatch) |
  // (1 << kPromoteCompilerTemps) |
  // (1 << kSuppressExceptionEdges) |
  (1 << kSuppressMethodInlining) |
  0;

最后一步是在 art/compiler/driver/compiler_driver.cc 中禁用直接代码偏移调用:

-bool use_dex_cache = GetCompilerOptions().GetCompilePic();
+bool use_dex_cache = true;

通过这些更改,所有不同的调用都将落入 DoCall 函数中,我们最终可以在其中添加目标日志记录例程。

在 art/runtime/interpreter/interpreter_common.h 中,在包含的开头添加:

#ifdef HAVE_ANDROID_OS
#include "cutils/properties.h"
#endif

在 art/runtime/interpreter/interpreter_common.cc 中,在 DoCall 函数的开头添加:

#ifdef HAVE_ANDROID_OS 
  char targetAppVar[92];
  property_get("target.app.pid", targetAppVar, "0");

  int targetAppPID = atoi(targetAppVar);

  if(targetAppPID != 0 && targetAppPID == getpid())
    LOG(INFO) << "DoCall - " << PrettyMethod(method, true);
#endif

为了定位应用程序,我使用一个设置目标 pid 的属性。 为此,我们需要 lib system/core/libcutils,并且该库仅在为真实手机编译 AOSP 时可用(不会干扰当前的 makefile)。
因此该解决方案不适用于模拟器。 (仅猜测,从未尝试过编辑:已确认,“cutils/properties.h”无法添加到模拟器的构建中)。

编译并刷新打补丁的AOSP后,启动一个应用程序,ps | grep 用于查找 PID 并在 root 中设置属性:

shell@android:/ # ps | grep contacts                                       
u0_a2     4278  129   1234668 47356 ffffffff 401e8318 S com.android.contacts

shell@android:/ # setprop target.app.pid 4278

shell@android:/ # logcat
[...]
I/art     ( 4278): DoCall - int android.view.View.getId()
I/art     ( 4278): DoCall - void com.android.contacts.activities.PeopleActivity$ContactsUnavailableFragmentListener.onCreateNewContactAction()
I/art     ( 4278): DoCall - void android.content.Intent.<init>(java.lang.String, android.net.Uri)
I/art     ( 4278): DoCall - void android.app.Activity.startActivity(android.content.Intent)
I/ActivityManager(  498): START u0 {act=android.intent.action.INSERT dat=content://com.android.contacts/contacts cmp=com.android.contacts/.activities.ContactEditorActivity} from uid 10002 on display 0
V/WindowManager(  498): addAppToken: AppWindowToken{3a82282b token=Token{dc3f87a ActivityRecord{c0aaca5 u0 com.android.contacts/.activities.ContactEditorActivity t4}}} to stack=1 task=4 at 1
I/art     ( 4278): DoCall - void android.app.Fragment.onPause()
I/art     ( 4278): DoCall - void com.android.contacts.common.list.ContactEntryListFragment.removePendingDirectorySearchRequests()
I/art     ( 4278): DoCall - void android.os.Handler.removeMessages(int)
I/art     ( 4278): DoCall - void com.android.contacts.list.ProviderStatusWatcher.stop()
I/art     ( 4278): DoCall - boolean com.android.contacts.list.ProviderStatusWatcher.isStarted()
I/art     ( 4278): DoCall - void android.os.Handler.removeCallbacks(java.lang.Runnable)
I/art     ( 4278): DoCall - android.content.ContentResolver com.android.contacts.ContactsActivity.getContentResolver()
I/art     ( 4278): DoCall - void android.content.ContentResolver.unregisterContentObserver(android.database.ContentObserver)
I/art     ( 4278): DoCall - void android.app.Activity.onPause()
I/art     ( 4278): DoCall - void android.view.ViewGroup.drawableStateChanged()
I/art     ( 4278): DoCall - void com.android.contacts.ContactsActivity.<init>()
I/art     ( 4278): DoCall - void com.android.contacts.common.activity.TransactionSafeActivity.<init>()
I/art     ( 4278): DoCall - void android.app.Activity.<init>()
I/art     ( 4278): DoCall - void com.android.contacts.util.DialogManager.<init>(android.app.Activity)
I/art     ( 4278): DoCall - void java.lang.Object.<init>()
[...]

当它结束时:

shell@android:/ # setprop target.app.pid 0

Voilà !

从用户的角度来看,过载并不明显,但 logcat 很快就会被填满。

PS:文件路径和名称与Android 5版本(Lollipop)匹配,它们可能与高级版本不同。

PS':如果有人想要打印方法的参数,我建议它查看 art/runtime/utils.cc 中的 PrettyArguments 方法,并在代码中的某处找到一些实际的实现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android应用程序:java / JNI调用挂钩策略 的相关文章

  • static >

    我有以下带有一个静态方法的类 public class Helper public static
  • 用于挂钩进程函数的 Linux 模块

    我有一个问题 也许你有一些关于这方面的信息 我想在运行进程中挂钩套接字接收函数 recv 并修改传入数据 我怎么知道 我可以使用内核模块来做到这一点 但我找不到有关如何执行此类挂钩的信息 我尝试过其他方法 例如 Netfilter ipta
  • 如何在添加到 Android AOSP 的自定义项目中设置文件权限

    我添加到 AOSP 设备所有者 APP 在packages apps myapp 创建目录 将 myapp apk device owner xml 复制到packages apps myapp 创建Android mk LOCAL PAT
  • 如何将第 3 方库添加到 Android AOSP 构建中?

    我正在尝试将 Jackson JSON 库添加到我的 AOSP 项目中 我可以编译我的项目并将其刷新到手机 但出现运行时错误 E JavaBinder 1689 java lang NoClassDefFoundError Failed r
  • 调用 GetPointerFrameTouchInfo 时出现错误 998(对内存位置的访问无效)[重复]

    这个问题在这里已经有答案了 我正在尝试致电GetPointerFrameTouchInfo函数来获取指针计数 但该函数似乎失败了 错误 998 对内存位置的访问无效 知道为什么会发生这种情况以及如何解决它吗 我试图在钩子过程中调用相同的方法
  • 在 Mac OS X 中获取进程创建通知

    我正在尝试为 Mac OS X 编写 kext 当任何进程启动时都会收到通知 在 Windows 中 您可以通过调用 PsSetLoadImageNotifyRoutine 并指定在进程启动时调用的回调来完成此操作 这是有记录的方式 它适用
  • 从活动顶点数组生成平滑法线

    我正在尝试通过挂钩 OpenGl 调用来破解和修改旧版 opengl 固定管道游戏的多个渲染功能 而我当前的任务是实现着色器照明 我已经创建了一个适当的着色器程序 可以正确照亮大部分对象 但该游戏的地形是在没有提供正常数据的情况下绘制的 游
  • Android Twilio 视频通话,唤醒应用程序并带到前台

    我正在尝试使用 Twilio Video Call 提供本机视频通话体验 这是场景 人 AAA 称人 BBB BBB 没有打开应用程序 在后台或前台 应用程序处于终止状态 手机甚至可能被锁定 当来自 AAA 的电话到达时 应用程序将打开 并
  • 如何列出运行时函数的所有调用?

    有什么办法可以list 在VS中显示 写入文件 所有来电者 对象 函数 一个函数的当程序运行时 可能使用调试器 我需要record 所有通话 包括来电者 一个函数的从计划启动到终止 简单扫描源代码或二进制文件不做这份工作因为该程序可以作为服
  • C# 调用返回结构的 C++ DLL 函数

    我有一个 C dll 它定义了一个结构体和一个 dll 调用 如下所示 typedef const char FString typedef struct FString version FString build no FString b
  • 使用主题函数在 body 标记后插入代码

    我试图在开头添加一段代码everyDrupal 站点中的页面 因为我有不止一个page模板 我想以编程方式执行此操作 但没有成功 我还是个新手 虽然我了解了钩子 主题函数等的要点 但我只是想不出实现这一目标的正确方法 到目前为止我已经覆盖了
  • 部分渲染冗余方法调用

    我知道 JSF 可能会调用托管 bean 方法几次 即使它在 xhtml 中只调用一次 我知道这是由于编码 方法造成的 我想请您向我解释一下以下案例 我有一个类似这样的 JSF 文件
  • CALL指令是否总是将EIP指向的地址压入堆栈?

    x86架构中函数调用时是否存在返回地址不入栈的情况 No CALL根据定义 将在跳转到目标地址之前将返回地址压入堆栈 该返回地址是EIP or RIP sizeof call instruction 通常为 5 个字节 英特尔 64 和 I
  • 构建 gradle 系统应用程序作为 AOSP 构建的一部分

    我有一个基于 AOSP 的自定义 ROM 并且正在开发一个系统应用程序 该应用程序在 ROM 构建期间打包 就像任何其他系统应用程序一样 是否可以将此应用程序切换为 gradle 样式应用程序 并在 AOSP 构建期间使用 gradle 构
  • 在java中获取调用层次结构

    我在追踪错误时遇到了很大的困难 了解哪个方法调用了某个方法会很有帮助 有没有一种简单的方法可以从java获取调用层次结构 Java 是应用程序的一小部分 因此我无法在 eclipse net beans 中编译和运行整个应用程序 因此我无法
  • 低级键盘钩子不在 UI 线程上

    我想为键盘挂钩创建一个好的库 我使用 SetWindowsHookEx 方法 我注意到如果我的应用程序的主线程繁忙 则应在任何系统 KeyDown 事件中调用的方法 hookProc 不会执行 我认为钩子应该这样制作 以便另一个线程负责它
  • 无论如何,要控制宋何时选择Android.bp,何时不选择?

    使用新的构建系统 即 Soong 安卓取代Android mk with Android bp 还有 Android Q 及以上版本 Soong将选择所有Android bp文件 无论所有文件都存在于何处 早些时候 对于 2 级和 3 级模
  • 退出设备上的 system.img

    我正在为我们部署给客户的设备 LG p509 Optimus 1 开发自动应用程序更新解决方案 我们可以控制这些设备 并且目前在它们上安装自定义内核 但不是完整的自定义 ROM 由于我们试图在设备上自动更新我们的应用程序 因此我们需要由我们
  • 现代 C++ 编译器是否能够在某些情况下避免调用 const 函数两次?

    例如 如果我有以下代码 class SomeDataProcessor public bool calc const SomeData d1 const SomeData d2 const private Some non mutable
  • 詹金斯钩子不工作 - 詹金斯位桶

    您好 我正在使用 jenkins 和 bitbucket 当我向 bitbucket 存储库提交任何内容时 我想触发 jenkins 中的构建 在詹金斯 我创建了一个名为test 1 在配置部分Build Triggers我勾选的部分Tri

随机推荐