Smali - デコンパイル/[変更]/コンパイル
Reading time: 12 minutes
tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:
HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
アプリケーションのコードを変更して隠された情報にアクセスすること(難読化されたパスワードやフラグなど)が有用な場合があります。その際、apk をデコンパイルしてコードを変更し、再コンパイルすることが有用です。
オペコード参照: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html
手早い方法
Using Visual Studio Code and the APKLab extension, you can automatically decompile, modify, recompile, sign & install the application without executing any command.
この作業を大幅に簡単にする別のスクリプトは https://github.com/ax/apk.sh です。
APK をデコンパイルする
APKTool を使用すると、smali コードとリソースにアクセスできます:
apktool d APP.apk
もし apktool がエラーを返す場合は、 installing the latest version をインストールしてみてください。
調べるべき興味深いファイル:
- res/values/strings.xml (および res/values/* 内のすべての xml)
- AndroidManifest.xml
- 拡張子が .sqlite または .db のファイル
apktool がアプリケーションのデコードに問題がある場合は、https://ibotpeaches.github.io/Apktool/documentation/#framework-files を参照するか、引数 -r(リソースをデコードしない)を試してください。問題がソースコードではなくリソース側にある場合、これで問題は発生しなくなります(リソースはデコンパイルされません)。
smali コードの変更
命令を変更したり、いくつかの変数の値を変更したり、新しい命令を追加したりできます。私は Smali コードを VS Code で編集します。smalise extension をインストールすると、エディタが不正な命令を教えてくれます。
いくつかの例は以下にあります:
または check below some Smali changes explained を参照してください。
APK を再コンパイルする
コードを変更した後、次のようにしてコードを再コンパイルできます:
apktool b . #In the folder generated when you decompiled the application
これにより、新しい APK が dist フォルダの内部でコンパイルされます。
もし apktool がエラーを出す場合は、最新バージョンをインストールしてみてください。
新しい APK に署名する
次に、キーを生成する必要があります(パスワードやランダムに入力して構わないいくつかの情報を尋ねられます):
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>
最後に、署名して新しいAPKを作成します:
jarsigner -keystore key.jks path/to/dist/* <your-alias>
新しいアプリケーションの最適化
zipalign は、Android application (APK) files に対して重要な最適化を提供するアーカイブ整列ツールです。 More information here.
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
zipalign -v 4 infile.apk
新しい APK に署名(また?)
もし jarsigner の代わりに apksigner を使うことを好むなら、zipaling による最適化を適用した後にAPK に署名するべきです。ただし、アプリケーションは jarsigner(zipalign の前)で、または aspsigner(zipaling の後)で一度だけ署名すればよいという点に注意してください。
apksigner sign --ks key.jks ./dist/mycompiled.apk
Smaliの変更
次の Hello World Java コードの場合:
public static void printHelloWorld() {
System.out.println("Hello World")
}
Smali のコードは次のようになります:
.method public static printHelloWorld()V
.registers 2
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v1, "Hello World"
invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
return-void
.end method
Smali の命令セットは here で確認できます。
軽微な変更
関数内の変数の初期値を変更する
一部の変数は関数の先頭で opcode const を使って定義されています。値を変更したり、新しいものを定義したりできます:
#Number
const v9, 0xf4240
const/4 v8, 0x1
#Strings
const-string v5, "wins"
基本操作
#Math
add-int/lit8 v0, v2, 0x1 #v2 + 0x1 and save it in v0
mul-int v0,v2,0x2 #v2*0x2 and save in v0
#Move the value of one object into another
move v1,v2
#Condtions
if-ge #Greater or equals
if-le #Less or equals
if-eq #Equals
#Get/Save attributes of an object
iget v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save this.o inside v0
iput v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save v0 inside this.o
#goto
:goto_6 #Declare this where you want to start a loop
if-ne v0, v9, :goto_6 #If not equals, go to: :goto_6
goto :goto_6 #Always go to: :goto_6
大きな変更
ロギング
#Log win: <number>
iget v5, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Get this.o inside v5
invoke-static {v5}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; #Transform number to String
move-result-object v1 #Move to v1
const-string v5, "wins" #Save "win" inside v5
invoke-static {v5, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I #Logging "Wins: <num>"
推奨事項:
- 関数内で宣言済みの変数を使用する場合(宣言は v0,v1,v2...)、これらの行を .local
と変数の宣言(const v0, 0x1)の間に入れてください。 - 関数のコードの途中にロギングコードを置きたい場合:
- 宣言済み変数の数に2を追加してください。例: .locals 10 から .locals 12 へ
- 新しい変数は既に宣言されている変数の次の番号にしてください(この例では v10 と v11 になります。v0 から始まることを忘れないでください)。
- ロギング関数のコードを変更し、v10 と v11 を v5 と v1 の代わりに使用してください。
トースト表示
関数の先頭で .locals の数に3を追加することを忘れないでください。
このコードは 関数の途中 に挿入するために用意されています(必要に応じて 変数 の数を変更してください)。this.o の値を取得し、String に変換して、その値で toast を表示します。
const/4 v10, 0x1
const/4 v11, 0x1
const/4 v12, 0x1
iget v10, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I
invoke-static {v10}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
move-result-object v11
invoke-static {p0, v11, v12}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v12
invoke-virtual {v12}, Landroid/widget/Toast;->show()V
スタートアップでネイティブライブラリをロードする (System.loadLibrary)
他の JNI ライブラリより先に初期化されるように、ネイティブライブラリを事前にロードする必要があることがあります(例: プロセスローカルの telemetry/logging を有効にするため)。System.loadLibrary() の呼び出しを static 初期化子または Application.onCreate() の早い段階に注入できます。static クラスイニシャライザ (
.class public Lcom/example/App;
.super Landroid/app/Application;
.method static constructor <clinit>()V
.registers 1
const-string v0, "sotap" # library name without lib...so prefix
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
return-void
.end method
あるいは、同じ2つの命令を Application.onCreate() の先頭に置いて、ライブラリが可能な限り早くロードされるようにします:
.method public onCreate()V
.locals 1
const-string v0, "sotap"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
invoke-super {p0}, Landroid/app/Application;->onCreate()V
return-void
.end method
注意事項:
- ライブラリの正しい ABI バリアントが lib/
/(例: arm64-v8a/armeabi-v7a)の下に存在することを確認し、UnsatisfiedLinkError を回避してください。 - 非常に早い段階で読み込む(class static initializer)ことで、native logger が以後の JNI activity を観測できることが保証されます。
参考
- SoTap: 軽量なアプリ内 JNI (.so) 挙動ロガー – github.com/RezaArbabBot/SoTap
tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:
HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HackTricks