如何反编译 android 中 /data/dalvik-cache/arm 下的文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何反编译 android 中 /data/dalvik-cache/arm 下的文件相关的知识,希望对你有一定的参考价值。

  所有的 apk 内包含一个 classes.dex 文件。在 Dalvik上,apk包里的 dex文件在安装的时候会通过 dexopt 转化成另一个格式,叫odex(Opitimized dex),然后存在 /data/dalvik-cache里面,如:

  /data/dalvik-cache/data@app@com.wochacha-1.apk@classes.dex
  虽然文件后缀还是 .dex,但是这个dex和apk内的那个已经不一样了。这个文件是针对当前机器的硬件对 dex 文件进行了定制化,也就是说把这个放到别的设备上,不一定能运行。

  PS: 在要编译 rom 的时候,如果参数加上 "WITH_DEXPREOPT=true",会在 /system/app/ 下同时生成 .apk 和 .odex 文件(注意,这里后缀又用的 .odex,但实际上和系统在 /data/dalvik-cache/ 下的 .dex文件是一样的)

  ART

  在 ART上,apk 包里的 dex文件在安装的时候通过 dex2oat,也会生成一个后缀为 .dex 的文件,放在 /data/dalvik-cache中,如:

  /data/dalvik-cache/arm/system@app@Bluetooth@Bluetooth.apk@classes.dex
  /data/dalvik-cache/arm64/system@vendor@app@ims@ims.apk@classes.dex
  这个文件后缀叫 .dex ,但是这个文件又不一样了,这个既不是 dex 也不是 odex,用 dex2jar 的无法进行反编译的。文件格式也完全不同,因为这其实就是一个实打实的 elf文件,这个文件已经可以直接在机器上运行了。

  为何 pm.jar 是空的?

  首先来了解一下 ROM 的编译选项,看一下编译的时候能做什么事情, 大致了解就行了 。

  编译选项

  WITH_DEXPREOPT

  使能编译时生成 OAT,避免第一次开机时编译耗时,但会增大 system分区的空间消耗

  DONT_DEXPREOPT_PREBUILTS

  使能后,将不会对 android.mk中包含了 include $(BUILD_PREBUILT)的 Apk进行 oat,例如 Gmail,它很可能会在后期通过商店自行升级,而升级后系统中的 oat文件则没有意义了,但又无法删除,会造成空间的浪费(oat比dex文件要大)

  WITH_DEXPREOPT_BOOT_IMG_ONLY

  仅仅针对 boot.img进行oat优化(boot.img中包含 boot.art和 boot.oat)

  LOCAL_DEX_PREOPT ture|false|nostripping

  可用于各个 Android.mk,对每个 package进行单独配置,当设置为 true时,dex文件将会从 apk中剔除,如果不想剔除可使用 nostripping WPRODUCT _DEX PREOPT_*

  WPRODUCT__DEX_PREOPT_*

  PRODUCT_DEX_PREOPT_BOOT_FLAGS

  这里的参数将会传至 dex2oat,控制 boot.img的编译优化行为。

  PRODUCT_DEX_PREOPT_DEFAULT_FLAGS

  控制除 boot.img 外,其他(如 jar, apk)的 OAT编译行为 例如:

  PRODUCT_DEX_PREOPT_DEFAULT_FLAGS := --compiler- filter=interpret-only
  $(call add-product-dex-preopt-module- config,services,--compiler-filter=space)
  WITH_DEXPREOPT_PIC ture|false

  使能 position-independent code,这样在dex2oat编译生成的 odex文件在运行时将不必再从 /system 下拷贝到 /data/dalvik-cache/ 目录下, 可以节省 /data 空间

  WITH_ART_SMALL_MODE true|false

  设置为 true 时,将只编译处于 boot classpath 里的类,其他的均不编译,这样既能加快第一次开机时间,因为大部分必要的类已经编译过了; 同时也能节省不少空间,因为 APP 都未进行编译。缺点是可能损失一性能,这可能要平时觉察不出,但在跑分软件上会有所体现

  编译选项的经典配置

  为了提高第一次开机速度,WITH_DEXPREOPT是必须使能的,这样则在编译阶段会完成 dex2oat的操作,避免在开机时间去做这个转码,节省了开机时间(6min以上缩短2min内)。

  但会引起一个缺点,那就是 apk中还是包含了 class.dex(dexopt生成的),同时在对应的apk文件夹中又生成了已经转码成oat的 class.odex(dex2oat生成的),相当于这部分重复,造成了大量的空间浪费。

  为了把 apk包里的 class.dex去除,节省空间,可以打开 DEX PREOPT DEFAULT := ture。

  然而,这样开机速度是快了,而且节省了不少system空间,但开机后,我们会发现即使在 system中已经存在 class.odex的 apk,第一次开机后还是会在 /data下面生成 class.odex,如data/dalvik-cache/arm64/system@app@Music@Music.apk@classes.dex,这是何解?原来 Google为了提高安全性,在每一台机器开机时都会在之前的机器码加一个随机的偏移量,这个偏移量是随机的,每台机器都不相同,而 data分区下的这些文件就是从 system下的 class.odex加上偏移而来。
参考技术A 使用oatdump,即可反编译这个文件,其实虽然/data/dalvik-cache/arm/包名@base.apk@classes.dex是以.dex结尾的,但实际它是一个oat文件,并不是dex文件。oat文件是ART虚拟机下的,一个ELF文件。而oatdump的使用方法,大致是adb shell oatdump --oat-file=(路径)

如何使 Google Play 服务 API 和 Firebase API 的 API javadocs 出现在 Android Studio 中,而不是没有文档的反编译类?

【中文标题】如何使 Google Play 服务 API 和 Firebase API 的 API javadocs 出现在 Android Studio 中,而不是没有文档的反编译类?【英文标题】:How to make API javadocs for Google Play Services APIs and Firebase APIs show up in Android Studio rather than decompiled classes with no docs? 【发布时间】:2016-11-11 22:54:32 【问题描述】:

当我点击我在 Android Studio 的 android 项目中使用的任何 Google Play Services API 或 Firebase API 时,IDE 会将我带到该类的反编译版本,其中变量名被混淆并且没有任何方法的文档。任何想法如何直接在 IDE 中查看文档?

我怀疑原因是播放服务和 firebase 服务不是开源的,我对看到 impls 没意见,我知道他们想要保护它。但我真的会从直接在 IDE 中查看文档而不是使用 alt-tabbing 浏览器中受益。感谢您的帮助。

【问题讨论】:

复制:***.com/q/38141103/435605 我认为这个答案比链接问题中的答案质量更高 【参考方案1】:

Javadocs 确实应该与客户端库一起分发。我们在 Google 内部对此有一个未解决的问题,但我没有关于何时提供适当解决方案的时间表。但是,我可以为您提供一种解决方法,您可以将其应用于您的项目。这不是一个很好的解决方案,但它是一些东西。

在我的 OSX 机器上,Android SDK 安装在这里:

/Users/[myusername]/Library/Android/sdk

Play Services 和 Firebase javadocs 的本地副本在这里(您的可能会有所不同):

/Users/[myusername]/Library/Android/sdk/extras/google/google_play_services/docs/reference/

您实际上可以通过以下过程将此路径附加到 Android Studio 中的 Firebase 客户端库:

    在“外部库”下的项目视图中查找 Firebase/Play 客户端库。 右键单击您最感兴趣的 javadoc。例如,对于 Firebase 实时数据库,您可以使用“firebase-database-9.2.0”。 在上下文菜单中,单击底部的库属性。 在“库属性”窗口中,有一个带有 + 号的按钮。点击那个。这使您可以将 javadoc 路径附加到该库中的类。 从上方导航/粘贴您的 javadoc 路径到对话框中。 在下一个对话框中,告诉它“JavaDocs”。

现在,当您为该库中的类调用 javadoc 时,您会看到它。但是,您必须为每个需要 javadoc 的库执行此操作。

如果您由于某种原因没有安装本地 javadoc,您可以附加 javadoc 的远程 url。为此,请使用下方带有小地球的加号按钮,然后粘贴 javadoc url。对于 Firebase,这是 https://firebase.google.com/docs/reference/android,对于 Play Services,这是 https://developers.google.com/android/reference/

完成所有这些手动工作并不好,但至少它可以让您在 IDE 中获得 javadoc。

如果您想编写一个脚本来为您使用的所有内容附加此内容,请知道此过程本质上只是修改 .idea/libraries 下的文件。当您在 IDE 中进行更改时,您可以很容易地观察到被修改的 javadoc XML 元素,如果需要,您可以自己编写/编辑更改。

【讨论】:

非常感谢道格!谷歌任务在任何问题跟踪系统上都是公开可见的,还是全部是内部的?我想“关注”该领域的发展,即使目前还没有固定的交货日期 不幸的是,没有像这样的 Play 服务或 Firebase 错误的跟踪器(希望有!)。如果您将其记录为 firebase.google.com/support/contact/bugs-features 的错误,这实际上非常有帮助 - 这也应该在内部冒泡,您可以从自己的错误报告的角度跟踪它。 完成了,但是我刚刚意识到我将其记录为“功能请求”而不是“错误”...可能无助于确定优先级,但现在无法更改... 应该没什么大不了的,不过多角度记录就好了。谢谢! 在线 javadocs URL 现已更改为 firebase.google.com/docs/reference/android【参考方案2】:

就我而言,添加此https://firebase.google.com/docs/reference/android/packages 有效。

【讨论】:

以上是关于如何反编译 android 中 /data/dalvik-cache/arm 下的文件的主要内容,如果未能解决你的问题,请参考以下文章

如何反编译android应用并重新打包

如何反编译android应用并重新打包

IDEA中使用默认反编译出现/* compiled code*/

如何防止Unity3D代码被反编译

如何防止Unity3D代码被反编译

如何从 google play store 反编译一个 android 应用程序