文章目录

  • 一、前言,发现新玩意
  • 二、.dex、.odex与.oat文件介绍
    • 1、dex文件
    • 2、vdex文件
    • 3、odex文件
    • 4、oat文件

一、前言,发现新玩意

最近Unity项目打出的Android包在红米Note4真机上运行闪退了,查看日志如下:

07-28 17:56:49.623  7368  7368 D YSDK d.OnSupport:  Device OAID loadSuccesstrue
07-28 17:56:49.623  7368  7416 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x1 in tid 7416 (YSDK_TEMP_THREA)
07-28 17:56:49.624  7368  7368 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x1 in tid 7368 (mgp.linxinfagame)
07-28 17:56:49.624  7368  7368 I libc    : Another thread contacted debuggerd first; not contacting debuggerd.
07-28 17:56:49.646  7368  7418 I MID     : >>>   queryMatchContentProviders size:1
07-28 17:56:49.647  7368  7418 D MID     : >>>   appPrivateMidMap size:0,content:
07-28 17:56:49.651  7368  7397 I XgStat  : [tpush.working.thread(590): null:-1] - read mid from sharedPreferences, key=__MTA_DEVICE_INFO__1000001
07-28 17:56:49.652  7368  7397 I XgStat  : [tpush.working.thread(590): null:-1] - read mid from sharedPreferences, key=__MTA_DEVICE_INFO__3
07-28 17:56:49.677   637   637 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
07-28 17:56:49.677   637   637 F DEBUG   : Build fingerprint: 'Xiaomi/prada/prada:6.0.1/MMB29M/V10.2.2.0.MCECNXM:user/release-keys'
07-28 17:56:49.677   637   637 F DEBUG   : Revision: '0'
07-28 17:56:49.677   637   637 F DEBUG   : ABI: 'arm'
07-28 17:56:49.677   637   637 F DEBUG   : pid: 7368, tid: 7416, name: YSDK_TEMP_THREA  >>> com.tencent.tmgp.linxinfagame <<<
07-28 17:56:49.677   637   637 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1
07-28 17:56:49.688  3771  3771 E klogd   : 6>[45073.921305] type=1400 audit(1595930209.671:1826): avc: denied { search } for pid=637 comm="debuggerd" name="com.tencent.tmgp.linxinfagame" dev="dm-1" ino=81623 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
07-28 17:56:49.692   637   637 F DEBUG   :     r0 710f98f8  r1 00000001  r2 ddf6feb4  r3 00000000
07-28 17:56:49.692   637   637 F DEBUG   :     r4 70a40770  r5 130c27a0  r6 00000001  r7 130c29f0
07-28 17:56:49.693   637   637 F DEBUG   :     r8 12c5bb00  r9 ab5de3b0  sl 12c7fb00  fp ddf7010c
07-28 17:56:49.693   637   637 F DEBUG   :     ip 0000f682  sp ddf6fff0  lr e1565349  pc 7479d05c  cpsr 000f0030
07-28 17:56:49.693   637   637 F DEBUG   :
07-28 17:56:49.693   637   637 F DEBUG   : backtrace:
07-28 17:56:49.693   637   637 F DEBUG   :     #00 pc 7479d05c  /data/dalvik-cache/arm/system@framework@boot.oat (offset 0x256a000)
07-28 17:56:49.694   637   637 F DEBUG   :     #01 pc 01211347  /data/app/com.tencent.tmgp.linxinfagame-1/oat/arm/base.odex (offset 0x9fd000)
07-28 17:56:49.695  3771  3771 E klogd   : 6>[45073.937028] type=1400 audit(1595930209.681:1827): avc: denied { search } for pid=637 comm="debuggerd"
name="com.tencent.tmgp.linxinfagame" dev="dm-1" ino=81623 scontext=u:r:debuggerd:s0 tcontext=u:object_r:app_data_file:s0:c512,c768 tclass=dir permissive=0
07-28 17:56:49.901  1931  1931 W ResourceType: No package identifier when getting name for resource number 0x00000000
07-28 17:56:49.979  3005  3005 D wpa_supplicant: wlan0: Control interface command 'SIGNAL_POLL'
07-28 17:56:49.994  3005  3005 D wpa_supplicant: CTRL-DEBUG: global_ctrl_sock-sendto: sock=13 sndbuf=229376 outq=0 send_len=48
07-28 17:56:50.320  1512  7424 I am_crash: [1512,0,com.tencent.tmgp.linxinfagame,982040132,Native crash,Segmentation fault,unknown,0]

可以看到触发了一个致命信号SIGSEGV,最终crash闪退了。
日志里输出了闪退时的调用堆栈(backtrace):

07-28 17:56:49.693   637   637 F DEBUG   : backtrace:
07-28 17:56:49.693   637   637 F DEBUG   :     #00 pc 7479d05c  /data/dalvik-cache/arm/system@framework@boot.oat (offset 0x256a000)
07-28 17:56:49.694   637   637 F DEBUG   :     #01 pc 01211347  /data/app/com.tencent.tmgp.linxinfagame-1/oat/arm/base.odex (offset 0x9fd000)

这里出现了两个奇怪的文件:.oat.odex,我们知道,Unity打出的Android包(.apk),里面是有一个classes.dex文件的,如下

那么,.dex.odex.oat有什么联系呢?

二、.dex、.odex与.oat文件介绍

1、dex文件

在我们写Java代码的时候,生成的文件是.java文件。
对于PC上的java虚拟机(JVM)运行的是.class

.java文件转成.class文件,需要jdk工具,转换命令:

javac xxxx.java

关于JavaEE和JavaSE
JavaEE:Java Enterprise Edition,Java企业版,多用于企业级开发,包括web开发等等。企业版本帮助开发和部署可移植、健壮、可伸缩切安全的服务端Java应用。Java EE是在JavaSE的基础上构建的他提供Web 服务、组建模型、管理和通信API.可以用来实现企业级的面向服务体系结构(service-oriented architecture,SOA)和web2.0应用程序。
JavaSE:通常是指Java Standard Edition,Java标准版,就是一般Java程序的开发就可以(如桌面程序),可以看作是JavaEE的子集。它允许开发和部署在桌面、服务器、嵌入式环境和实施环境中使用的Java应用程序。JavaSE 包括支持Java Web服务开发的类,并为Java Platform,Enterprise Edition(Java EE)提供基础。

关于JVM虚拟机
为了使代码和平台无关,JAVA开发了 JVM,即 Java 虚拟机。它为每一个平台开发一个 JVM,也就意味着 JVM 是和平台相关的。Java 编译器将 .java 文件转换成 .class文件,也就是字节码。最终将字节码提供给 JVM,由 JVM 将它转换成机器码。

Android端,Android上的Davlik虚拟机是运行.dex。所以还得将.class转成dex文件,即dex文件就是Android Dalvik虚拟机运行的程序。
.class转成dex文件 需要使用dx.bat工具,dx.bat工具在Android SDKbuild-tools目录中可以找到,转换命令:

dx --dex --output = C:\output.dex C:\test

其中C:\output.dex表示输出文件,C:\test表示原文件的路径名。

关于Dalvik虚拟机
Dalvik是Google公司自己设计用于Android平台的虚拟机,.dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。Dalvik 经过优化,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个Dalvik 应用作为一个独立的Linux 进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
很长时间以来,Dalvik虚拟机一直被用户指责为拖慢安卓系统运行速度不如IOS的根源。
2014年6月25日,Android L 正式亮相于召开的谷歌I/O大会,Android L 改动幅度较大,谷歌将直接删除Dalvik,代替它的是传闻已久的ART。

关于ART
Dalvik 使用 JIT(Just in time)编译,而 ART 使用 AOT(Ahead of time)编译。Android 7.0 向 ART 中添加了一个 just-in-time(JIT)编译器,这样就可以在应用运行时持续的提高其性能。
ART 和 Dalvik 一样使用的是相同的 DEX 字节码。编译好的应用如果使用 ART 在安装时需要额外的时间用于编译,同时还需要更多的空间用于存储编译后的代码。
由于 ART 直接运行的是应用的机器码(native execution),它所占用的 CPU 资源要少于 使用 JIT 编译的 Dalvik。由于占用较少的 CPU 资源也就消耗更少的电池资源。

关于JIT (Just In Time )
使用 Dalvik JIT 编译器,每次应用在运行时,它实时的将一部分 Dalvik 字节码翻译成机器码。在程序的执行过程中,更多的代码被被编译并缓存。由于 JIT 只翻译一部分代码,它消耗的更少的内存,占用的更少的物理存储空间。

关于AOT(Ahead Of Time)
ART 内置了一个 Ahead-of-Time 编译器。在应用的安装期间,他就将 DEX 字节码翻译成机器码并存储在设备的存储器上。这个过程只在将应用安装到设备上时发生。由于不再需要 JIT 编译,代码的执行速度要快得多。

常规的反编译dex流程:
1、拿到apk文件,然后解压 ,得到 class.dex 文件
2、用dex2jar 把 class.dex 还原成 classes-dex2jar.jar 文件
3、用 jd-gui.exe 把 classes-dex2jar.jar 文件打开,就可以看到源码了。

2、vdex文件

在讲odex之前,需要先讲vdexAndroid O开始加入的)
package直接转化的 可执行二进制码 文件:
1.第一次开机就会生成在/system/app/<packagename>/oat/下;
2.在系统运行过程中,虚拟机将其 从“/system/app”copy“/data/davilk-cache/”

为何要搞出个vdex文件
目的不是为了提升性能,而是为了避免不必要的验证Dex 文件合法性的过程,例如首次安装时进行dex2oat时会校验Dex 文件各个section的合法性,这时候使用的compiler filter 为了照顾安装速度等方面,并没有采用全量编译,当app盘启动后,运行一段时间后,收集了足够多的jit 热点方法信息,Android会在后台重新进行dex2oat, 将热点方法编译成机器代码,这时候就不用再重复做验证Dex文件的过程了,

3、odex文件

odex是优化版的dex
Android N之前,Dalvik虚拟机执行程序dex文件前,系统会对dex文件做优化,生成可执行文件odex,保存到data/dalvik-cache目录,最后把apk文件中的dex文件删除。

Android O之后,odex是从vdex这个文件中 提取了部分模块生成的一个新的 可执行二进制码 文件 , odexvdex中提取后,vdex的大小就减少了。具体过程:
1.第一次开机就会生成在/system/app/<packagename>/oat/
2.在系统运行过程中,虚拟机将其 从“/system/app”copy“/data/davilk-cache/”
3.odex + vdex = apk的全部源码 (vdex并不是独立于odex的文件,odex + vdex才代表一个apk

4、oat文件

ART虚拟机使用的是oat文件,oat文件是一种Android私有ELF文件格式,它不仅包含有从DEX文件翻译而来的本地机器指令,还包含有原来的DEX文件内容。APK在安装的过程中,会通过dex2oat工具生成一个OAT文件。对于APK来说,oat文件实际上就是对odex文件的包装,即oat=odex,而对于一些framework中的一些jar包,会生成相应的oat尾缀的文件,如system@framework@boot-telephony-common.oat

Android的.dex、.odex与.oat文件扫盲相关推荐

  1. Android执行时ART载入OAT文件的过程分析

    在前面一文中,我们介绍了Android执行时ART,它的核心是OAT文件.OAT文件是一种Android私有ELF文件格式,它不仅包括有从DEX文件翻译而来的本地机器指令.还包括有原来的DEX文件内容 ...

  2. 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | exec_utils.cc 中执行 Dex 编译为 Oat 文件的 Exec 和 ExecAndReturnC函数 )

    文章目录 前言 一.exec_utils.cc#Exec 函数分析 二.exec_utils.cc#ExecAndReturnCode 函数分析 前言 在上一篇博客 [Android 逆向]ART 脱 ...

  3. android oat如何提取dex文件字节码,Android: 使用oatdump反编译oat文件

    网上经常看到有通过apktool将apk中的dex反编译成smali格式的文件,以便分析功能实现与破-解,确没怎么看到oat文件反通过oatdump反编译的,所以就写了一篇这样的文档.声明一下oat文 ...

  4. android oat文件,OAT格式文件 如何打开OAT文件 OAT是什么格式的文件 用什么打开 - The X 在线工具...

    Android操作系统会创建一个.OAT 文件,以加快Android应用程序(.APK 文件)的加载时间.安装应用程序时,Android会自动优化应用程序数据并创建相应的.OAT 文件.Android ...

  5. android运行时ART加载OAT文件解析

    在前面一文中,我们介绍了Android运行时ART,它的核心是OAT文件.OAT文件是一种Android私有ELF文件格式,它不仅包含有从DEX文件翻译而来的本地机器指令,还包含有原来的DEX文件内容 ...

  6. ART加载OAT文件的分析

    本文对老罗博客http://blog.csdn.net/luoshengyang/article/details/39307813 进行学习理解,针对android6.0系统源码,连个人理解带复制粘贴 ...

  7. Android[art]-Android dex,odex,oat,vdex,art文件结构学习总结

    参考学习博客: Android Dex文件格式(一):https://blog.csdn.net/p312011150/article/details/80501690 dex文件解析(第三篇) :h ...

  8. Android dex、odex、oat、vdex、art区别

    1.dex java程序编译成class后,dx工具将所有class文件合成一个dex文件,dex文件是jar文件大小的50%左右.2.odex(Android5.0之前)全称:Optimized D ...

  9. 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | oat_file_assistant.cc 中涉及的 oat 文件生成流程 )

    文章目录 前言 一.dalvik_system_DexFile.cc#DexFile_openDexFileNative 函数分析 二.oat_file_manager.cc#OpenDexFiles ...

最新文章

  1. 安装setuptools与pip
  2. 程序员必备技能-科学砍需求
  3. 谷歌的网页排序算法(PageRank Algorithm)
  4. feedback for last final year project meeting
  5. gitlab ci 自动化部署_前端gitLab加jenkins自动化构建和部署,以及服务器常用的linux命令行操作,免密登录...
  6. 【Go API 开发实战】Go API 开发实战教程简介(1-7)
  7. 1.7 ConcurrentHashMap增删改查
  8. JavaScript强化教程—— RegExp 对象
  9. Vue前后端对接时判断是否与后端连接成功
  10. windows事件id大全_技术转载 || springboot+redis做过期事件通知业务
  11. https提供安全的web通讯
  12. UrlRewrite 的配置和使用总结
  13. DSP SRIO接口设计
  14. OpenCalib: 自动驾驶多传感器的一个开源标定工具箱
  15. 关于培训机构~程序员培训
  16. html中img的title属性值,img标签中alt属性和title属性的区别是什么?
  17. 如何绘制四线3格拼音
  18. java程序cpu突然飚高_fullGC 频繁导致CPU飙高
  19. win7网上邻居_win7网上邻居寻找教程
  20. oracle 数据库表的字段类型修改为clob类型报错及解决方法

热门文章

  1. java swt 几种布局_实战SWT布局
  2. Timsort 介绍(listsort.txt 翻译)
  3. VMware Server V1.04VMCN绿色精简英文版
  4. 怎么查oracle ocm证书,Oracle OCM认证
  5. 路由选路java,java基于蚁群算法路由选择可视化动态模拟-开题报告
  6. Markdown基础语法教程
  7. 多模Zigbee, Thread,BLE芯片的未来趋势
  8. 一个 SAP 成都研究院开发工程师的2021年度总结:既没有厚积,也未能薄发
  9. 关于提出神经网络概念的McCulloch和Pitts
  10. mysql insert into values select from_mysql中复制表数据(select into from和insert into select)...