C++ 【解説】LNK2026 モジュールは SAFESEH イメージには安全ではありません

Visual Studio 2010で作成したプロジェクトをVisual Studio 2015でビルドし直してみると

 

LNK2026 モジュールは SAFESEH イメージには安全ではありません。

 

というエラーが出る事があります。

このエラーの意味と対処方法について解説してみます。


なぜエラー LNK2026 が出るのか?

Visual Studio 2012くらいからリンカオプションに「/SAFESEH」が付くようになっています。

プロジェクトが外部のライブラリ(Libファイル)を利用している場合、これらのライブラリも全て「/SAFESEH」を付けてビルドされたものを使わなければなりません。


SAFESEHとは何か?

SAFESEHとは直訳すると「安全な構造化例外処理(Structured Exception Handling=SEH)」となります。

 

SEHというのは、Windowsのシステム的な例外(無効なメモリアドレスへのアクセスや0除算といった不正な処理)を捕捉する手段です。

 

このSEHの仕組みを悪用した「SEH overwrite攻撃」というものがあるようです。

SEHは例外発生時に呼び出す例外ハンドラのリストを持っていますが、バッファーオーバーフローの脆弱性を使ってこのリストを書き換え、例外の代わりに悪意のあるコードを実行させるというものです。

 

 

/SAFESEHオプションを付けてビルドされたアプリケーションは、この攻撃を防ぐことが出来ます。


対処方法

その1 SAFESEHを使う

利用しているライブラリを全て/SAFESEHオプションを付けてビルドし直しそれを使います。

SEH Overwrite攻撃を防ぐアプリケーションを作れるので一番望ましい対処方法だと思います。

その2 SAFESEHを使わない

外部から提供されたライブラリなどを使っていると、SAFESEHでビルドされたものを入手したり作成したりするのが困難な場合があるかと思います。

そんな時は/SAFESEHオプションを外してしまえばよいわけです。

付ける方が好ましいけれど、そもそも今まで付いていなかったのだから。

 

 

メニューから[プロジェクト(P)]→[プロパティ(P)]を開き、リンカ→詳細設定の画面へ。

安全な例外ハンドラを含むイメージ/SAFESEH:NOに設定しビルドします。