Android смали вопрос - PullRequest
       15

Android смали вопрос

5 голосов
/ 04 декабря 2010

В настоящее время я занимаюсь исследованием smali / "code obfuscator" и сейчас пытаюсь ознакомиться с декомпилированными исходными кодами. Для этого я создал простое приложение и распаковал его с помощью smali.

Сейчас я пытаюсь понять декомпилированный исходный код, чтобы улучшить и сравнить безопасность (против декомпиляции) после использования обфускатора кода позже. Хотя большая часть исходного кода smali не так сложна, у меня все еще иногда возникают проблемы с преобразованием формата рисунков.

Можете ли вы объяснить мне, например, следующая строка. Я предполагаю, что оно должно иметь значение пять, но я не уверен, какой это двоичный формат. Как рассчитать это 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

Ответы [ 3 ]

12 голосов
/ 05 декабря 2010

К сожалению, байт-код dalvik не делает различий между целочисленными типами (short / integer / long / etc.) И типами с плавающей запятой (float / double). Таким образом, baksmali не может знать, показывать ли такую ​​константу в виде числа с плавающей запятой или целого числа, поэтому по умолчанию это просто целое число.

Это еще более осложняется существованием инструкций, подобных той, которую вы упомянули. Со страницы dalvik-bytecode из документации dalvik :

"Переместить заданное литеральное значение (с расширением вправо от нуля до 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 кажется одним из лучших.

1 голос
/ 04 декабря 2010

Я делаю это из памяти, но, насколько я помню, числа с плавающей запятой обычно хранятся так:

100000000010100
smmmmmmmmmmmmee

s = знак, m = мантисса, e = экспонентаТак что в вашем случае знак должен быть 1 или положительным, мантисса равна 5, а показатель степени равен нулю:

+ 5 x 2 ^ 0 = 5

См. Статью в Википедии на с плавающей точкой для получения дополнительной информации.Очевидно, что ваша кодировка использует 15 битов, что не много для числа с плавающей запятой, особенно только с 2 битами для показателя степени, так что это может быть что-то совсем другое.Это всего лишь мое обоснованное предположение.Вы можете попробовать ввести другие числа и проверить декомпилированный код, чтобы узнать больше.

0 голосов
/ 04 декабря 2010

Это, по-видимому, подходящее двоичное кодирование "5" в виде двойного числа для сравнения со вторым параметром этого типа с плавающей запятой.

...