使用 libdvm.so 内部函数dvm* 加载 dex
2017-06-05 19:22
162 查看
首先要清楚,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
- PHP中内部函数使用方法
- 约瑟夫环问题的 PHP 实现--使用 PHP 数组内部指针操作函数
- js使用闭包时,内部函数是直接访问外部函数的实际变量而非复制一份新变量
- 使用dlsym动态取用so中函数
- 使用ptrace向已运行进程中注入.so并执行相关函数
- Mysql 内部函数的使用
- PHP在函数中使用static变量来加载和设置配置文件
- PHP使用__autoload()函数自动加载未定义的类
- ctypes 加载的so库中函数参数的字符串传递问题(str与bytes转换)
- 在一个程序中加载另一程序使用GlobalFree()函数出错的原因
- 约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
- 使用指针类型参数和使用指针引用类型参数在函数内部用new给参数分配空间的不同结果
- 【Php】在函数内部使用unset的一些注意点
- Android下使用dlopen函数动态调用.so链接库 [转]
- 使用SQL SERVER 内部函数进行密码加密和校验小问题
- ERROR: Removing 'hello': Device or resource busy //关于使用系统定义的模块加载和卸载函数
- 在ajax循环加载多条数据,并在内部定义一个函数
- A3、限制函数内部循环使用局部变量的数目,最多不超过12个
- jquery等待图片加载完成,再使用函数,使用$(window).load(fn)