Понимание разборки кода Dalvik? - PullRequest
5 голосов
/ 27 января 2011

Я играю с smali и baksmali в небольшом приложении Hello World для Android, которое я написал. Мой исходный код:

package com.hello;

import android.app.Activity;
import android.os.Bundle;

public class Main extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

который затем был разобран на:

.class public Lcom/hello/Main;
.super Landroid/app/Activity;
.source "Main.java"


# direct methods
.method public constructor <init>()V
    .locals 0

    .prologue
    .line 6
    invoke-direct {p0}, Landroid/app/Activity;-><init>()V

    return-void
.end method


# virtual methods
.method public onCreate(Landroid/os/Bundle;)V
    .locals 1
    .parameter "savedInstanceState"

    .prologue
    .line 10
    invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

    .line 11
    const/high16 v0, 0x7f03

    invoke-virtual {p0, v0}, Lcom/hello/Main;->setContentView(I)V

    .line 12
    return-void
.end method

Я понимаю, что это какое-то Промежуточное Представление, но я не уверен, что это такое. Как я понимаю, должна быть некоторая спецификация о том, как понимать это представление, но я не могу понять, как его искать. Итак, учитывая файл apk, может ли кто-нибудь объяснить в терминах непрофессионала, как для получения этого представления используется спецификация кода операции Dalvik? Мое нынешнее понимание таково:

  • Учитывая APK, я мог бы извлечь AndroidManifest.xml в двоичном XML форматировать и использовать такой инструмент, как axml2xml.pl , чтобы получить «текстовый» версия манифеста, которая не полный ИЛИ я мог бы использовать apktool , чтобы получить более читабельный форма. Но я все еще не уверен, что спецификация, которую они используют для преобразовать двоичный XML в текст.
  • The дизассемблеры как-то используют спецификация кода операции Dalvil для читать файлы dex и конвертировать его в приведенное выше представление.

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

Обновление 1 (опубликовано после ответа Криса):

По сути, я бы сделал следующее, чтобы получить байт-код Dalvik:

  • Возьмите apk и извлеките его, чтобы получить файлы classes.dex.
  • Затем дизассемблер читает файл classes.dex и определяет все классы, присутствующие в apk. Можете ли вы дать мне некоторую информацию о том, как это делается? Он анализирует файл в шестнадцатеричном режиме и ищет спецификацию Dalvik, а затем разрешает соответствующим образом? Или что-то еще происходит? Например, когда я использовал hexdump на classes.dex, он дал мне что-то вроде этого:

    64 65 78 0a 30 33 ...

Используются ли они сейчас для поиска кода операции?

  • Предполагая, что инструмент смог разделить входящий байт-код на отдельные классы, он продолжает сканировать шестнадцатеричные коды из файла classes.dex и использует спецификацию Davlik для вывода соответствующего имени кода операции из таблицы?

На самом деле, короче говоря, мне интересно знать, как делается вся эта "магия". Так, например, если бы я научился писать этот инструмент, какой дорожной карте высокого уровня я должен придерживаться?

Ответы [ 2 ]

14 голосов
/ 27 января 2011

То, на что вы смотрите, это байт-код davlik.Код Java переводится в байт-код Dalvik с помощью инструмента dx.Манифест - это отдельная проблема, о которой я расскажу через минуту.Фактически, когда вы компилируете свое приложение Android, инструмент dx преобразует ваш код Java в байт-код (так же, как javac преобразует байт-код Java в Java для стандартного приложения JVM), используя 256 кодов операций dalvik.

Например, invoke-super - это код операции, который инструктирует dvm (виртуальная машина dalvik) вызывать метод в суперклассе.Точно так же invoke-interface инструктирует dvm для вызова метода интерфейса.

Итак, вы можете видеть, что

super.onCreate(savedInstanceState);

преобразуется в

invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)

В этом случае invoke-super принимает два параметра, группу {p0,p1 и параметр Landroid/app/Activity;->onCreate(Landroid/os/Bundle;), который представляет собой спецификацию метода, которую он использует для поиска и разрешения метода при необходимости.

Затем в вызове invoke-directобласть конструктора.

invoke-direct {p0}, Landroid/app/Activity;-><init>()V

У каждого класса есть метод init, который используется для инициализации членов данных класса, также известных как конструктор.Когда вы создаете класс, виртуальная машина также должна вызывать конструктор суперкласса.Это объясняет, почему конструктор для вашего класса вызывает конструктор Activity.

Что касается манифеста, что происходит (это все в спецификациях Dalvik, если вы проверяете исходный код), что компилятор (который генерирует файл apk) преобразует манифест в более сжатый формат (двоичный файл xml) для экономии места.Манифест не имеет ничего общего с кодом, который вы разместили, он больше инструктирует dvm о том, как обрабатывать приложение целиком в отношении Activities, Services и т. Д. То, что вы опубликовали, это то, что на самом делеисполняется.

Это ответ высокого уровня на ваш вопрос.Если вам нужно больше, дайте мне знать, и я сделаю все возможное.

Редактировать Вы в основном правы.Декомпилятор считывает двоичные данные как поток байтов из файла dex.Он понимает, каким должен быть формат, и способен извлекать такую ​​информацию, как константы, классы и т. Д. Что касается кодов операций, это именно то, что он делает.Он понимает, каково значение байта для каждого кода операции (или как оно представлено в файле dex), и может преобразовать его в удобочитаемую строку.Если бы вы собирались реализовать это, помимо понимания общих основ компиляторов, я бы начал с глубокого понимания структуры файла dex.Оттуда вам нужно будет создать таблицу, которая сопоставляет значения кода операции с удобочитаемой строкой.С помощью этой информации и некоторой дополнительной информации о строковых константах и ​​т. Д. Вы можете создать представление скомпилированного класса в текстовом файле.Это имеет смысл?

3 голосов
/ 27 января 2011

Спецификация кода операции описывает только инструкции. Формат dex - это нечто большее - он содержит все метаданные, необходимые для Dalvik VM (и дизассемблера) для интерпретации файла - строки, классы, типы, методы и так далее. См. Также официальную спецификацию кода операции , она более полная и подробная, чем та, которую вы связали.

<plug> Кстати, следующая версия IDA Pro будет поддерживать разборку .dex файлов </plug>

...