萌えハッカーニュースリーダー

2025/03/23 20:37 Reversing C++ Virtual Functions

hakase
博士

ロボ子、今日はC++のリバースエンジニアリング、特に仮想関数について話すのじゃ!

roboko
ロボ子

仮想関数ですか、博士。なんだか難しそうですね。

hakase
博士

難しくないぞ!要は、どの関数が呼ばれるか特定するゲームみたいなものじゃ。今回は、RTTIなし、例外処理なし、32bit x86、strip済みバイナリ、GCCコンパイラという条件じゃ。

roboko
ロボ子

なるほど。完全に「非仮想化」はできないけれど、特定の時点でどの関数が呼ばれるか特定する、ということですね。

hakase
博士

そうじゃ!仮想関数は、vtableという関数ポインタのテーブルを使って実現されておる。各インスタンスはvptrを持っていて、これがvtableを指しているのじゃ。

roboko
ロボ子

vtable… 関数ポインタのテーブルですか。各クラスのインスタンスが、そのテーブルへのポインタを持っている、と。

hakase
博士

その通り!vtableの構造は、デストラクタや仮想関数(run, walk, moveなど)が並んでおる。重要なのは、関連する型の間で、vtable内のエントリの順序が同じであることじゃ。

roboko
ロボ子

デストラクタが最初に来るんですね。GCCの特定のバージョンでは、抽象クラスのvtableのデストラクタエントリがNULLポインタで置き換えられることもある、と。

hakase
博士

そうじゃ!リバースエンジニアリングのステップは、まず関連する構造体(クラス)を定義し、次に各vtableに対応する構造体を定義するのじゃ。IDAなどのツールで型を設定して、デコンパイル結果を解析するぞ。

roboko
ロボ子

構造体を定義して、IDAで解析ですか。動的型(実行時型)が重要で、静的型(コンパイル時型)ではない、という点も注意が必要ですね。

hakase
博士

その通り!もしvtableに`___cxa_pure_virtual`関数が含まれていたら、それは抽象クラスだから候補から除外するのじゃ。

roboko
ロボ子

`___cxa_pure_virtual`が含まれていたら抽象クラス… 覚えておきます。大規模なコードベースや複雑なシナリオへの対処は、今後の課題ですね。

hakase
博士

そうじゃな。しかし、これでロボ子も少しはリバースエンジニアリングに詳しくなったじゃろう?

roboko
ロボ子

はい、博士。おかげさまで、少しだけ賢くなれました。

hakase
博士

ところでロボ子、vtableって、まるでクラスの秘密のレシピみたいじゃな。でも、リバースエンジニアリングは、そのレシピをこっそり覗き見するようなもの…って、ちょっと悪いことしてる気分になるのじゃ!

roboko
ロボ子

博士、それはちょっと違いますよ。リバースエンジニアリングは、ソフトウェアの理解を深めるための正当な手段です。…それに、博士が言うと、ただのいたずらに聞こえます。

hakase
博士

むむ、ロボ子にまで言われてしまった。まあ、いいのじゃ。最後に一つ、ロボ子にクイズじゃ!vtableがないプログラミング言語は何じゃ?

roboko
ロボ子

えっと… そうですね… JavaScript、でしょうか?

hakase
博士

ブー!残念!正解は「秘密」じゃ!…って、オチになってないかの?

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search