私が書いた小さな Hello World Android アプリケーションで、smali と baksmali をいじっています。私のソースコードは次のとおりです。
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 を指定すると、バイナリ XML 形式で AndroidManifest.xml を抽出し、 axml2xml.plなどのツールを使用して、完全ではない「テキスト」バージョンのマニフェストを取得するか、 apktoolを使用してより読みやすいものを取得できます。形。しかし、バイナリー XML をテキストに変換するために彼らがどのような仕様を使用しているのかはまだわかりません。
- 逆アセンブラーは、何らかの形で Dalvil オペコード仕様を利用して、dex ファイルを読み取り、それを上記の表現に変換しています。
上記の 2 つの手順に関する情報 (おそらくいくつかの簡単な例を含む) は、概念を正しく理解するのに大いに役立ちます。
更新 1 (Chris からの返信後に投稿):
基本的に、Dalvik バイトコードにたどり着くには次のようにします。
- apk を取得して展開し、classes.dex ファイルを取得します。
次に、逆アセンブラーは classes.dex ファイルを読み取り、apk に存在するすべてのクラスを判別します。これがどのように行われるかについての情報を教えてもらえますか? ファイルを 16 進モードで解析し、Dalvik 仕様を検索して、適切に解決しますか? それとも何か他のことが起こっていますか?たとえば、classes.dex で hexdump を使用すると、次のような結果が得られました。
64 65 78 0a 30 33 ...
これらは現在 Opcode ルックアップに使用されていますか?
- ツールが着信バイトコードを個別のクラスに分離できたと仮定すると、classes.dex ファイルから 16 進コードをスキャンし続け、Davlik 仕様を使用してテーブルから適切な Opcode 名を出力しますか?
実際、要するに、この「魔法」がどのように行われるかを知りたいのです。たとえば、このツールの作成方法を学ぶ場合、従うべき高レベルのロードマップは何ですか?