世界を動かす技術を、日本語で。

デヌーボ分析

概要

  • 本記事は Denuvo の最新技術に関する 教育目的 の解説
  • 個人メモ やリバースエンジニアとのやり取りを含む
  • Denuvoの 仕組み と保護メカニズムを詳細に説明
  • 一部 機密情報 は伏せ字処理
  • Irdeto社 への悪意は一切なし

Denuvoとは

  • Denuvo はデジタル著作権管理( DRM)および アンチタンパー 技術
  • 主に ゲーム などのデジタルメディアの 不正コピー防止リバースエンジニアリング対策 に利用
  • 従来型DRMと異なり、多様な 検証手法チェック機構 を搭載
  • ゲームコードやユーザーの正当性を 多重確認 する設計

Denuvoの基本的な仕組み

  • Denuvoは セミオンライン型DRM として機能
  • 初回起動時、 ハードウェアID を収集しサーバーへ送信
  • サーバー側で「 盗難定数」とハードウェア情報を 可逆的演算 で混合
  • サーバーから返される「 ライセンスファイル」をローカル保存
  • 以降はオフラインでも ライセンスファイル を参照し起動可能
  • 毎回起動時にハードウェア情報を再収集し、 定数の復号 や整合性チェックを実施
  • ハードウェア情報が一致しない場合、 ゲームがクラッシュ する等の不具合発生

技術的詳細

  • Denuvo導入時、特定の関数が「 保護対象」として選定
  • 保護対象関数は 仮想マシン(VM) 上で実行され、一部命令バイトがバイナリから削除
  • 削除された命令バイト群+ハードウェアIDを 可逆演算 で混合し、サーバー保管
  • ライセンスファイルは、 削除命令バイト とハードウェアIDの混合体
  • 各命令は「 License DWORD」としてVMセクション内に分散保存
  • 実行時、VMはハードウェア情報を再収集し、License DWORDを 復号
  • 復号値が正しければ元の命令を実行、不一致なら 異常動作

命令削除例

  • 例:mov DWORD PTR [rbp-4], edi の「-4」をバイナリから削除、サーバーで管理
  • ライセンスファイルがなければ、 関数が正しく動作しない
  • 関数全体を 独自バイトコード 化し、VMでのみ解釈可能
  • VM内で、削除命令の 復号ラッパー が動作し、正当性確認

ユーザー正当性チェック

  • Denuvoは複数の 整合性検証 ベクトルを実装
  • ライセンスファイル要求時、各種チェック結果をサーバー送信

Pre-OEPチェック

  • ハードウェア構成変更時(例:Windows Update、CPU交換)にも対応
  • OEP(Original Entry Point)直前に 定数復号テスト を実施
  • 期待値と異なればローカルライセンスを削除し、再取得を要求

主要なハードウェア情報収集手法

  • KUSER_SHARED_DATA :Windowsバージョン、ビルド番号、物理メモリ数など
  • CPUID命令 :プロセッサ情報やブランド文字列取得
  • SYSCALL命令 :NtQuerySystemInformation呼び出し
  • ntdll.dll検査 :特定関数のバイト列やImage Data Directoryを参照
  • PEB(Process Environment Block) :OSバージョンやサブシステム情報
  • XGETBV命令 :CPUの拡張制御レジスタ情報取得
  • GetWindowsDirectoryW :Windowsディレクトリパス取得
  • GetVolumeInformationW :ボリューム情報取得
  • GetComputerNameW :コンピュータ名取得
  • GetUsernameW :実行ユーザー名取得

コード整合性チェック

  • CRC(Cyclic Redundancy Check) によるVMハンドラや重要コードの改変検出
  • .VMセクション からランダムにバイト列を抽出し、定数生成・検証
  • 例:VMハンドラ内で「ランダム」なワードを読み込み、暗号化・復号処理で整合性維持

Denuvoの設計思想と特徴

  • 多層的保護 :ハードウェア・ソフトウェア双方からユーザー正当性を検証
  • 仮想化 :重要処理をVM化し、逆解析を困難化
  • 可逆暗号 :サーバーとクライアント間で定数を安全にやり取り
  • 動的検証 :実行時ごとにハードウェア情報を再確認し、不正利用を即座に検知

まとめ

  • Denuvoは 最先端のDRM技術 を駆使し、 不正利用防止 を徹底
  • 多様な ハードウェア情報収集コード整合性検証 を組み合わせた高度な保護構造
  • 一部情報は 公開されていない独自技術 を含むため、詳細は割愛
  • 本記事は 教育・研究目的 の情報共有

Hackerたちの意見

高校生の頃からゲームを海賊版でやってないけど、今の状況のおかげで、金払って買ったゲームのUXが最悪になってる。こっちにはどうしようもないしね。Cloudflareみたいなもんかな。誰かがちゃんと行動しないせいで、他の人が苦しむっていう。

子供の頃からゲームを海賊版でやってないけど、Linuxを使ってるし、デスクトップでもROG Ally(Bazzite)でもLinuxでゲームしてる。ゲームを買うときの体験は、DRM付きのゲームは買わないか、動くかもしれないゲームを買って、正しいProtonのバージョンを探すのにちょっと時間がかかるって感じ。機械の識別子を頻繁に変えたりすると、一時的に禁止されたりもするし。本当に、払ってる人より払ってない人の方が、ゲームや音楽、動画の体験がずっといいっていうのは、まるで悪い冗談みたいだよ。

「誰かがちゃんと行動しないせいで、他の人が苦しむ」これは自己成就的だね。Denuvo付きのゲームが出ると、ちゃんと行動しない人もいるから。

Denuvoが原因で体験のどの部分が悪くなるの? Denuvo付きのゲームを持ってたけど、Denuvoが外れた後、少なくとも私の限られた経験では、特に違いは感じなかったよ。DRM全般に対する反論や、買ったものを所有することの重要性は理解できるけど、それは別の問題のように思う。

もし役に立つなら、Denuvoで保護されたゲームをマークするSteamのキュレーターがあるよ。購入前にその事実をもっと目立たせるためにね。https://store.steampowered.com/curator/26095454-Denuvo-Watch...

記事で触れられてないのは、なぜUD2が選ばれたのかってこと。これはSecuROM時代の遺物で、実際、SecuROMの開発者の一人がDenuvoでも働いているか、働いていたんだろうね。SecuROM時代のものがDenuvoに残っていると思うけど、記事を読むと、Denuvoのせいで将来的に特定のゲームが動かなくなることに気づくよ。「これにより、例外ベースのフックが破壊される。大抵の場合、例外がトリガーされると、Windowsは未使用のスタックスペースの高い位置にEXCEPTION_RECORDを書き込む。これがどうなるかは分かると思う。今や、CPUIDが例外を通じてフックされると、その重要な値がEXCEPTION_RECORDで上書きされて、後で未定義の動作を引き起こす。デバッガをプロセスにアタッチして、例外処理に関する特定のフラグを設定すれば回避できると思うけど、ハードウェアチェックをすべてパッチする方法は、ランダム性のせいで面倒だよ。」Windowsが成熟するにつれて、動作が変わって特定のものが壊れることもある。

Windowsが成熟するにつれて、動作が変わって特定のものが壊れることがある。前述の技術がそのゲームを壊すと思ってるの?もし何かが「壊れる」としたら、それはアンチタンパー機能が無効になるだけだよ。

識別情報を「盗まれた定数」や「盗まれた命令」と呼ぶのが混乱する。なぜそれが盗まれたと見なされるのか理解できない。「傍受された」と言いたいのかな?

「盗まれた」定数や命令は、元の(VM難読化された)バイナリに含まれていたコードの一部だよ。これらの定数や命令はバイナリから削除され、サーバーから難読化された形で提供される。つまり、ゲームを買ったときに手に入るバイナリは不完全で、サーバーから動的で暗号化された、システム依存のパッチを受け取って、欠けている部分(「盗まれた」部分)を補うことになる。

これはリバースエンジニアリングや低レベルプログラミングではよく使われる用語だね。VMでは、元のバイナリから取られたバイトや命令、定数を指して「盗まれた」って言うことが多いよ。オブフスケートされてるかどうか、ローカルバイナリにまだあるか、デヌーボみたいなサーバーにあるかは関係なくね。

明らかに効果的だよ。PCゲームの海賊版サイトに行くと、ほとんどのゲームが手に入るけど、Denuvoで保護されているものは数年経っても入手できない。誰もそれをクラックしようとしないか(ありえないけど)、Denuvoが素晴らしい仕事をしているかのどちらかだね。

ある程度はそうだけど、これは「解けない」っていうよりコストと利益の分析だよ。デヌーボはすごく侵入的だから、ソフトウェアの脆弱性を利用するのは労力に見合わない(ユーザーのリスクもあるし)、だから物理的な脆弱性が売られることが多い。例えば、物理的なFPSの脆弱性には、HDMI/DPチェーンに接続してUSB出力でキーボードとマウスをエミュレートするデバイスが含まれてる。

確かにデヌーボがかかったゲームはたくさんあるけど、まだ割られてないゲームのほとんどにはデヌーボが入ってると思う。デヌーボのバージョンにもよると思うけど、新しいバージョンはかなりしっかり守られてる感じだね。

それがシングルプレイヤーゲームのシェアが減ってるせいかもね。マルチプレイヤーや常時オンラインのゲームは、オフラインゲームに比べて狙いが定まらないし、一度割るだけで済むからね。すべてが「オンライン」である必要があって、ユーザー体験なんてお構いなしだよ。

割られたデヌーボゲームはあるし、どんなアンチパイラシー対策も絶対に壊れないわけじゃない。コピー保護されてる状態でPCで動くってことは、どこかでCPUが正しい命令を実行したってことだから、必ずクラックは可能だよ。逆アセンブルするのにどれだけの労力と時間がかかるかの問題だね。ソフトウェアを無限にコピー保護することはできない。俺がティーンエイジャーの頃、GTA 3を復号化後のライブメモリをダンプしてクラックした時は、めっちゃクールだなって思ったのを覚えてる。もちろん、もう25年経ったから、状況はかなり改善されてるし、コピー保護にどれだけの人年やkWhが無駄にされてるかは神のみぞ知る。

これは両方の組み合わせだと思う。聞いた話だと、デヌーボは「シーン」から多くの人を雇ってるらしいし、誰かがクラックすると徹底的に追いかけるみたい。デヌーボは今のゲームの数が多すぎて、特定のゲームにこだわるほどの大きなターゲットにはなってない。例外は「ホグワーツレガシー」がデヌーボ付きでリリースされた時で、クラックがたった13日後に出たからみんな狂ったように盛り上がったよ。

Denuvoで保護されているものは、何年経っても利用できない。これはマーケティングの主張みたいだね。Denuvoで保護されたゲームの中には、すでにクラックされているものがたくさんあるよ。私が知っている限りでは、完全に最新情報ではないけど、クラックされたDenuvoゲームの方が、そうでないものより多いと思う。しばらくの間、毎月「ゲームリリースから数時間でDenuvoがクラックされた」って見出しがあった気がする(例: https://www.techspot.com/news/71543-denuvo-protected-games-n...)。Denuvoは、特にゲームの発売時にその目的に対しては一般的に効果的だと思うけど、全く完璧ではないよ。

Denuvoの一番重要な点は、ゲームパブリッシャーにサブスクリプションライセンスがあるから、一定の期間が経つとほぼ必ず削除されるってこと。これが、なぜクラックされにくいのかを理解するのに重要なんだ。経済的に「3ヶ月かけて難解な手法を取り除くか、1年待ってゲームはどうせ保護されなくなるか」ってシフトしてるから。> Denuvoで保護されているものは、何年経っても利用できないってのは、一般的には真実じゃないと思う。> 誰もクラックしたがらない(ありえない)ってのも、その通りだよ。時間と利益の問題であって、「可能かどうか」じゃない。Denuvoの画期的な点は、全体の技術が理解できないわけじゃなくて、取り除くのがすごく面倒で、自動化が非常に難しいってこと。彼らは画期的な理論的技術を作ったわけじゃなくて、バイナリを難読化するための「標準的な」方法をたくさん適用した結果、取り除くのが面倒すぎるって感じだね。

目標は、リリース時にゲームを保護することだよ。ここで大半の収益が得られるからね。

10年前、ゲームがどこでも導入され始めたときに、子供の頃のゲームから抜け出すことができたよ。彼らが考えていたビジネスアイデアとはちょっと違うと思うけどね。今はF2Pのガチャをちょこちょこやったり、たまにGame Passをチェックしたりしてるから、もうそれ以来、ゲームにハマることもないかな。

ちょっと関係ないけど、「2年生のコンピュータサイエンス学生」ってブログ名を見たら、ポジティブな意味で驚いたけど、ちょっと切ない気持ちにもなった。作者には本当に拍手を送りたいね。

深いリバースエンジニアリングに耐えられるのは学生だけだよね。俺もティーンエイジャーの頃、似たようなVMを使ったバイナリを解凍するのに何時間も費やして、かなり上手くなった。でも今は全然無理だな。最近hacktheboxに戻ろうとしたけど、新しいREチャレンジは脳が痛くなる。

エンプレスの分析を見てみよう

よく訓練されたモデルなら、すぐに解決できることばかりだよ。単なる雑務で、ロケットサイエンスじゃない。DRMはクソだけどね。いいニュースは、あのAAAゲームは誰にとっても時間の無駄なことが多いってこと。インディーズやクラシックゲームを楽しんだ方がいいよ。良いSNESゲームは、あのクソみたいなAAAライセンスのリメイクよりも百倍価値があるから。

ノーマルな人には向いてないね。

現代のゲームの技術的な質がどれほど低いかは、言い過ぎだとは思わない。ほとんどのDX12/Raytracingタイトルは、ひたすらカクカクしてて、異常なシェーダーコンパイルやトラバースのカクつきがある。Lumenによって生じるおかしなゴーストアーティファクトなんて気にしないで。現代のゲームは、スクリーンショットやトレーラー用のリアルタイムでないエンジンレンダリングを良く見せるように最適化されてる。ハードウェアやAPIはこれまでで最も強力なのに、エンジン開発者たちは2000年代の30fpsハードロックされたXboxポート以来、最悪の動作をするゲームを作り出してる。

これは、意味のあるプロダクションの脅威検出ソフトウェアには全く当てはまらないってことを強調したい。モデルは、基本的な難読化タスクを逆転させるのにも失敗することが多いよ。自分で試してみて。ChatGPTがDenuvoを破るなんてことはないから。多分、OpenAIの夢の中でも無理だと思う。画像や音を生成するのは、実際の複雑なソフトウェアタスクに比べれば子供の遊びみたいなもんだしね。トレーニングできるオープンソースのDRMコードベースが1,000もあるわけじゃないし、多様な分野でもないよ。スクリプトキディのフックを作るコードを生成するのはいいけど、複雑なマルチティアの難読化や信頼プラットフォームを逆転させるなんて、無理だよね。

しばらく前にDenuvoを見てみたことがあるよ。LLVMを使ってx86の難読化を取り除いて、VMオペコードに分解したんだ。少なくともその時は、Denuvoはゲームコードをスタックマシンに変換しているように見えた。これがVMプッシュの例だよ: temp[0]=add(mem[e268], fffffffffffffff8) mem[temp[0]]]=mem[e560] mem[e268]=temp[0](vmreg_e268はスタックポインタで、減算されてtempregに保存され、その後vmreg_e560の値がスタックポインタアドレスにコピーされ、最後に新しいスタックポインタ値が書き戻される)。でもMBAが大量に出てきた時にすぐに興味を失ったよ: temp[7]=sub(add(add(and(mem[ebe8], b2f7), 3fd8), xor(lshr(mem[ebe8], 1), 2684)), lshr(add(mem[ebe8], b2f8), 1)) temp[d]=or(sub(sub(4ad, temp[7]), xor(and(shl(temp[7], 1), 95c), 95c)), 8000) temp[e]=lshr(temp[d], 1) temp[11]=lshr(add(temp[d], 8001), 1) mem[ebe8]=sub(xor(xor(temp[e], 3fff), temp[11]), shl(and(and(temp[e], 3fff), temp[11]), 1))(一定の操作をvmreg_ebe8に対して行っているようだけど、MBAで難読化されていて、結果はほとんど使われないから、実際の操作をかき消すためのノイズに過ぎない)。ところで: MBAを扱えるLLVMオプティマイザーパスの実装について知ってる人いる?

ところで: MBAを扱えるLLVMオプティマイザーパスの実装について知ってる人いる? あなたのベストな選択肢はInstCombineだけど、ほとんどのMBAパターンはInstCombineパターンにはならないと思う。誰がそんなコードを書くんだって話だし。原理的には、Alive2を使って(LLVM IRをSMTロジックにマッピングできる)ペーパーホールオプティマイザーを作れるかもしれないけど、そんなパスを作った人はまだいないし、コンパイラの中では普通のパスではないよ。

SiMBA++を見てみて -> https://github.com/pgarba/SiMBA- これはSiMBAのC++実装なんだ [1] - Denuvo自身が提供している線形MBAを扱うツール。Denuvoには非線形MBAを扱うためのGambaという別のツールもあるよ。そして、別の研究者によるさらなる改良版MSiMBA [3]もある。SiMBA++はC++で書かれているから、速いし、LLVMパスにうまく統合されてMBAを自動的に特定して、LLVM IR内で簡略化された表現に置き換えることができる。だから、追加の作業は不要だよ。ちょっと宣伝になるけど、私と同僚(SiMBA++の作者)は最近、WASMの難読化解除にLLVMを使うことについての講演をしたんだ。その中でMBAやSiMBA++についても話してる。アイデアはWASMに限らず、バイナリをLLVM IRに持ち上げれば言語に依存しないんだ。https://www.youtube.com/watch?v=gKRdOcuXbYI [1] SiMBA - https://github.com/DenuvoSoftwareSolutions/SiMBA [2] Gamba - https://github.com/DenuvoSoftwareSolutions/GAMBA [3] MSiMBA - https://github.com/mazeworks-security/MSiMBA

数年前、友達が暇なときに数年かけてDenuvoに相当するものを作ったんだ。彼の最初のアイデアは「小さな人のためのDRM」で、インディーゲームが初期リリースの海賊版で大きな収益を失っていることに気づいていた。彼はそれをどうやって売るか全然分からなかった。しばらく放置されていた後、VCの友達にその技術を提案してみたけど、全く何を言ってるのか分からなかったみたい。才能と努力の結晶が何の報酬も得られないのを見るのは、長い間モヤモヤしてた。こういう技術を大手出版社が買い取って、自社のアンチパイラシーをDenuvoに頼らずに内製するのは面白いんじゃないかって思ったんだけど、どう思う?アイデアや助けがあれば教えてほしい :)

インディーゲームが初期リリースの海賊版で大きな収益を失っていることに気づいていた。これは特にインディーゲームに関しては変な主張だね。インディーゲームはそもそも買い手を引きつけるのが難しいから、海賊版を考えている人はできなければそのまま別のゲームに移る気がする。

財布で投票して、こんなゴミが入ったゲームは買わないようにしよう。

Denuvoが原因で、たくさんのカクつきや、膨大なロード時間の増加、全体的なパフォーマンスの問題が起きるのは注目すべきだね。Denuvoのマーケティング部門はこれが真実じゃないって言いたがるけど、Denuvoありとなしのゲームのビフォーアフターを見れば一目瞭然だよ。モンスターハンターワールドはその典型的な例だった。Denuvoがモンスターハンターワイルドのパフォーマンス問題にも大きく寄与しているのは間違いないと思う。