Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
simplify — Android仮想マシンおよび難読化解除ツール | Kitploit
ツール/GitHubGitHub/calebfenton/simplify
Androidセキュリティ動的分析 (サンドボックス)リバースエンジニアリングマルウェア分析バイナリ解析
GitHubcalebfenton/simplify

simplify

Android仮想マシンおよび難読化解除ツール

リポジトリを見る
4.7k45515年前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

Simplify

Build Status Coverage Status Coverity Scan Build Status

汎用 Android 難読化解除ツール

Simplify はアプリを仮想的に実行してその動作を理解し、その後コードを最適化して、同じように動作しながらも人間にとって理解しやすくなるようにします。各最適化タイプはシンプルで汎用的なので、使用されている難読化の具体的な種類は問いません。

前と後

左側のコードは難読化されたアプリの逆コンパイル結果で、右側のコードは難読化が解除されています。

多くのメソッド呼び出し、明確な意味なし わあ、とてもリテラルで、意味が豊富

概要

このプロジェクトには3つの部分があります:smalivm、simplify、およびデモアプリです。

  1. smalivm: Dalvikメソッドを実行するための仮想マシンサンドボックスを提供します。メソッドを実行した後、すべての実行パスにおける可能なレジスタ値とクラス値のグラフを返します。ファイルやネットワークI/Oなど一部の値が不明な場合でも機能します。例えば、不明な値を持つifまたはswitch条件は、両方のブランチが実行されることになります。
  2. simplify: smalivmからの実行グラフを分析し、定数伝播、デッドコード除去、リフレクション解除、およびいくつかのピープホール最適化を適用します。これらはかなりシンプルですが、繰り返し組み合わせて適用すると、文字列の復号、リフレクションの除去、コードの大幅な簡略化が行われます。メソッドやクラスの名前は変更しません。
  3. demoapp: 独自のプロジェクトでsmalivmを使用するための、シンプルでコメントが豊富な例が含まれています。Dalvikコードを実行する必要があるものを作成している場合は、ぜひご覧ください。

Usage

root@kitploit:~
usage: java -jar simplify.jar <input> [options]
deobfuscates a dalvik executable
 -et,--exclude-types <pattern>   Exclude classes and methods which include REGEX, eg: "com/android", applied after include-types
 -h,--help                       Display this message
 -ie,--ignore-errors             Ignore errors while executing and optimizing methods. This may lead to unexpected behavior.
    --include-support            Attempt to execute and optimize classes in Android support library packages, default: false
 -it,--include-types <pattern>   Limit execution to classes and methods which include REGEX, eg: ";->targetMethod\("
    --max-address-visits <N>     Give up executing a method after visiting the same address N times, limits loops, default: 10000
    --max-call-depth <N>         Do not call methods after reaching a call depth of N, limits recursion and long method chains, default: 50
    --max-execution-time <N>     Give up executing a method after N seconds, default: 300
    --max-method-visits <N>      Give up executing a method after executing N instructions in that method, default: 1000000
    --max-passes <N>             Do not run optimizers on a method more than N times, default: 100
 -o,--output <file>              Output simplified input to FILE
    --output-api-level <LEVEL>   Set output DEX API compatibility to LEVEL, default: 15
 -q,--quiet                      Be quiet
    --remove-weak                Remove code even if there are weak side effects, default: true
 -v,--verbose <LEVEL>            Set verbosity to LEVEL, default: 0

Building

ビルドにはJava Development Kit 8 (JDK)のインストールが必要です。

このプロジェクトにはAndroidフレームワークのサブモジュールが含まれているため、--recursive 付きでクローンするか:

root@kitploit:~
git clone --recursive https://github.com/CalebFenton/simplify.git

または、いつでも次のようにサブモジュールを更新します:

root@kitploit:~
git submodule update --init --recursive

次に、すべての依存関係を含む単一のjarをビルドするには:

root@kitploit:~
./gradlew fatjar

Simplify jarは simplify/build/libs/ に配置されます。提供されている難読化されたサンプルアプリ を簡略化して動作をテストできます。実行方法は次のとおりです( simplify.jar を変更する必要があるかもしれません):

root@kitploit:~
java -jar simplify/build/libs/simplify.jar -it "org/cf/obfuscated" -et "MainActivity" simplify/obfuscated-app.apk

何が難読化解除されているかを理解するには、難読化アプリのREADME を参照してください。

Troubleshooting

Simplifyが失敗した場合は、以下の推奨事項を順に試してください。

  1. -it オプションを使用して、少数のメソッドまたはクラスのみを対象にします。
  2. 失敗の原因が最大訪問回数の超過である場合は、より高い --max-address-visits、--max-call-depth、--max-method-visits を試してください。
  3. -v または -v 2 を試し、ログとDEXまたはAPKのハッシュを添えて問題を報告してください。
  4. もう一度試してください。ただし、アイコンタクトを切らないでください。Simplifyは恐怖を感知できます。

Windowsでビルドしていて、次のようなエラーでビルドが失敗する場合:

Could not find tools.jar. Please check that C:\Program Files\Java\jre1.8.0_151 contains a valid JDK installation.

これはGradleが適切なJDKパスを見つけられないことを意味します。JDKがインストールされていることを確認し、JAVA_HOME 環境変数をJDKパスに設定し、ビルドに使用するコマンドプロンプトを閉じて再度開いてください。

Contributing

遠慮しないでください。仮想実行と難読化解除は魅力的な問題だと思います。興味がある人は自動的にクールで、タイポ修正のような小さなものでも貢献を歓迎します。Issueで質問したり、プルリクエストを送信したりしてください。

Reporting Issues

APKまたはDEXへのリンクと、使用している完全なコマンドを含めてください。これにより、問題の再現(したがって修正)がはるかに容易になります。

サンプルを共有できない場合は、ファイルハッシュ(SHA1、SHA256など)を必ず含めてください。

Optimization Strategies

Constant Propagation

オペコードが文字列、数値、ブール値などの定数に変換できるタイプの値を配置する場合、この最適化はそのオペコードを定数で置き換えます。例:

root@kitploit:~
const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
invoke-static {v0}, Lmy/string/Decryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
# Decrypts to: "Tell me of your homeworld, Usul."
move-result v0

この例では、暗号化された文字列が復号され、v0 に配置されます。文字列は「定数化可能」であるため、move-result v0 は const-string に置き換えることができます:

root@kitploit:~
const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
invoke-static {v0}, Lmy/string/Decryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
const-string v0, "Tell me of your homeworld, Usul."

Dead Code Removal

コードが削除されてもアプリの動作が変わらない場合、そのコードはデッドコードです。最も明白なケースは、コードに到達できない場合です(例:if (false) { // dead })。到達可能なコードであっても、メソッド外部の状態に影響を与えない場合(つまり、副作用がない場合)、デッドコードと見なされる可能性があります。例えば、コードがメソッドの戻り値に影響を与えず、クラス変数を変更せず、I/Oも行わない場合などです。これは静的解析では判断が難しいです。幸い、smalivmは賢くなろうとする必要はありません。可能なものはすべて愚直に実行し、確信が持てない場合は副作用があると仮定します。Constant Propagationの例を考えてみましょう:

root@kitploit:~
const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
invoke-static {v0}, Lmy/string/Decryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
const-string v0, "Tell me of your homeworld, Usul."

このコードでは、invoke-static はメソッドの戻り値に影響を与えなくなり、ファイルシステムやネットワークソケットにバイトを書き込むなどの異常なことをしないと仮定すると、副作用はありません。単純に削除できます。

root@kitploit:~
const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
const-string v0, "Tell me of your homeworld, Usul."

最後に、最初の const-string はレジスタに値を代入していますが、その値は決して使用されないため、代入はデッドです。これも削除できます。

root@kitploit:~
const-string v0, "Tell me of your homeworld, Usul."

万歳!

Unreflection

Javaの静的解析における大きな課題の一つはリフレクションです。注意深いデータフロー解析を行わなければ、リフレクションメソッドの引数を知ることは不可能です。これを行うスマートで巧妙な方法もありますが、smalivmはコードを実行するだけで対処します。次のようなリフレクションされたメソッド呼び出しを見つけると:

root@kitploit:~
invoke-virtual {v0, v1, v2}, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;

v0、v1、v2 の値を知ることができます。値が確実にわかっている場合、Method.invoke() の呼び出しを実際の非リフレクションメソッド呼び出しに置き換えることができます。これはリフレクションされたフィールドやクラスの検索にも同様に適用されます。

Peephole

特定のカテゴリにきれいに分類できないものについては、ピープホール最適化があります。これには、不要な check-cast オペコードの削除、Ljava/lang/String;-><init> 呼び出しの const-string への置き換えなどが含まれます。

Deobfuscation Example

Before Optimization

root@kitploit:~
.method public static test1()I
    .locals 2

    new-instance v0, Ljava/lang/Integer;
    const/4 v1, 0x1
    invoke-direct {v0, v1}, Ljava/lang/Integer;-><init>(I)V

    invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I
    move-result v0

    return v0
.end method

これが行っているのは v0 = 1 だけです。

After Constant Propagation

root@kitploit:~
.method public static test1()I
    .locals 2

    new-instance v0, Ljava/lang/Integer;
    const/4 v1, 0x1
    invoke-direct {v0, v1}, Ljava/lang/Integer;-><init>(I)V

    invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I
    const/4 v0, 0x1

    return v0
.end method

move-result v0 は const/4 v0, 0x1 に置き換えられます。これは、intValue()I の可能な戻り値が1つしかなく、戻り値の型を定数にできるためです。引数 v0 と v1 は曖昧でなく、変更されません。つまり、intValue()I におけるすべての可能な実行パスについて値の一致があります。定数に変換できる他のタイプの値:

  • 数値 - const/4、const/16 など
  • 文字列 - const-string
  • クラス - const-class

After Dead Code Removal

root@kitploit:~
.method public static test1()I
    .locals 2

    const/4 v0, 0x1

    return v0
.end method

const/4 v0, 0x1 より上のコードはメソッド外部の状態に影響を与えない(副作用がない)ため、動作を変えずに削除できます。ファイルシステムやネットワークに何かを書き込むメソッド呼び出しがあった場合、メソッド外部の状態に影響を与えるため削除できません。または、test()I が LinkedList のような可変の引数を取る場合、それにアクセスする命令はデッドと見なせません。

その他のデッドコードの例:

  • 参照されていない代入 - レジスタに代入して使用しない
  • 到達不能 / 到達不可能な命令 - if (false) { dead_code(); }

License

このツールはデュアルライセンスで提供されています:クローズドソースプロジェクトに適した商用ライセンスと、オープンソースソフトウェアで使用可能なGPLライセンスです。

ニーズに応じて、いずれかを選択し、そのポリシーに従う必要があります。各ライセンスタイプのポリシーと契約の詳細は、LICENSE.COMMERCIAL および LICENSE.GPL ファイルにあります。

Further Reading

  • SmaliVMによるDalvik仮想実行
  • Guillot, Yoann, and Alexandre Gazet. "自動バイナリ難読化解除." Journal in Computer Virology 6.3 (2010): 261-76
  • Unicorn - 究極のCPUエミュレータ
  • Babak Yadegari, Saumya Debray. 「難読化されたコードのシンボリック実行」
  • 成功事例:
    • 「AES/CFB/NoPadding」暗号化を使用したAndroidの動的クラスローディング。前後の様子をチラ見。使用ツール: #simplify。 #Android #obfuscation #classencryption #dex
    • マルウェアの文字列暗号化を復号
ツールをダウンロード