小規模なビデオ アプリを例とした、OkHttp の一般的なパケット キャプチャ方法の分析

1. 目標

難しすぎます。近年、パケットをキャプチャするのがますます困難になってきています。小さなビデオが頻繁に更新されます。QUIC をブロックするという以前の計画は失敗したようです。

幸いなことに、OkHttpLogger はまだあります- フリーダ

タイプ: v9.10.10.22596

急いでいる学生は、後ろに下がってKnowledgeJS を入手できます。理想を持っている生徒は、次回適応できるように原則を注意深く学ぶことをお勧めします。

2 つのステップ

原理分析

小規模ビデオ アプリ v8.x の署名計算方法 (1) パケット キャプチャから始めましょうこの記事では、OkHttpLogger-Fridaを使用してパケットをキャプチャする v8.0の方法を分析しました。

では、OkHttpLogger-Frida でパケットをキャプチャするには、どのような種類のアプリが適しているのでしょうか?

著者はその原則について次のように説明しています。Okhttp フレームワークを使用してアプリによって送信されるすべてのリクエストは RealCall.java を通じて送信されるため、このクラスをフックしてリクエストと応答を取得できます。

jadx で APK を開きます

メイン.png

簡単に言うと、明らかに Okhttp が見つかったアプリの場合、このスクリプトを使用してパケットをキャプチャできる可能性が高くなります。Okhttp が明らかに見つからなかった場合、混乱する可能性があります。このスクリプトの find コマンドを実行すると、見つけてみてください

問題を分析する

友人の中には、「このスクリプトを試してみたけどうまくいかない、パッケージをキャッチできない」という人もいます。

偉い人たちは皆、ヒスイを引き寄せるためにレンガを投げていますが、誰もあなたが各バージョンに適応するのを手助けするために苦労しません。したがって、私たち自身で適応を行うには、スクリプトの原理を理解する必要があります。

まず okhttpfind.dex を /data/local/tmp/ にコピーします

次に、frida -U -l okhttp_poker.js -f com.example.demo --no-pause が実行されました。

まずfind()コマンドを実行し、出力された結果から、このアプリがokhttp3 を使用していることがわかり、この行の出力を書き留めます。

var Cls_okio_Buffer = "okio.f";

これでパケットのキャプチャを開始できるようになり、hold()コマンドを入力します。

素晴らしいですね、URL とリクエスト ヘッダー情報を出力することがすでに可能です。

ここには 2 つの問題があります。

1. リクエストボディが印刷されない場合は、「ファイルリクエストボディ省略...」というメッセージが表示されます。

2. 応答データは印刷されません。

3. このようなエラーがあります

print request error :  Error: writeTo(): argument types do not match any of:
	.overload('okio.g')
    at X (frida/node_modules/frida-java-bridge/lib/class-factory.js:563)
    at value (frida/node_modules/frida-java-bridge/lib/class-factory.js:966)
    at e (frida/node_modules/frida-java-bridge/lib/class-factory.js:547)
    at printerRequest (/okhttp_poker.js:171)
    at printAll (/okhttp_poker.js:106)
    at <anonymous> (/okhttp_poker.js:89)
    at <anonymous> (frida/node_modules/frida-java-bridge/lib/vm.js:16)
    at perform (frida/node_modules/frida-java-bridge/index.js:193)
    at buildNewResponse (/okhttp_poker.js:98)
    at <anonymous> (/okhttp_poker.js:510)
    at apply (native)
    at ne (frida/node_modules/frida-java-bridge/lib/class-factory.js:613)
    at <anonymous> (frida/node_modules/frida-java-bridge/lib/class-factory.js:592)

適応コード

まず最初の質問を見てください。okhttp_poker.js:160 行に fi​​lterUrl 判定があります。本来の目的は画像ファイルをフィルタリングすることですが、リクエスト値または戻り値に "jpg" や "png" などの文字列が含まれている場合したがって、正確に判断し、最後のいくつかの文字列が一致した場合にのみフィルタリングする必要があります。

var filterArray = [".JPG", ".jpg", ".PNG", ".png", ".WEBP", ".webp", ".JPEG", ".jpeg", ".GIF", ".gif",".zip", ".data"]
......

/**
 *  fenfei 过滤url
 *  false 显示
 *  true  拦截 不显示 返回信息
 */
function filterUrl(url) {
	
	//*
    for (var i = 0; i < filterArray.length; i++) {
        // if (url.indexOf(filterArray[i]) != -1) {
            // console.log(url + " ?? " + filterArray[i])
        //    return true;
        //}

        if (url.lastIndexOf(filterArray[i]) >= (url.length - 6) ) {
           // console.log(url + " ?? " + filterArray[i])
           return true;
        }
		
    }
	// */
	
    return false;
}

2 番目の問題の理由は今のところ明らかではないため、まずエラー レポートを解決しましょう。

printerRequest (/okhttp_poker.js:171) に次のコードがあります。

        var buffer = BufferWapper.$new()
        requestBody[M_reqbody_writeTo](buffer)

これは、requestBody の値を BufferWapper 型のバッファ変数に書き込むことを意味します。

BufferWapper のタイプは ** var Cls_okio_Buffer = "com.singleman.okio.Buffer"; **

この解決策にはすでに 2 つのヒントがあります。

1. エラー メッセージは、ここに okio.g タイプが必要であることを思い出させます。

2. 最初に見つかった場合、このアプリでは var Cls_okio_Buffer = “okio.f” を指定するように求められます。

それでは、okio.g または okio.f を使用する必要がありますか?

jadx によって分析されたコードを見てみましょう

public interface g extends z, WritableByteChannel {
......
}

public final class f implements h, g, Cloneable, ByteChannel {
......
}

okio.g はインターフェースクラス、okio.f はそれを継承する実装クラスです。したがって、#okio.f# を使用するのは間違いありません。

このように変更します

// add fenfei 适配 910
// var buffer = BufferWapper.$new()

var ffBufferWapper = Java.use("okio.f");
var buffer = ffBufferWapper.$new();

もう一度実行すると、今度は非常に美しく、リクエストとレスポンスの両方が出力されます。

最後の質問

このパケット キャプチャを追加した後、アプリが突然非常に不安定になり、しばらく停止するか、ネットワークにアクセスできなくなりました。

この問題は私たちの js が原因であるはずです。しかし、正確には何が原因でしょうか?問題のトラブルシューティング方法は?

この種の問題を解決する最良の方法は消去

1. printAll 関数をブロックすると、何も印刷されず、アプリは正常に実行されます。これは、フックが正常であり、問​​題が印刷にあることを示します。

2. 印刷は printerRequest と printerResponse の 2 つの部分に分かれており、シールド方法により、printerResponse に問題があることがわかります。

3. printerResponse 関数でマスキング メソッドを使用し続けると、問題が getByteString 関数のバッファ [M_buffer_readByteArray] にあることがわかります。つまり、応答本文が読み取られている限り、問題は存在します。

現状ではバッファの読み込みに問題があるのではないかと感じています、読み込み競合かもしれません、フックスクリプトがバッファを読み込んでいるためにアプリが結果を読み取れず、色々とおかしな問題が発生しています。

そこで、読み込み関数を変更したり、バッファをディープコピーしたり、さまざまな方法を試しましたが、どれも成功しませんでした。最終的に、作成者が 1 つの手を保留していたことが判明し、実際には、作成者は Response 本文のディープ コピーを作成し、newResponse を生成していました。

したがって、フックを続けて出力し、生成された newResponse をアプリに返すだけで問題ありません。

もう一度実行して、これで終わりです。

3. まとめ

教義を使うのは簡単ですが、原理を理解した上で適応できるかどうかの方が重要です。

問題が発生した場合は、まず可用性を最小限にする原則に従い、コードを段階的にブロックして範囲を狭め、問題を定義します。

ffshow.jpeg

人生の後悔を思う限り、南山中に梅の花が散るでしょう

おすすめ

転載: blog.csdn.net/fenfei331/article/details/122661732