アニメーションアプリの署名検証学習

最近ollvmを投げていますが、数日投げてもコンパイルが完了せず、ピットを踏んでいるので、一時的に脇に置いてアプリ全体を分析する必要があります。

このアプリはアニメーションアプリです。誰かがKanxueでこのアプリを分析しているのを見ました:https://bbs.pediy.com/thread-258593.htm。
分析はあまり詳細ではない感じたので、自分で分析して作成しました。分析プロセス

目的:永続的なメンバーとしてアプリを変更します

最初にapkを開いて、見てみましょう。
ここに写真の説明を挿入

もちろん、メンバーシップの日付を変更する場合は、インターフェイスに対応するアクティビティを見つける必要があります。メンバーシップ文字列を直接検索するなど、変更する方法はたくさんあります。その後、関連する場所を見つけることができますUserInfoActivity
ここに写真の説明を挿入
。getExpireを表示:

ここに写真の説明を挿入
setExpireを表示:

ここに写真の説明を挿入
dateFormatオブジェクトが数回文字列に変換され、「2100-01-01」文字列と比較されていることがわかります。この値以上である限り、永続的なメンバーです。

longは非常に単純なので、androidKillerを使用してgetExpireの戻り値を変更するだけです。

その後、コンパイル解除後に実行を開始したところ、機能しないことがわかりました。

ここに写真の説明を挿入

最初に考えたのは検索文字列でしたが、確かにソフトウェアはそれほど単純ではなく検索できないので、サーバー側で検証が行われていると推定されます

フィドラーを使用してパケットを取得します。

ここに写真の説明を挿入

imeiは私の目を迎えました、ただそれを探してください:

ここに写真の説明を挿入

案の定、私はそれを見つけました、getV()をチェックしてください:

ここに写真の説明を挿入

ネイティブメソッドであることが判明し、戻りタイプはStringであり、現在のタイムスタンプが渡されます。戻り値を直接変更することは非現実的です。レイヤーコード分析チェックコードがどのように生成されるかを確認することしかできません。

残念ながら、ida静的分析を使用すると、一部のパラメーターが表示されないことがわかりましたが、幸いなことに場所パラメーターが見つかりました。動的デバッグに基づいて特定の値を見つけることができます。
ここに写真の説明を挿入
しかし、インターネットによると、jebも非常に機能的であり、そのビューは非常に明確であることがわかりまし
ここに写真の説明を挿入
た。図からわかるように、合計3つのチェックがあり、固定値「dt8re」+「rt9ws」がそれぞれスプライスされています。その中には、hash1とhash2の2つのパラメーターがあり、
計算されます。

現在、動的デバッグには、(1)値を取得する動的デバッグ、(2)フック技術を使用して固定値のタイムスタンプを取得し、戻り値を出力し、制御変数法に従って結果を計算する方法が考えられています。

フック方式のみを以下に示します。

(1)最初にfrida hookjsスクリプトを使用する

Java.perform(function () {
    
    
    var CheckUtils = Java.use("info.zzjian.dididh.util.CheckUtils");
    CheckUtils.getV.overload("long").implementation = function (j) {
    
    
        var ret = this.getV(j);
        console.log(this.getV(0));
        return (ret);
    };
});

印刷結果は次のとおりです。

33cc6f39fdt8re3af08b80crt9ws3ff2a033f

結果によると、それはに分割されます:

(check1)33cc6f39f + dt8re + (check2)3af08b80c + 9ws3f + (check3)f2a033f

制御変数法による

hash1 = -1916912749L;
hash2 = 1344359219L;

次のように最終文字列を見つけます。

String check1 = Long.toHexString(13904573343L + ts * 2);
        String check2 = Long.toHexString(15821486092L + ts);
        String check3 = Long.toHexString(17165845311L + ts);
        return check1 + "dt8re" + check2 + "rt9ws" + check3;

復元されたアルゴリズムに従って、CheckUtils.javaを書き直して、javaレイヤーに直接文字列を返すようにします。

public class CheckUtils {
    
    
    public CheckUtils() {
    
    
    }
 
    public String getV(long ts) {
    
    
        String check1 = Long.toHexString(13904573343L + ts * 2);
        String check2 = Long.toHexString(15821486092L + ts);
        String check3 = Long.toHexString(17165845311L + ts);
        return check1 + "dt8re" + check2 + "rt9ws" + check3;
    }
}

コマンドラインを使用して、記述されたjavaファイルをsmaliファイルに変換します。これは、リソースファイルで表示およびダウンロードできる記述されたスクリプトです(パッケージ名は実際の状況に応じて変更されます)。

.class public Linfo/zzjian/dididh/util/CheckUtils;
.super Ljava/lang/Object;
.source "CheckUtils.java"


# direct methods
.method public constructor <init>()V
    .registers 1

    .prologue
    .line 3
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    .line 4
    return-void
.end method


# virtual methods
.method public getV(J)Ljava/lang/String;
    .registers 8

    .prologue
    .line 7
    const-wide v0, 0x33cc6f39fL

    const-wide/16 v2, 0x2

    mul-long/2addr v2, p1

    add-long/2addr v0, v2

    invoke-static {v0, v1}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;

    move-result-object v0

    .line 8
    const-wide v2, 0x3af08b80cL

    add-long/2addr v2, p1

    invoke-static {v2, v3}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;

    move-result-object v1

    .line 9
    const-wide v2, 0x3ff2a033fL

    add-long/2addr v2, p1

    invoke-static {v2, v3}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;

    move-result-object v2

    .line 10
    new-instance v3, Ljava/lang/StringBuilder;

    invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V

    invoke-virtual {v3, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    const-string v3, "dt8re"

    invoke-virtual {v0, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    const-string v1, "rt9ws"

    invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v0

    return-object v0
.end method

次に
androidkillerのクラス記述されたコードで上書きしコンパイル解除後に結果を正常に取得します。
ここに写真の説明を挿入

補足:もちろん、このapkはフックを検出しないため、Xposedまたはfridahookを直接使用して、VIPをクラッキングする機能を実現できます。著者の声明を確認したところ、著者はXposedを使用して変更を加えることに反対していなかったことがわかりまし
ここに写真の説明を挿入
た。この機会に学ぶ機会がありますが、apkのひびの入ったバージョンはここでは提供されていません。必要な場合は、公式Webサイトから直接元のバージョンをダウンロードできます:http://dddh.pub/

補足:動的デバッグ後、プログラムが64ビットプログラムであることが判明したため、ida32は文字列を表示できず、文字列はida64で正常に表示されます。

ここに写真の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_43632667/article/details/105778450