首页
论坛
课程
招聘
[原创][原创][原创]小米学安卓逆向一 - NDK开发(2)
2021-5-12 22:27 8114

[原创][原创][原创]小米学安卓逆向一 - NDK开发(2)

2021-5-12 22:27
8114

前言

在学习NDK的过程中,我的心态有些浮躁,心里在想这其实不就是开发的内容么,就想跳过。但是等我冷静下来一步步学习NDK的时候,才逐渐认识到NDK开发的重要性。

 

我在看雪上找了大神的文章,发现只要涉及到脱壳和分析时,几乎无可避免的要接触到so、JNI、NDK这些名词,学习NDK的意义则不言而喻。

 

图片描述
图片描述
图片描述

 

以下知识点会比较散,纯粹记录和思考总结。

NDK的优缺点

  • 优点:C/C++编写,安全、可复用程度高
  • 缺点:开发难度高,要熟悉Android底层、C/C++,开发效率没有Java高,稳定性难以保证,没有高级语言的gc回收机制,可能会内存泄露这样比较难以发现的问题。

Android环境下Java函数运行模式

JVM将java代码编译成class文件,然后android系统利用dx对class进行编译输出为Dalvik字节码,也就是dex文件,最后进行签名和配置生成apk。

1、纯解释模式下运行

纯粹性运行时读取dex文件并解释为机器码。

2、JIT模式

dalvik下,在Android4.4之后引入了JIT模式,每遇到一个新类,JNI将其编译为相当精简的汇编代码,优化执行效率,但JIT不是针对所有类,只是针对经常使用到的类,才进行编译优化以此提高运行效率。

3、AOT模式

art下,AOT(运行前编译),在对程序进行安装时,将应用全部编译成机器码,实现真正的本地应用,省掉编译时间。
但是也有不足,安装后的应用存储变大了,安装时间也很变久,但是和流畅的运行体验相比都是小事。

4、AOT、JIT、配置文件引导型编译

从Android 7.0(代号 Nougat,简称 N)开始结合使用 AOT、即时 (JIT) 编译和配置文件引导型编译。

  • 最初安装应用时不进行任何AOT编译,前几次运行时,会对经常使用的方法进行JIT编译,缓存机器码。
  • 当应用闲置时或者充电时,编译守护程序运行, 以便根据在应用前几次运行期间生成的配置文件对常用代码进行 AOT 编译。
  • 下一次重新启动应用时,将会使用配置文件引导型代码,避免在运行时对已经编译的方法再次进行JIT编译,在使用过程中的JIT编译后的方法会显示在配置中,后续AOT对这些方法进行翻译,变成本地机器码。

也就是说,在Android7.0以后,Java函数的状态具有了不确定因素。

5、oatdump

oatdump是android自带的工具,能够反编译经过dex2oat过程的oat文件。
vdex包含原始的dex文件内容,当设备首次加载应用,一定会经过dex2oat过程。

 

我们新建一个native C++工程命名为performtest01,只用java写一个for循环变量相加的逻辑,然后安装该应用并run运行。我们去找它的oat文件。
图片描述
对照classes.dex文件和base.vdex文件,发现base.vdex头部多了一些内容。
图片描述
图片描述
将base.vdex头部内容去掉并将后缀改为dex,可以发现base.dex已经被成功解析为dex文件,还原dex内容,脱壳可借鉴。

 

图片描述
图片描述

 

我们在android shell运行

1
oatdump --oat-file=base.odex >> base.txt

图片描述
均翻译为smali指令。

JNI数据类型

JNI调用Java代码,于是数据类型需要和Java一一对应。大体分为两种:基本数据类型,有8种;引用类型,jclass、jobject、jstring和jthrowable。
详情请见:
图片描述

 

下一节学习java反射思维和使用JNI调用java代码,待续...


[公告] 欢迎大家踊跃尝试高研班11月试题,挑战自己的极限!

最后于 2021-5-12 22:30 被miniboom编辑 ,原因: 少写了前提条件,dalvik和art环境
收藏
点赞5
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回