【问题标题】:Android smali question安卓小问题
【发布时间】:2010-12-04 12:56:36
【问题描述】:

我目前正在对 smali/"code obfuscator" 进行一些研究,目前正在尝试熟悉反编译的源代码。为此,我创建了一个简单的应用程序并通过 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;
    }

小源:

.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

【问题讨论】:

  • 我应该使用反编译的源代码在android开发中再次运行吗?
  • 回滚 3rd 方编辑,这与提出的实际问题大体上不一致 - 这实际上不是一个混淆问题(还),它确实涉及 smali 中的浮点表示。

标签: android floating-point decompiling opcodes


【解决方案1】:

不幸的是,dalvik 字节码在整数类型(short/integer/long/etc.)和浮点类型(float/double)之间没有区别。所以 baksmali 不知道是将这样的常量显示为浮点数还是整数,所以它只是默认为整数。

由于存在您提到的那种指令,这使情况变得更加复杂。来自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 似乎是更好的之一。

【讨论】:

  • 其实我现在还有一个问题。您怎么知道使用了 v0 和 v1(参见 const-wide/high16 v0, 0x4014)?该命令中没有 v0,不是吗?
  • 呃..再看一遍?我肯定在那里看到一个“v0”:)
  • 嗯,抱歉打错了。当然,我的意思是 v1。 const-wide/high16 v0, 0x4014 .... 没有 v1 ... 我怎么知道?从某种意义上的价值?
  • double 和 long 总是存储在连续的寄存器中。然后你通过较低的寄存器引用它们。
【解决方案2】:

我是凭记忆做的,但据我记忆,浮点数通常是这样存储的:

100000000010100
smmmmmmmmmmmmee

s = 符号,m = 尾数,e = 指数。因此,在您的情况下,符号必须为 1 或正数,尾数为 5,指数为零:

+5 x 2^0 = 5

有关更多信息,请参阅floating point 上的维基百科文章。显然,您的编码使用 15 位,这对于浮点数来说并不多,尤其是指数只有 2 位,所以它可能完全是另一回事。这只是我有根据的猜测。您可以尝试输入其他数字并检查反编译的代码以了解更多信息。

【讨论】:

    【解决方案3】:

    这显然是“5”作为双精度的适当二进制编码,用于与该浮点类型的第二个参数进行比较。

    【讨论】:

    • 你知道怎么计算吗?我不确定如何将 0x4014 转换为 5 的值。在某处可能有关于此主题的任何文档吗?
    猜你喜欢
    • 2012-05-07
    • 2018-07-03
    • 2014-02-19
    • 2011-06-12
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多