为了工作而工作是悲哀的!工作是实现自我价值的地方!

学习dalvik,首先得从了解dex文件的格式开始,这可以参考相关的一下资料:

其实也就是一些告诉你dex文件是由那些头组成,头里面的信息又是指向文件中的哪些块,各个块又是什么意思。说白了设计这个格式的人是介于牛A和牛C之间的人,而我们只需要读懂该格式的人,只要肯下功夫,肯定都是能读懂的。当然,都有一些工具帮您解析这个格式。这里我就不多说了。大家可以去google, dexdump, dedexer, smali都是神马,来了解这些神马和制作这些神马的都是些什么人:)同时,我也会陆续的记录关于smali解析的相关文章,希望和大家一起学习探讨。

好了废话不说,来看我学习dex format遇到的第一个问题, LEB128是神马玩意?

看了mydroid/dalvik/docs/dex-format.html中的描述,,直接无语,不知所云:(然后又Link到Dwarf3的标准,这才了解一二,最终还是在wikipedia上找到了最让我理解的解释:))

其实,LEB128就是利用了一种压缩算法(variable-length code),来一个表示整型数值。当然,可以是表示有符号的,也可表示无符号的。

LEB128的wiki上比较清楚的表示了一个如何把一个无符号的整型数压缩位3个bytes的LEB128格式。

10011000011101100101 624485的2进制表示010011000011101100101 把2进制的表示的bit扩展为能被7整除(不足的加0) 0100110 0001110 1100101 再以7-bit为一组进行分组00100110 10001110 11100101 把第一组+0扩展为8bit,而其余的都+1扩展为8bit0xE50x8E0x26 结果表示位16进制0x26 0x8E 0xE5最终在内存中的表示

而对于有符号的转换只有文字描述,下面我套用无符号的格式,描述一下有符号的压缩

01100111100010011011 -624485的2进制表示(呵呵,负数在计算机中是如何表示的,大家没有忘吧:)补码啊补码) 001100111100010011011 把2进制的表示扩展为能被7整除 0011001 1110001 0011011 再以7-bit为一组进行分组01011001 11110001 10011011 把第一组+0扩展为8bit,而其余的都根据原整形数的符号位来扩展为8bit(所以这里最后两个7bit组都是+1来扩展的)0x590xf10x9b 结果表示位16进制0x9b 0xf1 0x59最终在内存中的表示

具体的C语言算法,伪代码在wiki上就有。而相关的android dalvik的代码目前只找到在dalvik/vm/reflect/Annotation.c中的readUleb128。

这里还留有两个跟dalvik相关的问题,需要以后逐步求证(关于这两个疑问希望知道的朋友不吝赐教!!!)

1. 这里很奇怪的,在dalvik的dex-format的文档中描述有2个地方会用到有符号的leb128,却没有发现类似的readUleb128的读取有符号的leb128的函数,

2.在分析smali源码的时候,在libdex/DexFile.java中关于preserveSignedRegisters中有关于dalvik对于leb128的一个bug的描述。但是,现阶段我还么有找到相关的证据。希望随着后面对smali和dex的了解,能够找到这个bug的例子。(??待求证??)

参考资料:

,Appendix C — Variable Length Data: Encoding/Decoding (informative)

与其用泪水悔恨今天,不如用汗水拼搏今天。

为了工作而工作是悲哀的!工作是实现自我价值的地方!

相关文章:

你感兴趣的文章:

标签云: