フリダでAPKネットワークパッケージを取得する方法
1. 落とし穴の分析に重点を置きます
パケットをキャプチャするためにパケットをキャプチャするのではなく、システムの観点からフック ポイントを探します。
1.okhttp 呼び出しプロセス
public static final MediaType JSON = MediaType.get("application/json; charset=utf-8"); OkHttpClient client = new OkHttpClient(); String post(String url, String json) throws IOException { RequestBody body = RequestBody.create(json, JSON); Request request = new Request.Builder() .url(url) .post(body) .build(); try (Response response = client.newCall(request).execute()) { return response.body().string(); } }
クライアントの重要なコードは client.newCall() にあります。上記は okhttp 公式 Web サイトの例です。ここでのインターフェース呼び出しから始まり、最終的には okhttp フレームワークに呼び出されますが、okhttp は元々 SDK でしたが、その後 AOSP がシステムに統合されたため、フレームワーク層に分類されます。
フレームワーク層については詳しく説明しませんが、主に次の Java クラスです:
com.android.okhttp.internal.huc.HttpURLConnectionImpl com.android.okhttp.internal.http.HttpEngine com.android.okhttp.internal.http.RetryableSink com.android.okhttp.internal.http.CacheStrategy$Factory
実際には、client.newCall は最終的に URL 経由で接続を取得します
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
ここでの urlConnection は次のとおりです。実際には HttpURLConnectionImpl のインスタンス。このクラスには getInputStream getOutputStream メソッドがあり、HttpEngine の getBufferedRequestBody と getResponse を内部でそれぞれ呼び出します。最初はこの2つのインターフェースをフックしてみましたが、例えばgetResponseをフックするとレスポンスが出力できるようになりましたが、
後になって、Requestはヘッダーのみ出力できてボディは出力できないことがわかりました。そこで、解析に没頭したところ、getBufferedRequestBody 関数を使用してシンクを取得できることがわかりました。最後に、RetryableSink がブレークスルー ポイントとして使用されます。たとえば、その write 関数をフックすると、本文を出力できます。 write 関数は、アプリ レベルの urlConnection.getOutputStream().write に対応します。
後で、リクエストの場合、getBufferedReuqestBody 関数が複数回呼び出される可能性があるため、データの重複の問題が発生することがわかりました。その後、フックする CacheStrategy$Factory.get ポイントを見つけて、データの重複がまだ存在することがわかりました。上記のフックにはすべて欠点があることが判明しました。
データの重複
- #non-okhttp 呼び出しはキャプチャできません
okhttp流程:sdk接口->okhttp框架->native(libc)
- android.util.Log が出力されません
var Logd = function Logd(tag, msg) { Java.use("android.util.Log").d(tag, msg); }; Logd('http-body-', '11111111111111');//该log不打印 Logd('http-body', '11111111111111');//该log打印
ログイン後にコピー - 匿名の内部クラスではメンバーを取得するためにリフレクションが必要です
var printRequest = function(request) { var Buffer = Java.use("com.android.okhttp.okio.Buffer"); var bodyField = request.getClass().getDeclaredField('body'); bodyField.setAccessible(true); if (request == null) return; Logd('http', 'printRequest: request' + request); //var requestBody = request.body();//gadget直接报错 var requestBody = bodyField.get(request); var requestBodyClass = requestBody.getClass(); var ClassInstanceArray = Java.array('java.lang.Class', []); //var contentLengthMethod = requestBodyClass.getMethod("contentLength");//gadget直接报错 var contentLengthMethod = requestBodyClass.getMethod("contentLength", ClassInstanceArray); contentLengthMethod.setAccessible(true); var ObjectInstanceArray = Java.array('java.lang.Object', []); var contentLength = requestBody ? contentLengthMethod.invoke(requestBody, ObjectInstanceArray) : 0; //if (contentLength == 0) contentLength = contentLen; Logd('http', 'printRequest contentLength: ' + contentLength); if (contentLength > 0) { var BufferObj = Buffer.$new(); requestBody.writeTo(BufferObj); Logd(TAG, "\nrequest body :\n" + BufferObj.readString() + "\n"); } };
ログイン後にコピー - android.os.Bundle の印刷には Bundle unparcel が必要です
var printIntentAndExtras = function printIntentAndExtras(intentObj) { if (intentObj == null) return; var Intent = Java.use("android.content.Intent"); var Bundle = Java.use("android.os.Bundle"); var bundleObj = Intent.getExtras.call(intentObj); if (bundleObj != null) { Bundle.getSize.call(bundleObj, null);//调用getSize即可反序列化 } Logd(TAG, ‘printIntentAndExtras ’ + bundleObj); };
ログイン後にコピー
- java.net.URL インターセプション
var URLHook = function() { var URL = Java.use('java.net.URL'); URL.openConnection.overload().implementation = function() { var retval = this.openConnection(); Logd('URL', openConnection' + retval); return retval; }; };//URL.openConnection调用概率比较大,但是不一定对网络进行请求
ログイン後にコピー - アプリが http リクエストを呼び出す前に json を使用するインターセプト。これはそのうちの 1 つです
var jsonHook = function() { var xx = Java.use('e.h.a.a');//app smali var xxa_method = xx.a.overload('org.json.JSONObject', 'java.lang.String', 'java.lang.String'); xxa_method.implementation = function(jsonObj, str1, str2) { Logd("json", jsonObj + " str1: " + str1 + " str2" + str2); xxa_method.call(this, jsonObj, str1, str2); } }
ログイン後にコピー - trace http 関連クラス
var traceAllHttpClass = function() { Java.perform(function() { Java.enumerateLoadedClasses({ onMatch: function(name, handle) { /*"e.h.a.a$a",起初也拦截过app的该混淆类*/ if (name.indexOf("com.android.okhttp.Http") != -1 || name.indexOf("com.android.okhttp.Request") != -1 || name.indexOf("com.android.okhttp.internal") != -1) { traceClass(name);//对这三个class进行trace } }, onComplete: function() { } }); }); };
ログイン後にコピー - Request$Builder インターセプション
var BuilderClass = Java.use('com.android.okhttp.Request$Builder') BuilderClass.build.implementation = function () { //LOG('com.android.okhttp.HttpUrl$Builder.build overload', { c: Color.Light.Cyan }); //printBacktrace(); var retval = this.build(); Logd(TAG, "retval:" + retval); printRequest(retval); return retval; }
ログイン後にコピー - property_get インターセプション
var nativePropertyGetAddr = Module.findExportByName(null, '__system_property_get'); Interceptor.attach(nativePropertyGetAddr, { onEnter: function onEnter(args) { this._name = args[0].readCString(); this._value = args[1]; }, onLeave: function onLeave(retval) { if (this._name.indexOf("ro.build.id") != -1) { var virtualDevice = getVirtualDevice(); if (DEBUG_PROP) Logd(TAG, "__system_property_get fake " + this._name + "=>to " + virtualDevice.build_id); this._value.writeUtf8String(virtualDevice.build_id); } var strFilter = /^ro\./g; if (DEBUG_PROP && this._name.match(strFilter) != null) Logd(TAG, "__system_property_get " + this._name); } });
ログイン後にコピー
var DEBUG_PROP = false;
var DEVICE_CONFIG = "/sdcard/.device";
function getVirtualDevice() {
var nativeOpen = new NativeFunction(Module.findExportByName(‘libc.so’, 'open'), 'int', ['pointer', 'int']);
var nativeRead = new NativeFunction(Module.findExportByName('libc.so', 'read'), 'int', ['int', 'pointer', 'int']);
var fd = nativeOpen(Memory.allocUtf8String(DEVICE_CONFIG), 0);
var mem = Memory.alloc(1024);
var readLen = nativeRead(fd, mem, 1024);
var json = JSON.parse(mem.readCString(readLen));
return json;
}
Secure.getString.implementation = function () {
var retval = this.getString(arguments[0], arguments[1]);
if (DEBUG_PROP) Logd(TAG, "Settings.Secure get " + arguments[1] + " val " + retval);
if (arguments[1].indexOf("android_id") != -1) {
var virtualDevice = getVirtualDevice();
return virtualDevice.android_id;
}
return retval;
};
ログイン後にコピー によって引き起こされるユーザーの有効期限に対処する
3. パケット キャプチャ ツール フィドルを使用してパケットをキャプチャし、トラップから抜け出す1 .fiddle プロキシ設定は正常です、アプリですが、ログインできませんadb ログを分析した後、プロセスで java.security.cert.CertPathValidatorException が出力されました。また、frida がパケットをインターセプトし、証明書をバイパスすることに関する投稿もいくつか見ました。前に。最初にブルート フォース検索を試してください:
var DEBUG_PROP = false; var DEVICE_CONFIG = "/sdcard/.device"; function getVirtualDevice() { var nativeOpen = new NativeFunction(Module.findExportByName(‘libc.so’, 'open'), 'int', ['pointer', 'int']); var nativeRead = new NativeFunction(Module.findExportByName('libc.so', 'read'), 'int', ['int', 'pointer', 'int']); var fd = nativeOpen(Memory.allocUtf8String(DEVICE_CONFIG), 0); var mem = Memory.alloc(1024); var readLen = nativeRead(fd, mem, 1024); var json = JSON.parse(mem.readCString(readLen)); return json; } Secure.getString.implementation = function () { var retval = this.getString(arguments[0], arguments[1]); if (DEBUG_PROP) Logd(TAG, "Settings.Secure get " + arguments[1] + " val " + retval); if (arguments[1].indexOf("android_id") != -1) { var virtualDevice = getVirtualDevice(); return virtualDevice.android_id; } return retval; };
Java.perform(function(){ const groups = Java.enumerateMethods('*!verify/u'); var classes = null; for(var i in groups){ var classes = groups[i]['classes']; for(var i in classes){ Java.use(classes[i]['name']) .verify .overload('java.lang.String', 'javax.net.ssl.SSLSession') .implementation = function() { printBacktrace(); LOG("[+] invoke verify", { c: Color.Red }); return true; } } } });
res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<!--添加fiddle证书可信任
<certificates src="user" />
-->
</trust-anchors>
</base-config>
</network-security-config>
HTTP/1.1 200 OK
Date: Sun, 16 Aug 2020 06:27:34 GMT
Content-Type: application/json
Content-Length: 101
Connection: keep-alive
Grpc-Metadata-Content-Type: application/grpc
Vary: Origin
Vary: Accept-Encoding
{"result":{"errno":"OK","errmsg":"成功"},"data":{"version":"xxxxxxxx-351e-40cf-aaa9-3177d6df9b7f"}}
-----------------------------------
HTTP/1.1 200 OK
Date: Sun, 16 Aug 2020 06:27:34 GMT
Content-Type: application/json
Content-Length: 99
Connection: keep-alive
Grpc-Metadata-Content-Type: application/grpc
Vary: Origin
Vary: Accept-Encoding
{"result":{"errno":"OK","errmsg":"成功"},"data":{"nodeToken":"xxxxxxxc24d79f55c0b07beaf50cb566"}}
POST https://tap-xxxxxxx.xxxxxx.com/api/v2/Android/analytics/basic HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cjbcjdsabcjvbXVCJ9.eyJ1aWQiOjE4ODMzMDEsInNlY3JldCI6IjAzNzE0M2Y3LTExMTUtNGY2Yi1iNzQxLWUyMjc5ZDM3MGY3MCIsImV4cCI6MTU5NzgxNjQ0MiwiaXNzIjoiZ3Vlc3QgbG9naW4ifQ.W3SiO0-afbhxPITjRinnhyWhZLy1bzZhYexm5VCWklI
X-Device-ID: 9xxxxxxx84d4542e
X-Loc: ["China","Shanghai","Shanghai","","ChinaUnicom","31.224349","121.4767528","Asia/Shanghai","UTC+8","310000","86","CN","AP","xxx.166.xxx.xxx"]
X-App-Version: 2.2.0
Content-Type: application/json; charset=utf-8
Content-Length: 208
Host: xx-xxxx.xxxxxx.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/4.7.2
{"deviceID":"9xxxxxxx84d4542e","model":"V1813BA","systemVersion":"9","version":"2.2.0","location":{"latitude":xx.x99x990990991,"longitude":xxx.26689769073256},"network":{"g2":0,"g3":0,"g4":4,"g5":0,"wifi":4}}
-----------------------------------
HTTP/1.1 200 OK
Date: Sun, 16 Aug 2020 06:27:35 GMT
Content-Type: application/json
Content-Length: 43
Connection: keep-alive
Grpc-Metadata-Content-Type: application/grpc
Vary: Origin
Vary: Accept-Encoding
{"result":{"errno":"OK","errmsg":"成功"}}
以上がフリダでAPKネットワークパッケージを取得する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









最新アップデート (v15.29.34.29 ベータ版) の APK 分解を考慮すると、Google の AI アシスタント Gemini はさらに高性能になる予定です。このテクノロジー巨人の新しい AI アシスタントには、いくつかの新しい拡張機能が追加される可能性があると伝えられています。これらの拡張機能は

侵入テストの初心者として、この記事の目的は、私のような初心者にテストのアイデアを提供することです。内容は比較的基本的なものになるかもしれませんが、ご容赦ください。 APK を解凍して APK を取得した後、7-Zip を使用して直接解凍し、いくつかのフォルダー、AndroidManifest.xml ファイル、および dex ファイルを取得します。 dex2jar https://sourceforge.net/projects/dex2jar/ を使用してこの dex ファイルを解凍し、jar ファイルを生成し、jd-gui を使用して Java ソース コードを表示します。もちろん、ソース コードからコードの抜け穴を見つけることはできますが、通常は混乱が生じるため、ここでは詳しく説明しません。

APK という文字で終わるファイルをダウンロードしたことがありますか?これは通常、携帯電話で動作し、コンピュータにロードされているアプリで発生します。これらのファイルのほとんどは APK という文字で終わります。これらのファイルを開こうとしても、拡張子が特殊なため、保存場所や開き方がわからない場合があります。 Windows 11 でそのようなファイルを開く方法を探していて、Google で検索したことがあっても、心配しないでください。実際にはそれよりもはるかに簡単です。実際、これは無料で、何もインストールする必要さえありません。オペレーティング システム用の APK ファイル オープナーをダウンロードする必要がありますが、まだダウンロードしていない場合に限ります。

変更手順: 1. 名前を変更したい APK ファイルがコンピュータに保存されていることを確認します; 2. APK ファイルを右クリックし、[名前の変更] オプションを選択します; 3. 元のファイル名を新しい名前に置き換えます希望の名前。ファイル拡張子「.apk」ではなく、ファイル名の部分のみを変更してください。 4. Enter キーを押すか、ウィンドウの「名前の変更」ボタンをクリックして変更を保存します。

1. パケットをキャプチャするためだけにパケットをキャプチャするのではなく、システムの観点から落とし穴を分析し、フック ポイントを見つけます。 1.okhttp 呼び出しプロセス publicstaticfinalMediaTypeJSON=MediaType.get("application/json;charset=utf-8");OkHttpClientclient=newOkHttpClient();Stringpost(Stringurl,Stringjson)throwsIOException{RequestBodybody=RequestBody

Unity3D プログラム コードのセキュリティ上の問題 Unity3D プログラムのコア アセンブリ ファイル Assembly-CSharp.dll は、標準の .NET ファイル形式であり、メソッド名、クラス名、型定義などの豊富なメタデータ情報が付属しています。 DnSpyなどのツールを使用すると簡単に逆コンパイルや改ざんができ、コードロジックやクラス名、メソッド名などが一目でわかります。コード ロジックが逆コンパイルされると、さまざまな種類のプラグインが繁殖しやすくなり、ゲーム バランスが崩れやすくなります。開発者。リソースのセキュリティの問題: コンパイルとパッケージ化の段階で、Unity3D プログラムは Unity エディターを通じてリソースを AssetBun にパッケージ化します。

ご存知のとおり、Microsoft は win11 で Android アプリケーションを実行し、ローカル APK をインストールできるようになると発表しました。しかし、Win11 をアップデートした後、ユーザーはローカル APK をインストールする方法がわからないことに気づきました。実際、これは Microsoft がまだ行っていないためです。この機能はまだwin11に実装されていないため、使用するには機能がインストールされるまで待つ必要があります。 win11 にローカル apk をインストールする方法: 1. Microsoft によると、win11 にこの機能がインストールされた後、ダウンロードした apk ファイルを直接ダブルクリックして直接インストールできます。 2. インストールが完了したら、ユーザーはシステム内で直接実行することもできます。 3. これは win11 の正式バージョンですが、Microsoft はまだこの機能を win11 に実装していません。 4. ユーザーが win11 を使用したい場合

1. はじめに apk が暗号化されていない場合は、逆コンパイルすると smail ファイルが得られます。注入する必要があるコードを注入するだけです。そして捺印と署名をしてください! 2. apk の作成 androidstudio を使用して簡単な apk を生成します。デフォルトのコードをそのまま使用してください。 packagecom.example.myapplication1;importandroidx.appcompat.app.AppCompatActivity;importandroid.os.Bundle;publicclassMainActivityextendsAppCompatActivity{
