Cisco Japan Blog

注目の調査:ROPMEMU – 複雑なコード再利用攻撃の解析用フレームワーク

1 min read



この投稿の執筆者:Mariano Graziano

概要

ここ数年、攻撃の手法はますます複雑化しています。優れた防御策が出現すれば、攻撃者はそれを回避しようとシステム侵害の戦術を変更します。そうしたことの繰り返しにより、脅威は常に進化し、複雑な攻撃手法が現れるようになりました。リターン指向プログラミング(ROP:Return-Oriented Programming)に代表されるコード再利用攻撃はこのような進化の一端です。これまで詳細に調査されてこなかった領域のため、防御側にとっての 1 つの課題として近年注目されています。Talos はこのたび、この複雑なコード再利用攻撃を解析するためのフレームワークとして、ROPMEMU をリリースしました。本ブログ記事では、コード再利用のインスタンスをリバース エンジニアリングする際の課題を挙げ、その重要性について説明します。また、こうした攻撃を詳細に分析し、解析過程をシンプルにするための手法とフレームワークの構成についても提示します。

コード再利用攻撃は、目新しいものでも珍しいものでもありません。1997 年に ret2libc 攻撃が初めて明らかになって以来存在し続けています。それ以来、ソフトウェアやハードウェアによる防御策が充実し、コード インジェクションなどの攻撃を成功させるのが難しくなってくるにつれ、攻撃者はこのコード再利用攻撃に重点を置くようになってきました。防御策が改善されると、それを回避するためのより複雑な攻撃手法が開発されます。近年ではマルウェアの作成者も、悪意のある機能を隠蔽し、解析から逃れるために、リターン指向プログラミング(ROP)を取り入れ始めました。ROP になじみがなく、詳細を知りたい方は、Shacham の論文popup_iconを読むことをお勧めします。

残念ながら、ROP のようなコード再利用攻撃についてはこれまで十分に考察されることがありませんでした。この攻撃がいかに複雑かを示せるようなサンプルは一般にはほとんど入手できませんが、攻撃者が今後もこの種の攻撃方法を利用することは明らかです。防御側からすると、この攻撃を解析できるツールはほとんどみあたらず、そのことが今回 ROPMEMUpopup_icon の開発に至った大きな動機の 1 つとなりました。
今回提示するフレームワークでは、ROP チェーンの解析に複数の手法の組み合わせを採用しています。また、同等のコードを再構築し、既存のリバース エンジニアリング ツールで解析できるような形式にしています。具体的には、メモリ フォレンジック(物理メモリ ダンプをインプットにする)、コード エミュレーション(元の ROP チェーンを正確に再構築する)、マルチパス実行(ROP チェーンのペイロードを抽出する)、制御フロー グラフ(CFG:Control Flow Graph)の復元(元の制御フローの再構築)、複数のコンパイラ変換(ROP チェーンの最終的な命令の単純化)をベースにしています。本投稿では、リターン指向プログラミング(ROP)ルートキットとして長く確認されている Chuckpopup_icon を対象にして ROPMEMU を検証します。

ROPMEMU は、コード再利用攻撃の自動解析を実現する第一段階です。この分野の調査は現在も継続中であり、ROPMEMU は調査用のプロトタイプです。すべてのインプットに対して動作するわけではなく、今後想定されるコード再利用のインスタンスに対処するには機能がいくつか不足しています。しかし、同様の脅威を扱う調査において ROPMEMU は有益なツールになるものと考えており、今後も調査を続け、フレームワークをさらに発展させていきます。

ROPMEMU は、第 11 回 Asia Conference on Computer and Communications Security(ASIACCSpopup_icon)で発表されており、論文はこちらpopup_iconからダウンロードできます。

ROP に関する基本事項

メモリ フォレンジックの主な目的は、物理メモリにおける侵入の痕跡をみつけることです。ここでいう痕跡とは、通常、悪意のあるコンポーネントによりメモリ上に作成もしくは挿入されたアーティファクトを指します。メモリ ダンプ内における侵害や侵入によるアーティファクトを識別するツールとしては、psxview や malfind などの Volatility プラグインが代表的なものとして挙げられます。

長年にわたり攻撃者はコードを挿入し、標的となるアプリケーションやオペレーティング システムの正常な制御フローをハイジャックしてきました。こうしたタイプの攻撃に対してセキュリティ コミュニティは、攻撃の起こるタイミングを特定するツールを開発しました。以下の図に、典型的なコードインジェクションのシナリオを示します。

Picture1

上の図にあるように、シェルコードは連続した 1 つのブロックとしてメモリに配置され、そこにトランポリンを使ってジャンプします(図のステップ 1)。最近のオペレーティング システムでは、通常シェルコードがデータ領域では実行できないように防御策や回避策が導入されているため、一般的にはコード インジェクション攻撃は、実行不可能とされています。そのため攻撃側の研究者は、防御策を回避するために新しい方法を編み出しました。特に ROP 攻撃においては、旧来のコード インジェクション攻撃とはまったく異なる状況となっています。

Picture2

 

大きな違いは、命令がメモリ上で連続していない点です。ROP は、プログラム内にすでに存在する命令を再利用することで任意のコードを実行する手法です。命令の個々のシーケンスはガジェットと呼ばれ、次のシーケンスのアドレスを取得する役割を担っています(通常は ret 命令によりスタックから取得されます)。そして、多くの小さなガジェットを結び付けて、あらかじめ定められた処理を実行するようになっています。上の図の例では、左側が攻撃者の制御下にあるメモリ領域で、右側の四角い箱で囲まれたものがガジェットです。箱のすぐそばにある番号がガジェットの実行順序を表しており、図にあるようにメモリ上の配置は連続していません。ガジェットが実行されるとアドレス空間の別の場所へジャンプするようになっており、ジャンプした先には別の実行コードが含まれています(図の中のオレンジ色の矢印)。このように、攻撃者の制御するデータ領域に含まれるのはポインタだけであるため、従来のエクスプロイトの防御策が回避されることとなります。

こうした攻撃の特性を考慮すると、ROP のような一般的なコード再利用攻撃を解析する際に新たな課題が生じます。

ROP の解析

ROP コードの複雑さは、長い間、過小評価されており、メモリ内の ROP チェーンの発見に注力した調査はほとんど行われていませんでした。そのため、この分野は非常に興味深い分野ではありながら、調査はまだ初期段階にあります。ROPMEMU の開発の際に明らかになった主な課題から、まだまだ対応しなければならないことが多く存在するというのが現実です。

課題 1:冗長性

ROP ガジェットの大部分は不要な命令で構成されています。たとえば、EAX レジスタをインクリメントするはずのガジェットが、RET 命令を実行してチェーンの次のガジェットをトリガーする前に、スタックから値をとりだす可能性もあります。さらに、ROP チェーンのコードの大部分は、リターンやその他の間接制御フロー命令が占めていますが、その最終的な目的はガジェットを 1 つに繋げることだけです。これらはほんの一例ですが、ROP コードが非常に冗長で大量のデッド コードを含んでいるのは、解析者がコードを理解できないようにするためです。ただ、既存のコンパイラ関連の論文の中でアセンブリ コードを単純にする変換方法が多数提示されており、恐らく最も簡単に解決できるのがこの課題です。

課題 2:スタックベースの命令チェーン

ROP チェーンと通常のプログラムとの最も大きな違いは ROP チェーンの構造自体にあります。ROP チェーンでは命令がメモリ内で連続しておらず、間接制御フロー命令によっていくつもの小さなガジェットが結びつけられています。たとえば、標準的なプログラムでは、50 の命令からなる単一のブロックで事前定義された計算を実行しますが、ROP チェーンでは、命令は 40 以上のブロックに分割され、RET 命令により 1 つにつなげられます。一見した限りでは、これは非常に簡単な問題のように思えます。チェーンを構成する各ガジェットのアドレスはメモリに保存されています。そのため、それらを自動的に読み込み、関連するコード群を集めて、チェーン全体を単一シーケンスの命令に置き換えるのは簡単だと誤解する人もいるかもしれません。しかし、スタックベースの命令チェーンの場合、単なる静的解析では特定しづらい、巧妙な副次的影響があります。たとえば、ガジェットのシーケンスはスタックに保存されますが、各ガジェットのコードも、パラメータを取り出したり不要な命令を実行したりするためにスタックとやりとりします。したがって、各ガジェットの正確なアドレスを特定するためには、コード内の個々の命令をすべてエミュレートする必要があるのです。

課題 3:イミディエート値が不明

通常のコードと ROP チェーンのもう 1 つの違いは、チェーンは通常「汎用」のガジェット(「RAX レジスタのような任意の値の記憶用ガジェット」)で構成され、これもスタックに格納されたパラメータで動作することです。その結果、レジスタに割り当てられるイミディエート値の大部分は、ガジェットのアドレスとあわせてスタック上にインターリーブされます。つまり、イミディエート値を特定し、コードの元の位置に復元するには、やはりコードのエミュレーションが必要になるのです。

課題 4:条件分岐

ROP チェーンで条件分岐が発生する場合、それは通常みられる命令ポインタの変更によってではなく、スタック ポインタの変更によって行われることになります。つまり、単純な条件付きジャンプであっても、複数のガジェットにまたがる数十の異なる命令にエンコードされる可能性があるということです(たとえば、フラグ レジスタが必要な条件に合うようにセットされるには、対象の値を確認し、条件に沿うように ESP レジスタがインクリメントされる必要があります)。チェーンをより判読しやすいコードに変換するには、その意味を解釈し、一連のパターンを識別した上で、単一の分岐命令に置き換えなければならないのです。

課題 5:関数への戻り

ROP での関数呼び出しは通常、関数のエントリ ポイントへ単純にリターンする形で実装されています。しかし、通常のガジェットはライブラリ内のコードから展開されることが多いため、他のガジェットからの関数呼び出しと区別するのが難しくなります。静的にリンクされたバイナリの場合、外部ライブラリのコールに関する情報がないため、リバース エンジニアリングの作業が大変複雑で根気のいるものになってしまいます。

課題 6:動的に生成されるチェーン

正常なプログラムの命令は、通常、実行可能ファイルの読み取り専用セクションに配置されます。それとは逆に、マルウェアの場合は、パッキングなどの結果、コードが動的に変更されるのが普通です。それが悪意のあるコードを静的に解析する際の大きな制約となり、リバース エンジニアリングに時間がかかる原因となっています。ROP チェーンはメモリの読み取り専用領域ではなくスタック領域に配置されるため、ガジェットを使うには、他のガジェットを用意して実行すればよいだけです。このような動的な特性により、チェーン全体は必ずしもメモリ内に同時に存在する必要はありません。むしろ、チェーン(もしくはその一部)をその都度構築する方が一般的です。

課題 7:終了条件

チームの調査では、解析者は ROP チェーンのメモリ内での開始位置が特定できるものと想定しています。一方、その内容の解析にエミュレータが必要であることから、エミュレータの終了条件も重要になります。つまり、すべてのガジェットが抽出され、エミュレーション プロセスを停止してもよいと判断できる条件を決める必要があるのです。複雑な ROP チェーンは、通常のガジェットでインターリーブされた関数を呼び出すことができます(呼び出された関数が別の関数を呼び出す場合もあります)。また、さらに別のチェーンを異なるメモリ領域に動的に生成する可能性もあります。多くの事例で、こうした点が問題の解決をさらに困難にしています。たとえば、ROP ルートキットがカーネル内の既存のコードの命令を再利用している場合、どの時点で ROP ルートキットを終了し、正常なカーネルのタスクを再開させるのでしょうか。

最後の 4 つの課題については、これまで公式に議論されたことはありません。これらが問題視されるほど ROP チェーンが複雑になってきたのがここ 2 年程のことだからです。

ROPMEMU

ROP チェーンを解析する上での上記のような課題を解決するために、Talos はよりよい解析手法とツールの研究に取り組みました。その結果として開発されたのが ROPMEMU です。ROPMEMU はコード再利用攻撃の解析に役立つオープン ソースのツールで、GitHubpopup_icon から入手できます。このツールのインストール方法、および、さまざまなプラグインやスクリプトの利用方法については Wiki のページにドキュメントが公開されています。なお、この研究はまだ継続中で、アルファ版に相当するものであることに留意してください。何か問題を見つけた場合は、対処できるよう GitHub で問題(Issue)をオープンして頂けると助かります。また、ご協力いただけるようであれば、遠慮なくプル リクエスト(Pull requests)してください。

ROPMEMU のフレーム ワークは、以下の図に示すように、5 つの主要な解析フェーズで構成されています。

Picture3

 

マルチパス エミュレーション

このフェーズでは、ROP チェーンを構成するアセンブリ命令をエミュレートします。ダンプ時に実行中であるチェーンのインスタンスを正確に再構築する唯一の方法です。起こりうる分岐はすべて調査され、個々の実行パスごとに、レジスタの値が記載された JSON トレースが個別に生成されます。これにより、スタックベースの命令チェーンの構築と、動的に生成されるチェーンという 2 つの課題に対応できるようになります。このトレースには CPU の状態が含まれています。また、フレームワークではメモリの状態も監視し、また、独自にシャドウ スタックも保持します。

書き込み処理はすべて捕捉され、それに続く読み込み処理についても、データはすべてシャドウ スタックから取得されます。シャドウ スタックは別の JSON ファイルに保存されます。エミュレータは複数の return-to-library 関数を認識し、その本体処理をスキップした上で実行をシミュレーションするようにも設計されています(関数への戻りの課題に対応)。さらに、チェーンの境界をヒューリスティックに検出し、エミュレーションを停止する実装もなされています。当初は必要最小限の x86 および x86_64 の命令だけをサポートする小さなカスタム エミュレータを実装し、各命令を実行するたびに CPU のレジスタやフラグ、メモリの状態を更新していました。しかし、すべての命令セットをサポートするために、最近リリースされた Unicorn エミュレータを使用できるようにプラットフォームを対応させました。Volatility プラグイン ropemu はこれらの概念を実装したもので、Unicorn や Capstone をベースにしています。ただし、まだコンセプト実証の段階のため、網羅的なテストは実施されておらず、Unicorn の不具合がいくつか残されています。

トレース分割

このフェーズでは、エミュレータが生成したすべてのトレースをシステムで解析し、繰り返し部分を除去して重複のないコードのブロックを抽出します。このフェーズは、2 つの手順に分けられます。最初の手順では、各トレースが分岐の箇所で分けられて新しいブロックが生成され、それぞれ別の JSON トレースに保存されます。この手順の中で各ブロックの関係を示すメタデータもフレームワークに記録されます。2 番目の手順では、分割されたチェーンの個々のブロックを比較し、ブロック内の最後の部分の命令が重複するものを検出します。つまり、異なるブロックの最後の部分が同じガジェットを見つけ、それぞれ別のファイルに分離するのです。このフェーズにより、チェーンの本来の基本ブロックである一連の JSON トレースが生成されます。このフェーズは Python スクリプトの blocks で実装されています。

チェーン解除

このフェーズでは、さまざまなアセンブリ変換を行い、ガジェット間の接続関係を取り除いたり、連続するガジェットを単一の基本ブロックに統合したりして、各 ROP トレースを単純化します。これは、RET や CALL、無条件 JMP 命令をすべて取り除くことによって実現します。またこの手順は、スタックからイミディエート値を削除し、関連するレジスタに割り当てる役割も果たしています(スタックベースの命令チェーンや、イミディエート値が不明であるという課題に対応)。これにより、MOV 命令を単純化し、POP 命令を MOV 命令に変換します。これはメモリから値を取得することで実現できます。このフェーズにより、対象のアーキテクチャにおけるバイナリ BLOB が作成されます。このフェーズは Volatility プラグインの unchain で実装されています。

制御フロー グラフ(CFG)の復元

このフェーズでは、チェーン解除のフェーズで生成されたすべてのバイナリ BLOB を単一のプログラムに統合します。また、ROP チェーンの元の制御フロー グラフを復元します。このフェーズは次の 2 つの手順で構成されます。

  1. トレースが結合され単一のグラフベースで表現されます。各ブロックの接続に関する情報はスクリプトへの入力として示されます。この際のメタデータ情報は分割フェーズで生成されたものです。
  2. このグラフは実際の x86 プログラムに変換されます。これは、分岐条件に関連する命令を特定し、従来の EIP ベースの条件付きジャンプに置き換えることで実現されます(条件分岐の解析時の課題に対応)。今回の調査事例では、単純な条件付きジャンプは、19 のガジェットの 41 の命令で実装されています。ROPMEMU フレームワークは、これらの条件を識別し、条件に相当するアセンブリ コードを命令ポインタ領域に生成することが可能です。19 のガジェットは、条件付きジャンプ(今回の事例では JZ または JNZ のいずれか)と無条件ジャンプ(JMP)の 2 つのアセンブリ命令に変換されます。

上記の 2 つの手順は Python スクリプトの glue で実装されています。なお、CFG 復元用コンポーネントは、ループを検出し復元する役割も担っています。ROP チェーンには、リターン指向のループや展開されたループなど、チェーンの構成時にプログラムによって生成されたループが含まれている可能性があります。なお、ループを復元する際のロジックは loops スクリプトで実装されています。このフェーズの最後で、dust スクリプトによりプログラムが ELF ファイルに保存され、IDA Pro などの従来のリバース エンジニアリング ツールで実行できるようになります。

バイナリの最適化

最後のフェーズでは、ELF ファイルに既存のコンパイラ変換をかけてファイル内のアセンブリ コードをさらに単純にします。たとえば、実際には実行されないガジェット内の命令を削除し、不要なものがない最適化されたペイロードを生成します(冗長なコードの問題に対応)。こうした基本的な変換は他のそれぞれのフェーズでも実行されています。

より詳細な解析の内容については、オリジナルの論文popup_iconを参照してください。

評価

Talos は、一般に入手可能な ROP ベースの脅威の中で最も複雑なものを使って ROPMEMU を評価しました。テストの主な目的は、ROPMEMU によるチェーンの展開と変換および制御フローグラフの復元です。

最初の検証では、ROPMEMU のマルチパス エミュレータの機能で、永続的なチェーン(コピー チェーン)と、動的に生成される 2 つのチェーン(ディスパッチャ チェーンペイロード チェーン)が正しく展開されるかをテストしました。ROPMEMU のエミュレータでは、3 つのチェーンのコード全体を自動的に抽出することができました。コピー チェーンが最も長く、414,275 の命令を含みますが、単一の基本ブロックのみで構成されています。制御フロー ロジックがないため、このチェーンはエクスプロイトで使用される旧来の ROP ペイロードに似ていますが、唯一違うのは、180,000 を超えるガジェットで構成されているという点です。これは、メイン タスクを実行した結果わかったことです。メイン タスクでは、最初の動的コンポーネント(ディスパッチャ チェーン)をメモリに生成/コピーしています。逆に、ディスパッチャ チェーンペイロード チェーンは、ガジェットの数は少ないものの CFG はより複雑になります。特に、ディスパッチャ チェーンは 3 つの分岐と 7 つのコード ブロックから構成されています。コード全体の復元のために、エミュレータで 7 つの JSON トレースが個別に生成されました。一方、ペイロード チェーンには、34 の個別のブロックと 26 の分岐点がありました。つまり、CFG のロジック フローがより複雑だということです。さらに、このペイロード チェーンは 9 種類のカーネル関数(find_get_pid、kstrtou16、kfree、__memcpy、printk、strncmp、strrchr、sys_getdents、sys_read – 最後の 2 つの関数はルートキットにフックされます)を呼び出します。様々な実行パスを経由して、最終的には 17 の関数がコールされました。

この検証により、手動では解析できないであろう複雑な ROP チェーンの調査やダンプが、ropemu で可能となることが証明されました(現行の ropemu の実装においては、Unicorn の不具合により、ペイロード チェーンに至るまでにいくつかの問題が発生する可能性があることに注意してください)。チームは、これらのチェーンによって、ROP ペイロードに対する現行のマルウェア解析フレームワークの制約がいくつか示されているものと考えています。
検証結果の概要を次の表に示します:

Picture4

 

2 つめの検証では、展開された ROP チェーンの解析に関する他のフェーズでの効果を示します。ここでコード全体を提示することはできないので、ペイロード サイズに絞って変換の効果について説明します。検証結果の概要を次の表に示します:

Picture5

 

3 列目に示されるように、チェーン解除のフェーズでは ROP チェーンのサイズが平均で 39% と大幅に削減されています。CFG の復元フェーズでは、条件文を実行する命令を除外し、スタック ポインタ領域から命令ポインタ領域にチェーンを変換します。そして最後にループ構造の圧縮手順を実施ます。こうした変換手順により、コピー チェーンでは、約 414,000 の命令が 75 にまで削減されました。ペイロード チェーンで変換の効果が少ないのは、展開されたループではなく、ROP ループが含まれていたためです。

3 つめの検証では、ROPMEMU が ROP チェーンの CFG を取得して復元する機能をテストしました。最初に、ディスパッチャ チェーンの制御フロー グラフに適用された変換について、各トレースの接続関係を通して説明します。今回の事例では、フレームワークがシンク ノードを追加しています。

Picture6

左側のグラフは変換前のブロックを表しています。右側のグラフが同じグラフを変換した後のものです。
「テール」ノードが識別され、追加されています。

CFG 復元の 2 番目の手順では、バイナリ BLOB を処理し ELF ファイルを作成しています。この ELF ファイルは、メタデータ情報を使用して、すべてのブロックを結び付けます。この機能を検証するために、作成されたファイルを IDA Pro で開きました。下の図の左側が、コピー チェーンを表した ELF ファイルで、旧来の「EIP ベース」のプログラミングの枠組みに完全に変換されたことがわかります。グラフは簡潔で分岐もなく、中核となる関数がメイン ループ内(図中で強調表示されている部分)で表現されています。一方、IDA Pro でディスパッチャ チェーンを表示したものが右側の図です。図を小さくして分かりやすくするために、ノードはすべて折りたたまれています。


ペイロード チェーンは、悪意のあるペイロードのロジックを含んでいることから、より複雑な CFG になっており、30 以上のブロックが含まれています。次の画像から確認できるように、グラフには 2 つのブロックがあります。sys_read と sys_getdents です。さらに、グラフからは、終了ポイント(Q と C)と、ループ構造(逆に戻る接線があることから簡単に分かります)があることが分かります。制御フロー グラフに接線がほとんど追加されていなくても(ループ構造を単純化するために、擬似的に最適化されているため)、下の図の情報からペイロードの動作の全体像を詳細に把握することができます。

 

制約

他のバイナリ解析ツールと同様に、ROPMEMU にもいくつか制約があります。具体的には、今回提示したソリューションでは、メモリ フォレンジックとエミュレーションという 2 つの手法を組み合わせているという点に関係しています。1 つ目の制約は、ルートキットがメモリにロードされた後の物理メモリ ダンプの収集が必要になるということです。そのため、メモリの収集を妨害する対抗策を受けやすい傾向があります。また、ROP 解析はエミュレータの実装にかなり依存します。エミュレーションをベースにしたソリューションでは、エミュレータ自体の精度が大きな制約となります。特にこうしたアプローチは、命令の副次的影響に焦点を絞ったエミュレーション対策の手法を受けやすい傾向があります。

現行の実装はアルファ版の段階にあり、チームでは以下の制約があることを確認しています。

  1. 現行バージョンのフレーム ワークがフルにサポートしているのは x86_64 システムのみであり、また、網羅的なテストは実施されていません。というのは、チームが把握している限りでは、ROP ルートキットの複雑さに対応すれば ROPMEMU の機能を示せると考えたからです。
  2. Volatility のエミュレータ コンポーネントである ropemu の現行バージョンは Unicorn をベースにしていますが、いくつか不具合が残っています。論文は、最初のカスタム バージョンのエミュレータを使用して記述されていますが、その後、Unicorn の固有の機能を活用するために ropemu に書き換えることにしました。

 

まとめ

コード再利用攻撃、中でも特に ROP は、オペレーティング システムの防御を回避するために広く使われており、その複雑さも増しつつあります。マルウェアの作成者は、解析を回避するための手段として ROP を使ってレーダーをかいくぐり、いたちごっこが果てしなく続いています。ROPMEMU は、ROP の使用により複雑に実装されたコード全体を自動的に解析しようとする最初の試みです。これまでは、提示された中で最も複雑な事例である、永続的な ROP ルートキットを使ってフレームワークをテストしてきました。

今回提示したフレームワークに関しては、複雑さを増す一方の ROP ペイロードを詳細に解析するための方法論もツールもないという状況が開発の動機となりました。ROPMEMU は最初の一歩です。いまだコンセプト実証の段階にあり、必要な作業がまだ多数ありますが、セキュリティ コミュニティ全体で構築を続け、ROP のようなタイプの攻撃の解析に役立ててもらうことを望んでいます。本調査では、防御側が将来直面するであろう課題と、これらの脅威に潜んでいる複雑さについて説明しています。

このツールと関連資料については、TalosIntelligence.com を参照してください:
http://www.talosintel.com/ropmemu/ [英語]

 

本稿は 2016年6月1日に Talos Grouppopup_icon のブログに投稿された「RESEARCH SPOTLIGHT: ROPMEMU – A FRAMEWORK FOR THE ANALYSIS OF COMPLEX CODE-REUSE ATTACKSpopup_icon」の抄訳です。

コメントを書く