2012年4月21日土曜日

AndroidでWebViewを使用する際の注意点

このエントリーをはてなブックマークに追加
Androidのアプリ内でWebViewを使用する際に、サイトページ内に、window.open(url)やwindow.location.href=urlを使用したが画面遷移があると、うまく画面遷移ができない。

解決策は、shouldOverrideUrlLoadingをオーバーライドして、各種サービスの起動を明記する。

下記例では、urlが、「mailto:」で始まった時はメールアプリを起動する暗黙的インテントを発行し、TwitterやFacebookのシェアボタンをタップした時には、画面遷移先を読み込むようにしている。

        wb = (WebView) findViewById(R.id.event_wb);
        wb.setWebChromeClient(new WebChromeClient());
        wb.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView webView, String url) {
                Intent intent = null;
                if(url.substring(0, 7).equals("mailto:"))
                intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(url));
                else if(url.contains("twitter") || url.contains("facebook"))
                    intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                if(intent != null) {
                    startActivity(intent);
                    webView.reload();   
                }
                return true;
            }
        });
        WebSettings settings = wb.getSettings();
        settings.setJavaScriptEnabled(true);

2012年4月12日木曜日

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

このエントリーをはてなブックマークに追加

apktool
dex2jar
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


【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";
}
}


【LogTestActivity.smali - 取得したSmaliファイル】
.class public Lcom/ayaki/log/LogTestActivity;
.super Landroid/app/Activity;
.source "LogTestActivity.java"


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

.prologue
.line 6
invoke-direct {p0}, Landroid/app/Activity;->()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


【LogTestActivity.java - 逆コンパイル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);に相当するものを書いてみる。



【LogTestActivity.smali - 修正後】
.class public Lcom/ayaki/log/LogTestActivity;
.super Landroid/app/Activity;
.source "LogTestActivity.java"


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

.prologue
.line 6
invoke-direct {p0}, Landroid/app/Activity;->()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と表示されれば、改変成功!