dwgx@blog:~$dwgx
> cd ../posts

Launch: C++/DX11/ImGui で書いたプロセスメモリエディタ

// created

Launch は Windows のプロセスメモリのビューア/エディタだ。DX11 でウィンドウを支え、ImGui で UI を描く。要するにミニマル版の Cheat Engine で、PID を渡してアタッチし、テーブルにアドレスを書き込み、値をリアルタイムで眺め、書き戻すこともできる。

これを書いたのは、Win32 でのプロセスメモリまわりをきちんと把握したかったからだ。ReadProcessMemory / WriteProcessMemory はドキュメントを眺めているだけでは感覚がつかめず、自分で一つ組んでみて初めて腑に落ちた。ついでに C++ / CMake / ImGui のデスクトップ開発の流れも一通りたどれた。製品にするつもりはなく、あくまで練習で、プロセスにアタッチできてゲームの HP を書き換えられれば十分だった。

管理者として起動するのは必須条件だ。アタッチには PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION が必要で、昇格しないとほとんどのプロセスはそもそも開けない。UI はテーブル一枚だけで、1 行につき 1 アドレス、Enter で行を追加する。アドレスは 3 つの書き方に対応している:

  • 絶対アドレス 0x605FFDA00
  • モジュール+オフセット th12.exe+0xB0C44、まずモジュールのベースアドレスを調べてからオフセットを足す
  • 多段ポインタチェーン th12.exe+0xB0C44->0x10->0x20、ReadProcessMemory を一段ずつたどって最終アドレスを解決する

ポインタチェーンは Cheat Engine の考え方に倣った。ゲーム内で安定したアドレスはたいていポインタの奥に隠れていて、絶対アドレスをベタ書きすると次にゲームを起動したときには使えなくなる。

技術スタックは C++20、GUI は Dear ImGui でソースをそのまま include/ に vendor しており、レンダリングは DX11 + Win32 を通す。CMake と VS の両方でビルドできる。中国語フォントは msyh → simsun → meiryo の順で探し、どれも無ければデフォルトにフォールバックする。UI が豆腐(□)だらけにならないようにするためだ。

機能はあえて最小限に抑えた。int の読み書きのみ、アタッチは一度に 1 プロセス、メモリスキャンや他の値の型、ポインタの自動スキャンは実装していない。一番印象に残ったハマりどころは大文字小文字だ。リポジトリは実際には src/Gui なのに CMake では src/GUI と書いており、大文字小文字を区別するシステムではどうしてもビルドが通らなかった。原因に気づくまでずいぶんかかった。コードには直せる箇所が山ほどあるが、ちゃんとしたツールに書き直すつもりはない。C++ を始めたばかりの頃の姿として残しておく。