3 ポイント 投稿者 GN⁺ 2024-03-31 | 1件のコメント | WhatsAppで共有
  • rev.ngはデコンパイラバックエンド revng-c を公開し、デコンパイルエンジンをオープンソース化するとともに、UIのクローズドベータ・新Webサイト・rev.ng Hub・ドキュメントをあわせて公開
  • ローカルではインストールスクリプトでCLIを構成した後、revng artifactrevng ptml を使って 有効なCコード 形式のデコンパイル結果を確認できる
  • インタラクティブUIは VSCodeベース で、ブラウザ版とスタンドアロンアプリの両方を目指しており、ニュースレター購読者をFIFO方式で招待するクローズドベータで提供される
  • 自動データ構造復元、協調リバースエンジニアリング、多様なアーキテクチャ対応、拡張性が中核目標だが、現在のQAは Linux x86-64バイナリ に最も注力している
  • フレームワークとCLIはオープンソースで、クラウドUIは公開プロジェクトに無料提供され、非公開プロジェクト・オフラインのスタンドアロンUIは有料モデルとして区分される

オープンソース化とクローズドベータ

  • rev.ngはデコンパイラバックエンド revng-c をオープンソースとして公開
    • これにより、デコンパイルエンジン全体が オープンソース になった
    • 初期の ドキュメント もあわせて提供されている
  • UIはニュースレター購読者向けに クローズドベータ 招待を開始予定
  • 新Webサイトと rev.ng Hub も同時に公開
    • rev.ng Hubはクラウド版への入口
    • ベータユーザーはプロジェクトを作成し、ブラウザでUIを実行し、他のユーザーと協業できる
    • クローズドベータ対象でなくても 公開プロジェクト は閲覧できる
  • rev.ngの機能を直接確認したいユーザー向けに 非公開デモ も実施

CLIでrev.ngを試す

  • revng はroot権限なしで単一ディレクトリにインストールでき、そのディレクトリを削除すればアンインストールできる
curl -L -s https://rev.ng/downloads/revng-distributable/master/install.sh | bash
cd revng
source ./environment
  • サンプル example.cargc * 3 を返すシンプルなプログラム
int main(int argc, char *argv[]) {
  return argc * 3;
}
  • gcc でコンパイルした後に revng artifact を実行すると、単一ファイル 形式のデコンパイル結果を取得できる
gcc example.c -o example -O2
revng artifact \
        --analyze \
        --progress \
        decompile-to-single-file \
        example \
        | revng ptml --color \
        | grep -A2 -B1 '[^_]main\b' \
        > decompiled.c

ベータの範囲とテスト対象

  • UIを利用するには ニュースレター に登録する必要があり、招待は少人数のバッチで進められる
  • 今回のリリースは、UIとデコンパイル結果を一部のバイナリでデモし、実際のバイナリ作業に関するフィードバックやバグレポートを受け取ることに重点を置く
  • テストに使用した複雑なバイナリと .text サイズは以下の通り
  • rev.ngは複数のABIとプラットフォームをサポートするが、この段階での初期QAは Linux x86-64バイナリ に集中している
  • 問題が発生した場合は Discourse で支援を受けられる

rev.ngが目指すデコンパイル体験

  • rev.ngの主な注力点は、自動データ構造復元、モダンなUX、協調リバースエンジニアリング、幅広いプラットフォーム対応、拡張性
  • 自動データ構造復元

    • Data Layout Analysisにより、struct レイアウトを プロシージャ間解析 を通じて自動復元できる
    • 連結リストノードの例では、int64_t data[5] 配列と次ノードへのポインタを持つ構造体を対象とする
    • rev.ngの出力は、配列サイズ5と次要素ポインタへのアクセスを自動検出した構造体と関数コードを生成する
    • デコンパイラ出力は構文的に有効なCコード
    • この機能は現在利用可能
  • VSCodeベースのインタラクティブUI

    • UIは VSCodeベース で、VSCodeユーザーは馴染みある形で利用できる
    • ブラウザタブとスタンドアロンアプリケーションの両方で動作可能
    • 主なショートカットは以下の通り
      • Ctrl + Click: カーソル下の関数または型定義へ移動
      • N: 名前変更
      • Y: 型編集
      • X: 参照を表示
    • rev.ngは変更があると影響を受ける部分だけを再計算する インタラクティブデコンパイラ
    • UIは現在クローズドベータ参加者に提供されている
  • 協調リバースエンジニアリング

    • rev.ng UIはクライアント・サーバーアーキテクチャを採用
    • 複数ユーザーが同じデーモンインスタンスに接続し、同じプロジェクトで同時に作業できる
    • クラウド版では、プロジェクト管理のためのGitHubライクなアプリケーション rev.ng Hub を利用できる
    • 協業機能は動作しているが、ユーザー体験の改善が必要で、ロードマップ項目 #797 で追跡されている

アーキテクチャとプラットフォーム対応方式

  • rev.ngはQEMUパイプラインの前段を使って実行コードを tiny code にリフトし、それをLLVM IRへ変換した後にデコンパイルを行う
  • この構造により、QEMUが対応するアーキテクチャ を比較的容易にサポートできる
  • アーキテクチャ対応と同じくらい、プラットフォーム、特にABI対応も重要
    • rev.ngはABIの属性を宣言的に記述するために ABI description format を使用する
    • この形式は、新しいABI対応を容易に追加できるほど汎用的に設計されている
  • 現在の対応状況は以下の通り
    • アーキテクチャ: x86、x86-64、ARM、AArch64、MIPS、s390xを異なる成熟度でサポート
    • バイナリ形式: ELF、PE/COFF、Mach-Oに対応
    • インポート: .idb、DWARFデバッグ情報、PDBデバッグ情報に対応
  • QAの大半はLinux x86-64バイナリで実施されており、その他は追加QAが必要
  • より多くのプラットフォームQAは ロードマップ項目 #58 で追跡されている

拡張性とスクリプティング

  • rev.ngはリバースエンジニアリングツール向けのフレームワークを目指しており、インタラクティブUIを除くプロジェクト全体がオープンソース
  • プロジェクトファイルである model はYAML文書のため、JSONまたはYAMLを解析できればrev.ngをスクリプトから扱える
  • modelには、デコンパイル対象バイナリのアーキテクチャ、デフォルトABI、セグメント、関数一覧、型一覧などが含まれる
  • PythonおよびTypeScript向けラッパーでmodelを編集できる
    • 現時点ではmodel操作用ラッパーはあるが、解析実行やアーティファクト取得を簡単に行う仕組みはまだない
    • 完全なPythonクライアントは ロードマップ項目 #17 で追跡されている
  • 内部表現ではLLVM IRが多用されており、LLVMエコシステムのツールを活用できる

オープンソースCLIと有料UIの切り分け

  • rev.ngフレームワークは完全にオープンソースで、CLIから任意の対象をデコンパイルできる
  • UIの提供形態は3つに分かれる
    • 公開プロジェクト向けクラウドUIは無料で利用可能
    • 非公開プロジェクト向けクラウドUIは購読が必要
    • 完全スタンドアロン・完全オフラインUIは有料で提供
  • クラウド利用方法は以下の通り
    • rev.ng Hub でプロジェクトを作成し、共同作業者を招待する
    • UIはブラウザで実行される
    • バックエンドはrev.ngクラウド上で動作する
  • プロジェクトファイルを公開しても問題なければ、UIを含むクラウド版rev.ngを無料で利用できる
  • Kubernetesを使うオンプレミスのプライベートクラウドサービス導入についても相談可能

1.0ロードマップと連絡チャネル

  • 1.0までのロードマップは4つのティアに分かれる
    • Tier 1: アルファ版、知人向けデモ、完了
    • Tier 2: ベータ版、ニュースレター購読者にクラウド版アクセスを提供、現在開始
    • Tier 3: オープンベータ、予定
    • Tier 4: 1.0リリース、予定
  • 詳細な進捗状況は ロードマップページ で確認できる
  • プロジェクト情報とサポートチャネルは以下の通り
    • X/Twitter: 開発情報と主要発表
    • Discord: 開発チームとのリアルタイム会話
    • Discourse: ユーザーサポートとバグレポート
    • GitHub: オープンソース開発とIssue登録
    • Monthly newsletter: クローズドベータ参加と月次情報
    • E-mail: 非公開での問い合わせ

1件のコメント

 
GN⁺ 2024-03-31
Hacker News の意見
  • 価格モデルは、rev.ng フレームワークが完全にオープンソースで、CLI では何でもデコンパイルできるという構成
    UI は公開プロジェクトならクラウド上で無料、非公開プロジェクトではクラウドサブスクリプション、完全に独立したオフラインアプリは有料で提供される予定
    比較すると、Hopper は1年間のアップデート込みで100ドル https://www.hopperapp.com/index.html、Ghidra と Radare2 はフリーかつオープンソースなので完全無料、IDA Pro は非常に高価

    • Binary Ninjaも良い選択肢
      使ってみた限りでは IDA とかなり似ているが、よりユーザーフレンドリーで、生産性を高めるよく設計された機能が多かった
      Hopper は使ったことがないが、Ghidra と Radare2 は開発体験があまり良くなく、生成された C コードも読みやすくなかった。ただし、どちらも数年前に使った時点での話
      Binja は300ドル、商用は1500ドルで、学生割引もある: https://binary.ninja/features
    • デコンパイルは、IDA/Ghidra の中で最も重要度が低く、信頼性も低い部分であることが多いので、両者を単純に比較するのは不公平
      それでも良い C デコンパイラは常に不足しているので、新しい試みはいつでも歓迎
    • 買い切りと決められたアップデート期間というライセンスモデルは本当に好き
      ただ、アプリにインターネット接続を必須にせず、それをどう強制するのかは気になる
  • チームページ https://rev.ng/about とコード貢献 https://github.com/revng/revng/graphs/contributors を見ると、CEO(aleclearmind) が CTO(pfez) よりもはるかに多くのコミットを持っているのが少し珍しく見える
    他の CEO はコーディングする時間がほとんどないとよく言うし、CTO もたいていはマネジメント寄りで、実際のコーディングは少なめ
    それでもこのやり方がうまく回っているなら、チームとしてはかなり面白そう。追記: タイムラインは確認していなかった

    • CTO は主に、たった今公開したデコンパイラバックエンド revng-c で作業している: https://github.com/revng/revng-c/commits/develop/
      最終的には2つのリポジトリを統合する予定
      それに私は毎日開発しているのだが、どういうわけか GitHub が私のユーザーを正しく拾えていない
      実際にも楽しい
    • CTO のほうが最近のコミットは多く、aleclearmind のコミットは2020年以降0になっているので、そちらもコーディング時間を作るのが難しくなったように見える
    • 批判するつもりは全くなかったのに、なぜダウンボートされたのか少し気になる
      むしろこういう姿は気に入ったし、他で見たものと違っていて興味深かった
      面白くない、または珍しくないという理由でダウンボートされたのだろうか?
  • 現存する最高のプログラミング言語理論の本の1つから力を得た、素晴らしい会社に見える: https://link.springer.com/book/10.1007/978-3-662-03811-6
    「彼は共犯者となる Pietro にも出会った。かなりロマンチックなことに、会社の土台となる本のおかげで彼に出会った。」
    https://rev.ng/about

    • その本にまつわる全体の話はこうだ。コンパイラを学び始めたものの、理論が難しすぎ、有名な本も自分には合わず、かなり落ち込んでいた
      そんな時、凝縮されているが明快に見えるこの本を見つけ、指導教員に買ってよいか尋ねたところ、「まず大学図書館を確認しなさい」と言われた
      図書館には所蔵があったがすでに貸出中で、コンパイラ研究をしている唯一のグループにいた私は「うちのグループ以外で、いったい誰がコンパイラなんてやっているんだ?」と思った
      図書館へ行って誰が借りたのか尋ねたが、個人情報なので教えられないと言われ、姓の3文字目と名の2文字目だけを聞いて Z と I を引き出した
      ここで見つけ出した: https://www.deib.polimi.it/ita/personale-lista-alfabetica
      時が経って友人になり、一緒に会社を始めた
      リリースまでには本当に多くの作業が必要だった
  • コードが変数や構造体メンバーをどう扱っているかに基づいて、変数名と構造体メンバー名を自動で付けられるとよい
    たとえば連結リストの next ポインタは next として識別しやすいはず
    GitHub 全体をダウンロードして、コード内でレイアウトと相互作用が最も似ている変数を探し、信頼度が十分に高ければその名前を使う、という方法が可能に見える

    • 以前はこういうことを手作業でやろうとした
      たとえば誘導変数を検出したら i にリネームする、という具合
      だが今では、こうしたことの正しいやり方は LLM を使うことだとかなり明確に見える
      ただ現段階では、私たちは堅牢な基盤を作る側に近く、基盤が整えば既製のモデルで名前を変えたりコメントを追加したりするのは比較的簡単
      要点は、100% の正確性が必要な難しいデコンパイル作業は私たちが行い、名前やコメントのように近似が許される部分には LLM を導入できるということ
      いずれにせよ、リネーム用スクリプトを書くのはかなり簡単なので、ドキュメントを見るとよい: https://docs.rev.ng/user-manual/model-tutorial/
    • 本当にかっこよさそうで、http://jsnice.org/ のような感じ
      JSNice が内部で何をしているかを説明する論文: https://files.sri.inf.ethz.ch/website/papers/jsnice15.pdf
    • Binary Ninja の sidekick に似ているように聞こえる
    • リバースエンジニアリング向けの GitHub Copilot みたいなもの?
  • 自分の ELF ファイルでは動作しない
    ./revng artifact --analyze --progress decompile-to-single-file ../maytag.ko を実行すると Only ELF executables and ELF dynamic libraries are supported と表示され、ファイルは ELF 64-bit LSB relocatable, x86-64, version 1 (FreeBSD), not stripped と出る
    FreeBSD バイナリをサポートしていないということ?
    追記: カーネルモジュールをサポートしていないことを見落としていて、FreeBSD のせいというより単純な実行ファイルではないからのようだ

    • GitHub に Issue を立てて、バイナリを添付してもらえる?
      これをロードするのはそれほど難しくなさそう
  • コラボレーションワークフローにもっと注目が集まるといい
    IDA Teams のようなものは使ったことがないが、Google Docs のように摩擦のないリバースエンジニアリング体験が実現できたらすごいと思う

    • それが私たちの目標
      以前は UI ベースで QtCreator を使っていたが、ひどい選択だった
      その後 VSCode に切り替えたところ、ちょうどブラウザでも実行できた
      そこで Kubernetes を少し組み合わせて、完全スタンドアロン版とまったく同じユーザー体験を持つ クラウドデコンパイラを作った
      コラボレーション部分はまだ QA がもう少し必要だが、基本的には動作している
      デーモン 1 つに複数クライアントという非常に単純な構成
      以前 CTF で、サーバー上の X セッションに IDA のウィンドウを複数開き、カーソルも複数ある状態で「共同作業」していた経験から着想を得たのだと思う。非常に呪われたやり方だったが、効果はあった
  • 型推論をサポートする予定はある?
    現状ではすべての変数が generic64_t に見えるようだが、Ghidra のように型を自動検出してくれるとよさそう。もちろん Ghidra も時々間違えるが

  • 面白そう
    完全スタンドアロン版を試してみたい
    おおよその価格について何か情報はある? 趣味ユーザーでも手が届く程度だとうれしい

  • バイナリハッキングツールが増えるのはいつでも歓迎
    自分でも試してみたいと思うかもしれないので、選ばれたパッケージ形式についてかなり細かい提案を残しておく
    source ./environment は良くない兆候。tar を取得してみると、実際に PATH を含む複数の環境変数を設定しており、幸い LD_LIBRARY_PATH ではなかった
    ほとんどが HARD_ プレフィックスで、おそらく固有だろうが、REVNG のほうが明確に見えるし、既存の環境変数と衝突するのは良くない
    AWS_EC2_METADATA_DISABLED="true" も設定しているが、自分は AWS を使っていないので壊れはしないものの、一般的には疑わしい
    RPATH_PLACEHOLDERHARD_FLAGS_CXX_CLANG、長い PATH、mingw32/gentoo/mips 文字列などは脆弱に見える
    実行手順に「次に環境変数を変更せよ」とあると、たいていは諦める。Ubuntu 以外のシステムでまともに動かないプログラムと強く相関している
    アプリケーションの制御フローを実行環境に結び付けると、最初に見える以上に失敗モードが多く、グローバル変数に非常によく似ている
    Clang はビルド時に -DCLANG_DEFAULT_CXX_STDLIB=libc++ のようなデフォルト値を焼き込めるし、DEFAULT_SYSROOT も有用
    rpath を使っていても、ユーザーが LD_LIBRARY_PATH を設定した状態で実行すると、バイナリの DT_RUNPATH が上書きされることがある
    最近の -Wl,rpath は実際には rpath ではなく、あまり有用でない runpath を意味する。おそらく望ましい呼び出しは -Wl,rpath -Wl,--disable-new-dtags で、ローダーがライブラリ探索時に LD_LIBRARY_PATH を無視するようにするものだ
    Clang のビルドフラグ、静的リンク、バイナリ内へのバイナリ埋め込みなどを組み合わせれば、環境変数の操作を完全になくせる可能性が高い
    clang-16 バイナリが動的リンクされていて、実行時に libLLVMAArch64CodeGen.so.16 のようなものを探すのも失敗モードを増やす
    LLVM_BUILD_STATIC=ON なら、HPC モジュールのツールチェーンが有効な環境で間違ったライブラリを拾う問題を減らせる
    ツール群は libc++.solibc++abi.so などにリンクされているが、静的 libc++ を検討する価値があり、少なくとも libc++abilibunwind は libc++ の中へ静的にリンクしたほうがよい
    Linux で動的リンクされたプログラムを配布することへの忍耐が完全に尽きた
    README の source ourhack やモジュールシステムが残した環境変数が自分のアプリケーションのランタイムライブラリを変えてしまうと、ユーザー体験とその後のバグ報告対応コストがひどいことになる
    それに比べて静的リンクは本当に良い

    • 環境をいじることへの懸念の大半は、実際に source environment をするという前提でのみ当てはまる
      実のところ、それを提案した理由はデモ用バイナリ向けに、われわれが配布している GCC を使わせるためだけで、意図された使い方は ./revng スクリプト
      この場合、環境の変更は revng の呼び出しにだけ影響する
      ドキュメントはこちら: https://docs.rev.ng/user-manual/working-environment/
      source ./environment について警告を追加したほうがよさそう
      LD_LIBRARY_PATH は使わないように多くの時間を費やし、各 ELF が相対パスで依存関係を参照する完全に自己完結したバイナリセットを作った。LD_LIBRARY_PATH は悪
      HARD_ 変数はコンパイララッパーでのみ使われ、実際に衝突する可能性はほぼないと思う
      AWS_EC2_METADATA_DISABLED="true" の元の議論は https://github.com/revng/revng/pull/309#discussion_r12805759... にある
      AWS SDK にパッチを当てて避けることもできるだろうが、いずれにせよ rev.ng がクラウド上で実行されるときにだけ影響がある
      RPATH_PLACEHOLDERHARD_FLAGS_CXX_CLANG は revng が変換したバイナリをリンクするときに使われ、エンドツーエンドのバイナリ変換に関心がないなら重要ではない
      われわれは意図的に DT_RUNPATH を望んでいる。DT_RPATH は廃止予定であり、LD_LIBRARY_PATH でわれわれのライブラリを置き換える必要があるユースケースもあり得る
      「環境操作」についての指摘は、非公開の環境変数でない場合にだけ妥当だと思う
      RPATH_PLACEHOLDERHARD_*REVNG_* は非公開変数で、すべてバイナリ変換目的
      より小さい範囲のコンパイララッパー内へ押し込むことはできるが、Python も一緒に配布しているため、環境を完全になくすことはできない
      Clang に一部のフラグを焼き込むだけでは不十分。このフラグ群はリンカにも影響し、ラッパー機能の中には単純に内蔵できないものがある
      ただし、より非公開な場所へ移すことはできる
      動的リンクを警戒しているようだが、われわれはここに労力をかけており、今ではかなりうまく動作し、常に正しい場所を見つける
      絶対パスをハードコードせず、バイナリを「パッチ」するインストール手順もない。展開したディレクトリはどこへでも移動できる
      われわれの解決策は LD_LIBRARY_PATH を使わず、すべてのバイナリが $ORIGIN を通じて堅牢に互いを参照するというもの
      ./root/bin/python ./root/bin/revng artifact --help を実行してみると動作する
      繰り返すが、source environment はほぼデモ用であり、実際の使用では ./revng だけ実行すれば環境はそのまま
      Python も一緒に配布しているが、必ずそれを使う必要はない。./revng を使うか、デーモンモードでネットワーク経由で相互作用すればよい
      アプローチとしては、好きなスクリプトツールで YAML プロジェクトファイルをパース・修正してから ./revng artifact を呼び出すか、デーモンと相互作用する: https://docs.rev.ng/user-manual/model-tutorial/
      結果として、われわれは最新の Python バージョンを使え、ユーザーは好きな言語を使える

今後は、さまざまな Python バージョンと互換性のある補助ラッパーを PyPI で提供する予定です
要するに、source ./environment はせずに ./revng を使えばよいということです
こうした点を気にかけてくれる人がいてうれしいです
次の大きなイテレーションでは、nix + mount namespace を導入して、root 権限なしで /nix/store を使えるようにし、多くのことを単純化できるかもしれません
こうした議論は、ここよりも Discord サーバーで話したほうがよいかもしれません

  • おめでとう
    QEMU TCGにリフティングを任せたことについて後悔はある? それとも、うまく機能した?
    • とてもよく機能した。後悔は2つある
      まず、QEMUのフォークを数年間リベースしていなかったため、よくない状況になっていた
      それでも、まさに今日チームメンバーが最新のQEMUでリフティングに成功し、私たちがQEMUへのサポート追加を手伝ったQualcomm Hexagonのコードもリフティングできた
      結果的に、私たちは初のまともなHexagonデコンパイラになるはず
      次に、QEMUに集中しすぎたせいで、フロントエンドがQEMUと強く結合してしまった
      今後、QEMUベースではない追加のフロントエンドをサポートするには多少の作業が必要だが、不可能ではない
      構想としては、ユーザーが新しいアーキテクチャのサポートを追加するときに、CでCPU状態構造体と、その上で動作する関数をいくつか定義するだけで済むようにすること
      内部表現を学ぶ必要はない
      要するに、QEMUは素晴らしい選択で、あまりにもうまく動いたため、そのコードベース部分に長く手を入れず、技術的負債が生まれたが、今まさに解消しているところ