序文
これまでに JS リバース エンジニアリングに関するいくつかの知識を学習しましたが、それらはいずれも比較的基本的なものであり、基本的には JS の機能を補足するためにのみ使用できます。今回は、Douyin を例として、環境と開発者ツールでブレークポイントをデバッグする新しい方法を試します。
1. 目標分析
1. フィルターインターフェイス
まず、ユーザーのホームページをランダムに選択すると、いくつかの作品が表示され、そのユーザーに基づいてすべての作品へのリンクを取得し、ダウンロードすることが目的です。
要求されたインターフェイスが多数あり、最終的にターゲット インターフェイスが選別されます。
キーワードで検索するとvideo
いくつかのURLアドレスが表示されます
次に、そこにアクセスして、それが本物のダウンロード リンクであるかどうかを確認します。
確かに、それが起こったのです。
2. リクエストヘッダーを確認する
ここにはスクリーンショットはありませんが、実際には特別なフィールドはそれほど多くないため、Cookie は少し特殊です。
3.ロード
この部分には暗号文である 3 つのフィールドがあります
どれが決定的なのかは分かりませんが、全部必要なのかもしれないし、一つしかないのかもしれません。
2. 論理的分析
1. リクエストエントリを見つけます。
まずは簡単な方法、つまりキーワード検索を使用してください。それがうまくいかない場合は、他の方法を検討してください。ただし、この Web サイトでX-Bogusを検索すると、見つけることはできますが、ブレークポイントに到達した後、そこに移動しないことがわかります。ここではこれ以上のデモンストレーションはありません。他の 2 つの暗号文フィールドにも同じことが当てはまります。
したがって、最も安全な方法は、ランチャーから場所を見つけることです。
これは ajax リクエストであることがわかりますが、ここから多くのリクエストが送信されていることがわかり、対象のインターフェイスを追跡するのは簡単ではありません。ただし、このインターフェイスのみをトレースする新しい方法を使用できます。
ここにブレークポイントを追加してターゲット URL を入力します。ただし、最初に以前のブレークポイントをすべてキャンセルすることを忘れないでください。
ここで自動停止し、対象のURLが表示されることがわかります。
実際、ここに来たら、コンソールで と入力するとthis
、最後に XB 値が生成されたことがわかります。
"/aweme/v1/web/aweme/post/?device_platform=webapp&aid=6383&channel=channel_pc_web&sec_user_id=MS4wLjABAAAAqwlfqpCgGCpMAxMEQm_evPUupsTBamwkG5-s6LWqqOgBTv9tniP-7P6QrjK4-m1N&max_cursor=0&locate_query=false&show_live_replay_strategy=1&need_time_list=1&time_list_query=0&whale_cut_token=&cut_version=1&count=18&publish_video_strategy_type=2&pc_client_type=1&version_code=170400&version_name=17.4.0&cookie_enabled=true&screen_width=1920&screen_height=1080&browser_language=zh-CN&browser_platform=MacIntel&browser_name=Chrome&browser_version=116.0.0.0&browser_online=true&engine_name=Blink&engine_version=116.0.0.0&os_name=Mac+OS&os_version=10.15.7&cpu_core_num=8&device_memory=8&platform=PC&downlink=10&effective_type=4g&round_trip_time=150&webid=7304127941348312585&msToken=m481D4fH-oOr3yUt_GMWxmhIvvFhjoWXQnWK8AK0ZaKuEwbkp-goBkCM5C6N4u03IiMM2JGF064qCIXQjKgQm-SOnXG3OSDbTLhDezOjda_r4pzEL3Fl9MWytJ904EJI&X-Bogus=DFSzswVOcYsANSTItmLIGMm4pIDg"
したがって、前のステップ呼び出しを確認できます。
この時点で、それがこの行によって生成された暗号文であることは間違いありませんが、_0xc26b5e, _0x1f1790
これら 2 つの値は常に変化していることがわかります。ここで文法について簡単に説明しましょう。
_0x2458f0['y']++) : _0xcc6308[++_0x2e1055] = _0x2458f0['apply'](_0xc26b5e, _0x1f1790);
apply
this
これは、関数を呼び出すために使用される JavaScript の関数メソッドであり、関数の実行時にコンテキスト (値) を指定し、関数のパラメーターとして配列または配列のようなオブジェクトを渡すことができます。
このコード行では、オブジェクトのメソッド_0x2458f0['apply']
を呼び出すことを意味します。このメソッドの目的は、関数を呼び出し、配列または配列のようなオブジェクトの要素をパラメーターとして関数に渡すことです。_0x2458f0
apply
具体的には:
_0x2458f0
: これはオブジェクトです。おそらく関数オブジェクトです。.apply
: 関数を呼び出すために使用される JavaScript 関数オブジェクトのメソッドです。_0xc26b5e
apply
: これは、メソッドの最初の引数として渡される関数です_0x2458f0
。_0x1f1790
apply
: これは、メソッドの 2 番目のパラメータとして関数に渡される配列です_0x2458f0
。
この行の目的は、_0x2458f0
オブジェクト内の関数 (おそらく関数配列内の要素) をコンテキスト_0xc26b5e
として呼び出し、_0x1f1790
配列をパラメーターとして渡し、結果を に割り当てることです_0xcc6308[++_0x2e1055]
。
しかし、それでも見つけるのは難しいです。追跡を続けるには、ログ ブレークポイントと条件付きブレークポイントの 2 つの方法があります。最初の_0x2458f0['apply'](_0xc26b5e, _0x1f1790)
ブレークポイント: ログ ブレークポイント: console.log(_0x2458f0['apply'](_0xc26b5e, _0x1f1790))
。大量の出力がありますが、URL や XB の最初の数文字などのキーワードをフィルタリングできます。
XB 値が表示され、URL も表示されることがわかります。次に、条件付きブレークポイントを使用して、XB 値が出力されたときに停止し、関数をトレースできます_0x2458f0['apply'](_0xc26b5e, _0x1f1790).length==28
。XB値の長さは28ビットなので、これで判断できます。
2.暗号化関数を見つける
更新すると中断されるので、値を確認してください
次に関数をトレースすると、XB 値が表示されることがわかります。
位置決めが終わりました。
3. コードの実装
3.1 JS部分
実装方法は2つあり、1つ目は機能を補完する方法、2つ目は環境を補完する方法です。
3.1.1 補数関数
まず最初のオプションを見てみましょう。ファイル全体をコピーして、それを直接実行します。
ReferenceError: window is not defined
増加window = global
ReferenceError: Request is not defined
コードを見つけます。
var _0x2aa7e4 = Request && Request instanceof Object
, _0x2b58b8 = Headers && Headers instanceof Object;
2 つのブール値があることがわかります。コンソールで実行すると、どちらも true であることがわかります。コードを変更します。
var _0x2aa7e4 =true
, _0x2b58b8 = true;
ReferenceError: document is not defined
実際、ここで提案されているのは、document['referrer']
コンソールまたはリクエスト ヘッダーにコピーするだけでよいということです。
document = {
"referer":'https://www.douyin.com/user/MS4wLjABAAAAjemOgh7N4uocHHEMmnTrewBlqxuGnVMPr4kVZv6h12s',
}
TypeError: document.addEventListener is not a function
リファラーと同じように、以下を追加するだけです。
document = {
"referer":'https://www.douyin.com/user/MS4wLjABAAAAjemOgh7N4uocHHEMmnTrewBlqxuGnVMPr4kVZv6h12s',
'addEventListener': function addEventListener(){
}
}
この時点で、エラーが報告されなくなっていることがわかります。その後、グローバル変数を使用して XB 値を取得し、以前に暗号化された関数を見つけることができます_0x5a8f25
。
function _0x5a8f25(_0x48914f, _0xa771aa) {
return ('undefined' == typeof window ? global : window)['_$webrt_1668687510']('484e4f4a403f52430017211b45bdadd5a9f8450800000000000007fa1b0002012f1d00921b000b191b000b02402217000a1c1b000b1926402217000c1c1b000b190200004017002646000306000e271f001b000200021d00920500121b001b000b031b000b19041d0092071b000b0401220117000b1c1b000b051e01301700131b00201d00741b000b06260a0000101c1b000b07260a0000101c1b001b000b081e01311d00931b001b000b091e00091d00941b0048021d00951b001b000b1d1d009d1b0048401d009e1b001b000b031b000b18041d00d51b001b000b0a221e0132241b000b031b000b0a221e0132241b000b200a000110040a0001101d00d71b001b000b0a221e0132241b000b031b000b0a221e0132241b000b1a0a000110040a0001101d00d91b000b0b1e00161e01330117002d1b000b0b1e001602000025001d11221e006e24131e00530201340200701a020200000a000210001d01331b001b000b0c1e00101d00da1b000b232217000e1c211b000b23430201353e1700151b001b000b23221e0133240a0000101d00da1b001b000b0d261b000b1c1b000b1b0a0002101d00db1b001b000b0e261b000b241b000b230a0002101d00dd1b001b000b0f261b000b250200200a0002101d00e11b001b000b0a221e0132241b000b031b000b26040a0001101d00e21b001b000b101a00221e00dc240a0000104903e82b1d00e31b001b000b11260a0000101d00e41b001b000b1f1d00e71b001b000b1c4901002b1d00e81b001b000b1c4901002c1d00ea1b001b000b1b1d00ee1b001b000b21480e191d00f31b001b000b21480f191d00f91b001b000b22480e191d00fa1b001b000b22480f191d00fc1b001b000b27480e191d00ff1b001b000b27480f191d01011b001b000b284818344900ff2f1d01021b001b000b284810344900ff2f1d01041b001b000b284808344900ff2f1d01361b001b000b2848003