我目前正在对 smali/“代码混淆器”进行一些研究,目前正在尝试熟悉反编译的源代码。为此,我创建了一个简单的应用程序,并通过 smali 对其进行了反编译。
我现在正在尝试了解反编译后的源代码,以提高和比较以后使用代码混淆器后的安全性(针对反编译)。虽然大多数 smali 源代码并不难,但我有时仍然会遇到图形格式转换的问题。
你能给我解释一下吗以下行。我猜它的值应该是 5,但我不确定这是哪种二进制格式。如何计算它 0x4014 = 5 ???
const-wide/high16 v0, 0x4014 // 100000000010100 (5 = 101)
附上本次测试功能的完整java和smali代码源:
Java 源代码:
boolean test(int a, double d) {
if (a < 5 && d < 5)
return true;
else
return false;
}
Smali 源码:
.method test(ID)Z
.locals 2
.parameter "a"
.parameter "d"
.prologue
.line 28
const/4 v0, 0x5
if-ge p1, v0, :cond_0
const-wide/high16 v0, 0x4014
cmpg-double v0, p2, v0
if-gez v0, :cond_0
.line 29
const/4 v0, 0x1
.line 31
:goto_0
return v0
:cond_0
const/4 v0, 0x0
goto :goto_0
.end method
最佳答案
不幸的是,dalvik 字节码不区分整数类型(short/integer/long/等)和浮点类型(float/double)。所以 baksmali 不知道是将这样的常量显示为 float 还是整数,所以它只是默认为整数。
由于您提到的指令的存在,这变得更加复杂。来自dalvik-bytecode page from the dalvik documentation :
“将给定的文字值(右零扩展为 64 位)移动到指定的寄存器对中。”。
因此该指令实际上会将值 0x4014000000000000 加载到 v0 和 v1 寄存器中。这是标准的 64 位 IEEE-754 浮点表示法。第一个(最重要的)位是符号位,接下来的 11 位是指数(以 2 为底),最后 52 位是尾数。在这种情况下,我们有一个二进制表示
0100000000010100000000000000000000000000000000000000000000000000
SEEEEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
对于符号位,0为正,1为负。
对于指数,您取 11 位的整数值(在本例中为 1025),然后减去 1023,指数为 2。
对于尾数,前面有一个隐含的“1”,在 2^0 的位置,后面的数字是通常的 2^-1、2^-2 等。所以在这种情况下,我们有二进制数 1.01,或 1*2^0 + 1*2^-2,或 1.25。
用于值计算的一般形式是
-1^(2+S) * M * 2^E
其中 S、M 和 E 是符号、尾数和指数。
在这种情况下,我们有 -1^(2+0) * 1.25 * 2^2 = 1 * 1.25 * 4 = 5
如果您不想每次都手动进行此计算,可以使用各种在线计算器为您完成。 http://babbage.cs.qc.edu/IEEE-754/64bit.html似乎是更好的之一。
关于Android小问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4353580/