Androidのリバースエンジニアリング方法

### 使うソフトウェア
[apktool](http://code.google.com/p/android-apktool/)
[dex2jar](http://code.google.com/p/dex2jar/downloads/list)
[jad](http://www.varaneckas.com/jad)

### 基本コマンド
[apk→smali]
`apktool d LogTest.apk Smali`

[apk→classes.dex]
`unzip LogTest.apk -d Unzip`

[classes.dex→classes_dex2jar.jar]
`./dex2jar.sh ./Unzip/classes.dex`

[classes_dex2jar.jar→class]
`unzip ./Unzip/classes_dex2jar.jar -d ./Classes`

[class→java]
` ./jad -8 -d Src -s .java -r ~ **/*.class`

### 元ファイル
```java:LogTestActivity.java
package com.ayaki.log;

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

public class LogTestActivity extends Activity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		String str = "ABC";
	}
}
```

### 取得したSmaliファイル

```java:LogTestActivity.smali
.class public Lcom/ayaki/log/LogTestActivity;
.super Landroid/app/Activity;
.source "LogTestActivity.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 2
    .parameter "savedInstanceState"

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

    .line 11
    const/high16 v1, 0x7f03

    invoke-virtual {p0, v1}, Lcom/ayaki/log/LogTestActivity;->setContentView(I)V

    .line 13
    const-string v0, "ABC"

    .line 16
    .local v0, str:Ljava/lang/String;
    return-void
.end method
```

### 逆コンパイルJavaファイル

```java:LogTestActivity.java
package com.ayaki.log;

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

public class LogTestActivity extends Activity
{

    public LogTestActivity()
    {
    }

    public void onCreate(Bundle bundle)
    {
        super.onCreate(bundle);
        setContentView(0x7f030000);
    }
}
```

### 動的な動作の変更
Smaliは可逆性があるので、.apk→.smali→編集→.apkが可能。
例えば、Log.d("MYLOG", str);に相当するものを書いてみる。
[修正後Smali]

```java:LogTestActivity.smali
.class public Lcom/ayaki/log/LogTestActivity;
.super Landroid/app/Activity;
.source "LogTestActivity.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 2
    .parameter "savedInstanceState"

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

    .line 11
    const/high16 v1, 0x7f03

    invoke-virtual {p0, v1}, Lcom/ayaki/log/LogTestActivity;->setContentView(I)V

    .line 13
    const-string v0, "ABC"

    const-string v2, "MYLOG"

    invoke-static {v2, v0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    .line 16
    .local v0, str:Ljava/lang/String;
    return-void
.end method
```

### 実行
[smali→apk]
`apktool b Smali LogTestNew.apk`

[keystoreの作成]
`keytool -genkey -keystore test.keystore -validity 10000 -alias test`

[認証]
`jarsigner -keystore test.keystore -verbose LogTestNew.apk test`

[デバイスへのインストール]
`adb install -r LogTestNew.apk`

[Log]
`adb logcat -s MYLOG`

これで、ABCと表示されれば、改変成功！