首先要清楚,odex只是对代码段(我将dex文件与elf文件类比,大家都将执行文件分成不同的段)作优化,而其它用于类反射信息的段都应用原来的dex,所以odex文件内部还包含了一个dex。

打开一个dex或一个odex文件,就是要将其中用于类反射的信息加载到虚拟机运行时中。对于打开一个odex文件,目的也是要将其中包含的dex部分的信息进行加载。

dalvik(libdvm.so)打开dex文件,实质就是要将dex里的反射信息加载到一个DexFile组织的结构体。这个结构有一个查找表,DexClassLookup。这个结构不直接被 libdvm.so 使用,而是由一个上层的DvmDex代替,为libdvm.so其它函数调用使用。但这个DvmDex不被JNI层,也就是libdvm.so最接近java的一层所直接使用,这里有一个DexOrJar结构体关联DvmDex,DexOrJar为最上层可寻找到的对象,并且插入到hash表中。

DexOrJar,JNI 层

DvmDex,libdvm 内部函数

DexFile,最后的执行委托处

对于dalvik.system.DexFile.openDexFile,它的native实现Dalvik_dalvik_system_DexFile_openDexFile的工作,就是调用libdvm内部相关的函数完成,从dex文件加载进DexFile,分配DvmDex关联DexFile,最后用一个DexOrJar关联DvmDex,并将DexOrJar放入hash表中。

我们c/c++则可以直接绕开java层或jni,直接去调用libdvm.so的内部函数去进行打开,以及打开后的使用。这些内部函数使用的是DvmDex。

在内部支持的打开函数里面,最上层的是dvmRawDexFileOpen,也就是Dalvik_dalvik_system_DexFile_openDexFile直接调用的内部函数。这个函数完成了比较多的事,如创建odex,优化dex进odex,然后才是实质上的打开。

实质上去打开dex的内部函数分别有dvmDexFileOpenFromFd以及dvmDexFileOpenPartial。dvmDexFileOpenFromFd的参数是odex的文件描述符,dvmDexFileOpenPartial的参数是odex或dex的映像。这两个函数都会返回DvmDex。并且最终使用dexFileParse实质地将dex的反射内容加载进DexFile。

dvmRawDexFileOpen,最上层的内部打开函数

dvmDexFileOpenPartial和dvmDexFileOpenFromFd,返回DvmDex,可用于其它内部函数调用

dexFileParse,最低端,也就是最实质的打开函数

使用dvmDefineClass就可是直接将类从Dex加载到ClassLoader,并不需要经过Java层或Jni来进行类的加载。

在libdvm.so只有少数几个函数是用extern "C"风格的链接符号导出的,dalvik却是c++项目,也就是说其它符号都使用了c++的风格,所以你并不能直接通过直观的函数名来进行函数符号的获取,而必须使用它对应的c++风格的真实链接符号。

下面是我将python移植后使用的pyjni.py,使用ctypes获取符号将名字做映射。这些符号可以通过objdump取得。

这样我就能在程序运行的同时手动去使用libdvm.so的内部函数,像命令一样使用,而不用每次都进行ndk编译。

使用 libdvm.so 内部函数dvm* 加载 dex的更多相关文章

  1. [转载] Android动态加载Dex机制解析

    本文转载自: http://blog.csdn.net/wy353208214/article/details/50859422 1.什么是类加载器? 类加载器(class loader)是 Java ...

  2. android加固系列—6.仿爱加密等第三方加固平台之动态加载dex防止apk被反编译

    [版权所有,转载请注明出处.出处:http://www.cnblogs.com/joey-hua/p/5402599.html ] 此方案的目的是隐藏源码防止直接性的反编译查看源码,原理是加密编译好的 ...

  3. Android应用安全之外部动态加载DEX文件风险

    1. 外部动态加载DEX文件风险描述 Android 系统提供了一种类加载器DexClassLoader,其可以在运行时动态加载并解释执行包含在JAR或APK文件内的DEX文件.外部动态加载DEX文件 ...

  4. Android 插件技术:动态加载dex技术初探

    1.Android动态加载dex技术初探 http://blog.csdn.net/u013478336/article/details/50734108 Android使用Dalvik虚拟机加载可执 ...

  5. Android拆分与加载Dex的多种方案对比

    http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=207151651&idx=1&sn=9eab282711f4eb2b ...

  6. Dex动态加载

    Dex动态加载是为了解决什么问题? 在Android系统中,一个App的所有代码都在一个Dex文件里面. Dex是一个类似Jar的存储了多个Java编译字节码的归档文件. 因为Android系统使用D ...

  7. Android系统下的动态Dex加载

    1 问题在Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件.因为Android系统使用Dalvik虚拟机,所以需要把使用 ...

  8. 浅析dex文件加载机制

    我们可以利用DexClassLoader来实现动态加载dex文件,而很多资料也只是对于DexClassLoader的使用进行了介绍,没有深入讲解dex的动态加载机制,我们就借助于Android4.4的 ...

  9. Android系统下的动态Dex加载与app速度优化

    1 问题 在Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件.因为Android系统使用Dalvik虚拟机,所以需要把 ...

随机推荐

  1. spring mvc中,直接注入的HttpServletRequst是否安全呢?

    看似很简单的一个问题,借此追踪下spring的源码处理 在写springMVC的Control中有很多这种代码, 如需要获取request对象去做某些事情 如: @Controller @Reques ...

  2. Docker for Mac与IntelliJ Docker Integration插件的兼容性问题

    笔者在自己的Mac上安装的是Docker for Mac,而不是Docker Toolbox. 这两者最主要的区别在于Docker for Mac用HyperKit作为虚拟化解决方案而不是Virtua ...

  3. PHP命名空间理解

    这玩意就是路径! 这玩意就是路径! 这玩意就是路径! 这玩意就是路径! 这玩意就是路径! use 就是声明要用某个路径的文件(类) 再有namespace的情况下,就类似于已经在一个路径里了 这个时候 ...

  4. [Day02] int, str功能学习

    第二天任务: int的常用功能,参照该篇博客里面列举的常用功能 http://13683137989.blog.51cto.com/9636221/1911393 str的常用功能(重要) ,参照该篇 ...

  5. WF4.0以上使用代码完整自定义动态生成执行工作流Xaml文件

    给大家分享一下,如何完全使用代码自定义的创建生成工作流文件(用代码创建Xaml文件),并且动态加载运行所生成的工作流. 工作流生成后 在Xaml文件里的主要节点如下: 输入输出参数 <x:Mem ...

  6. NGINX中的proxy_pass和rewrite

    文章作者:luxianghao 文章来源:http://www.cnblogs.com/luxianghao/p/6807081.html 转载请注明,谢谢合作. 免责声明:文章内容仅代表个人观点,如 ...

  7. 腾讯QQAndroid API调用实例(QQ分享无需登录)

    腾讯QQAndroid API调用实例(QQ分享无需登录)   主要分为两个步骤: 配置Androidmanifest.xml 修改activity里边代码 具体修改如下:   1.Activity代 ...

  8. iOS 详解NSObject协议

      协议就是一组接口的集合,遵守一个协议之后就拥有的该协议中所有方法的声明.NSObject这个类遵守了NSObject协议,并且实现了NSObject协议里的所有方法,所以NSObject类及其子类 ...

  9. iOS 使用 UIMenuController 且不隐藏键盘的方法

    iOS 使用 UIMenuController 且不隐藏键盘的方法 在键盘显示的时候使用 UIMenuController 弹出菜单,保持键盘显示且可输入的状态. 实现方法有 修改响应链(推荐) 遵循 ...

  10. OC 动态类型和静态类型

    多态 允许不同的类定义相同的方法 动态类型 程序直到执行时才能确定所属的类 静态类型 将一个变量定义为特定类的对象时,使用的是静态形态 将一个变量定义为特定类的对象时,使用的是静态类型,在编译的时候就 ...