Atlas

Atlas

Do you 👂 the people sing?
twitter
twitter

友達の輪データをエクスポートしてブロックチェーンに永続化する方法

これは実際には二つの問題です。最初の問題は、自分の友達のサークルデータをエクスポートする方法、二つ目の問題は、そのデータをブロックチェーンに保存する方法です。成果を先に述べると、最終的に私は iOS システムの 8.0.32 バージョンの WeChat から自分の友達のサークルデータをエクスポートし、Crossbell ブロックチェーンに保存することに成功しました:https://xfeed.app/u/wxd6bb23a9

私がこの件を研究した理由は、2023 年 2 月 4 日に私のWeChat が禁止された後、自分の友達のサークルの内容をエクスポートして再表示したいと思ったからです。その間、私は多くの資料を検索しましたが、どれも古いバージョンの解決策でした。だから、今こそ自分の探索や踏んだ落とし穴を記録しておくべきだと思いました。

事前に声明します:

  1. 私はコメントデータをエクスポートしていません。なぜなら、必要ないと思ったからです。結局、ブロックチェーンに保存することの一部の意味は所有権を確認することにあり、この件で他の人の内容をブロックチェーンに保存することにはあまり意味がありません。しかし、もし本当に必要であれば、実現するのはそれほど難しくないと思います。MyWC_Message01 というテーブルには明文で保存されたコメントがあるのを見ましたが、完全なものであるかどうかは不明です。必要があれば、このチュートリアルを参考にして自分で研究を続けてください。
  2. 私は他人の友達のサークルデータをエクスポートしていません。同様に必要ないと思いました。しかし、もしエクスポートが必要であれば、どのテーブルから始めるべきかは推測できます。
  3. 私は WeChat の友達 / チャット履歴をエクスポートしていません。これは一般的なニーズかもしれませんが、私はこの点であまり必要がなかったので研究しませんでした。しかし、おそらく別のテーブルからデータをエクスポートするだけで、それほど面倒ではないでしょう。
  4. 私は動画アカウントの共有を解析していません。普通のリンク共有は解析できますが、動画アカウントは非常に不明瞭で、実際の動画リンクを復元するのが難しいです。また、私は動画アカウントをあまりリツイートしないので、これを解析する必要はあまりありません。

目標を明確にする:友達のサークルデータをエクスポートする#

現在のニーズが友達のサークルデータをエクスポートすることであると仮定すると、実際にはいくつかの状況に分かれます。異なる状況には異なる方法があります:

  • あなたが WeChat ユーザー(WeChat のユーザーではなく)であれば、公式にデータエクスポートのインターフェースが提供されています。以前のこのブログを参考にしてください。もしブロックチェーンに表示したい場合は、このブログもご覧ください。
  • もし WeChat ユーザーであれば
    • あなたの WeChat が禁止されていない場合は、淘宝で「WeChat 友達のサークル」を検索してみてください。あなたの WeChat 友達のサークルをエクスポートして電子書籍にするサービスがたくさんあります(実際、淘宝の商人がどうやってやっているのか興味があります。キャッシュを通じてやっているのかどうかはわかりません)。
    • あなたの WeChat が私と同じように禁止されている場合、または禁止されていなくてもデータをエクスポートする方法に興味がある場合は、次に重点的に紹介するスマホのキャッシュからデータを復元する方法を試してみてください。この方法が可能な理由は、WeChat アカウントが禁止されても、自分の友達のサークルにはアクセスできるからです(幸運なことに)。

キャッシュからデータを復元する方法#

名前の通り、このアプローチの方法は、まず WeChat がローカルに自分の友達のサークルをキャッシュしていることを確認し、その後自分のスマホのデータをエクスポートし、最後にエクスポートしたデータから関連するファイルを見つけ、そこから有用な情報(公開時間、友達のサークルの内容など)を抽出し、最後に完全な友達のサークルデータを再構築することです。

1. ローカルキャッシュ#

WeChat を開き、キャッシュをクリアします(このステップは必須ではありませんが、バックアップやコピーに必要な待機時間を短縮できます)。その後、自分の友達のサークルを開き、最初の投稿までスクロールし、自分のすべての友達のサークルをローカルにキャッシュします。各画像も開く必要があります。さもなければ、キャッシュされるのはサムネイルだけです。すべてが正常にキャッシュされたことを確認するために、ページをめくった後にネットワークを切断して、まだ見ることができるか確認します。見ることができれば、キャッシュが成功したことを意味します。

2. キャッシュファイルをエクスポート#

私の WeChat は iOS システムでログインしているため、禁止された後に他のデバイスでログインできるかどうかわかりません(夜が長くなると心配なので、試行回数が多すぎると、ログインできる iOS デバイスにもログインできなくなってしまうかもしれません)。そのため、スマホのバックアップを通じてキャッシュをエクスポートするしかありません。Android システムではキャッシュファイルを直接エクスポートできるはずですが、iOS のメカニズムではアプリ自身のキャッシュファイルに直接アクセスできないため、スマホ全体のバックアップを通じて行う必要があります。

私が使用しているツールは iMazing で、無料版で十分です。まずスマホのデータをバックアップし、次に WeChat の Documents フォルダを見つけてエクスポートします。手順は以下の図の通りです。無料版の iMazing には 10 回のエクスポートの機会があります。
image

Documents フォルダ内には、少なくとも Hash 文字列で命名されたフォルダが一つ存在します。例えば、以下のようなものです。

eb8a6093b56e2f1c27fbf471ee97c7f9

このようなフォルダには、WeChat ユーザーの個人データが保存されています。このスマホで複数の WeChat にログインしていた場合、複数のこのような Hash 命名のフォルダが存在する可能性があります。どれが自分がエクスポートしたいものであるか不明な場合は、すべてエクスポートしてみてください。

./Documents/{hash}/wc/wc005_008.db と ./Documents/{hash}/DB/WCDB_Contact.sqlite を見つけます。これらの二つが解析する必要のあるキャッシュファイルです。前者は友達のサークルデータに関連するテーブルで、後者は友達データに関連するテーブルです。ここでは、このテーブルが必要なのは、自分のアカウントのプロフィール画像を解析するためだけです。

(踏んだ落とし穴:新しいバージョンの Mac では iTunes バックアップができなくなりました)

3. キャッシュを解析#

TL;DR このリポジトリをダウンロードし、wc005_008.dbWCDB_Contact.sqlite をルートディレクトリにドラッグし、main.pyの hash を自分の hash に変更して、python3 main.pyを実行すれば、moments.json をエクスポートできます。

スクリプトについて特に説明が必要なのは:

  1. スクリプト内で dl_img というパラメータを設定しました。True の場合、すべての画像をローカルにダウンロードします。結局、WeChat アカウントはすでに禁止されているので、友達のサークルの画像がいつホストされるかわからないし、頻繁に外部から友達のサークルの画像にアクセスするのはどうなるかわからないので、ダウンロードできるうちにすべての画像をローカルにダウンロードすることをお勧めします。

  2. 共有リンクタイプの moment については、共有されたリンク自体だけでなく、WeChat がこのリンクにキャッシュした画像 / タイトル / 説明も解析し、友達のサークルがリンクをどのようにレンダリングするかを完全に再現しました。こうする理由は、以前に共有された多くのリンクがすでに 404 になっているからです…… リンクだけを解析してもあまり意味がないと思うので、当時キャッシュされたデータをすべて解析する必要があると思います。少なくとも「表紙」を再現するために。

もちろん、このリポジトリのスクリプトがこのように書かれている背景には多くの分析があります。皆さんは興味に応じて、次の部分を飛ばすかどうか選択できます。

まず、WeChat は SQLlite キャッシュを使用しているので、wc005_008.db というデータベースを分析したい場合は、このオープンソースのsqlite browserを使用できます。簡単な分析を経て、db 内には大量のMyWC01_で始まるテーブルがあり、自分のアカウントの友達のサークルデータはMyWC01_{$hash}というテーブルに存在します。$hash は先ほどのディレクトリの hash であり、この hash は自分のアカウントの何らかの ID を表していると思われます。他のMyWC01_...は友達の友達のサークルデータを表していると推測されます。

自分の友達のサークルデータを保存するテーブルに入ると、非常に重要な二つのフィールドBufferidがあることがわかります。Buffer フィールドを utf-8 方式でデコードすると、多くの明文フィールドが見えます。中には画像の URL、友達の名前、以前に投稿した友達のサークルの内容があります。これにより、Buffer フィールドから友達のサークルデータを復元できることが推測されます。

ここで少し主題から外れて、「Buffer フィールドを utf-8 方式でデコードする」ということについて話します。このsqlite browserでは、バイナリファイルを utf8 方式でデコードして直接読む方法が見当たらなかったので、最終的にはこのテーブルのすべての Buffer フィールドをファイルに書き込み、hex viewer/editor を使用して読み取り分析することにしました。しかし、これも順調ではありませんでした。多くの hex viewer/editor を探しましたが、utf8 のデコード方式をサポートしているものはありませんでした。最終的に、私が見つけた唯一の utf8 解析をサポートするソフトウェアはSynalyze It!で、このソフトウェアは無料試用が 2 週間のみで、その後は 9.99 ドルの支払いが必要です。もっと良い方法があれば、皆さんと交流できればと思います。

主題に戻りますが、Buffer フィールドを分析し続けると、これらのデータの形式を完全に理解するのは難しいことがわかりますが、それでも固定の識別子に基づいて内容を識別することができます。典型的なペイロードはおおよそ以下のようになります:

payload

異なるフィールドにはそれぞれ対応する識別フラグがあります。画像 / 内容 / 共有リンクなど、これらのフィールドは Buffer 内での形式は基本的に最初にフラグが現れ、その後に 1〜2 バイトのメッセージの長さを示すものが続き、その後にメッセージ自体が続きます。

本文内容の例として、以下の図は二つの友達のサークル内容のバイナリファイルです。観察すると、b'\xba\x01'が本文内容の識別子であることが簡単にわかります。
flag

これで基本的な考え方は明確になりました。まず、どのフィールドを解析する必要があるかを確認し(最終的に解析が必要なフィールドは本文内容、画像リンク、共有リンク、共有リンクからレンダリングされた画像、共有リンクからレンダリングされたタイトル、共有リンクからレンダリングされた説明です)、次に解析するフィールドのフラグを識別し、最後にメッセージの長さとオフセットを解析する方法を考えればよいのです。

しかし、最後のピースが欠けています —— 公開時間です。直感的には、テーブル内の別のフィールドidが時間に非常に関連していると思います。なぜなら、これらの数字は実際の時間と共に増加するからです。これは時間スタンプに基づくアルゴリズムの一種であると推測されます。この部分については、@kaiiの助けに非常に感謝しています。最終的に、実際の create_time と id の変換アルゴリズムは以下のようにほぼ確定しました。

create_time = id / 8388607990

この公式のマジックナンバー 8388607990 は MyWC_Message01 から推測されました。これはコメントを保存するテーブルで、正確な公開時間はわかりませんが、このテーブルの create time フィールドからコメントの実際の公開時間がわかります。このテーブルの別のフィールド id は元の投稿の id に対応しているはずです。

私たちは簡略化して、各投稿の最初の返信の create time と id の関係が元の投稿と id の関係であると考えることができます。なぜなら、最初の返信の時間が元の投稿の実際の公開時間に最も近いからです。したがって、テーブル内の最大の Id/CreateTime をマジック係数として取ることができます。

SELECT MAX(ID/CreateTime) FROM MyWC_Message01

実際には、コメントから得られたマジック係数はわずかに小さかったため、より正確にするために、最後に自分の友達のサークルデータをいくつかサンプリングし、WeChat アプリのフロントエンドに表示される公開時間と照らし合わせて微調整を行い、最終的に 8388607990 という数字を得ました。この公式は、実際の公開時間との誤差が 1 分以内であることを保証できます。

要するに、概念はこのようなものです。もちろん、具体的には多くの詳細がありますので、興味があれば直接コードの実装を参考にしてください。

(踏んだ落とし穴:最初はこのリポジトリのコードを多く参考にしましたが、このリポジトリのコードは plist 形式で Buffer を解析しており、実際には現在のバージョンのキャッシュが何の形式かはわかりませんが、いずれにせよ plist 形式ではありません)

4. データの表示とブロックチェーンへの永続化#

データがすでにエクスポートされたので、実際には何をしても構いません。私はデータをブロックチェーンに保存することが非常にロマンチックな記録方法だと思うので、友達のサークルを Crossbell チェーンにバックアップし、再度 xFeed に表示することにしました。

ブロックチェーン機能を実現し、自分のデータが正常にエクスポートされているかを確認するために、リポジトリにはエクスポートスクリプトの他に、簡単な表示ページも作成しました。最終的な効果はおおよそ以下のようになります:

image

データのエクスポートに問題がなければ、ページ上で「ブロックチェーンに保存」をクリックし、手順に従って進むことができます。しかし、ブロックチェーンとスムーズにやり取りするためには、いくつかの準備が必要です:

  1. Metamask ウォレットプラグインをダウンロードします。
  2. 水道でインタラクションに必要なガスを受け取ります。データが多すぎる場合、必要なガスの量が多くなる可能性があります。もっとガスが必要な場合は、私に連絡してください。

この二つの準備が整ったら、ページ上で直接ブロックチェーンに保存できます。

結論#

WeChat のバージョンは常に更新されており、キャッシュの構造も変化し続けています。本記事の内容は完全に一般的ではなく、すべての状況をカバーすることはできませんが、この記事が参考になり、皆さんに何らかのインスピレーションを提供できればと思います。他に発見があれば、ぜひ交流しましょう。

最後に、この記事で言及された二つのリポジトリを再度列挙します:

また、友達のサークルをエクスポートするだけでなく、QQ スペースの発言をエクスポートするためのユーザースクリプトも書きました(はい、私の QQ も一緒に禁止されました)。QQ スペースのエクスポートははるかに簡単で、内容はすでにこちらにエクスポートされていますが、まだコードを整理していないので、後で簡単なチュートリアルも書くつもりです。

参考#

先人の木に感謝します:

https://zhuanlan.zhihu.com/p/22474033

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。