FastCopy v3.20 および IPMsg v4.03以降では、ビルド時の /gs オプションでスタック保護を入れているのだが、これを有効にするとスタック保護違反の場合に例外ハンドラが強制でデフォルトに戻されてしまう。(通常は、解析に必要なダンプを行う自前ハンドラに飛ぶようになっている)
VS2003までは _set_security_error_handler によって自前ハンドラに再セットできたのだが、悪質なウイルスによってはこれを利用する場合があるという話で廃止され、復活の見込みはなさそう。(それにしても、bo検出で汚染コードにジャンプしていない状態で、例外ハンドラ乗っ取りってどうやるのだろう?…terminateせずにcontinueするダメハンドラの場合の問題かな。後で調べておこう(*))
ともあれ、このポリシーは理解できなくもないのだが、だとすると、自前ダンプを有効にするには/gsを外すという後ろ向きの手しか選びづらくなる。
/gsを外すより幾分マシな方法として FastCopy v3.23と IPMsg v4.05で実装したのが、/gsを有効にした上で自己書き換え(SetUnhandledExceptionFilter自体を無効化)する方法(ちなみに両方ともstaticリンク)。
ただ自己書き換えという性質上、VM環境でWinXP(32),Win7~Win10環境(32/64)で問題ないことを確認&Win10(64)ノートン環境でも大丈夫であることを確認しておいた。
ところがリリース後、環境(VMでは確認済みの環境セット)によって稀に例外が発生することがあるらしいという話がイタリアから届く。
例外が発生 or 例外ハンドラ再登録しない限り通らないルーチンなので、この環境では何らかの理由で終了時に例外(しかも標準では刈り取りされうるもの)が発生しているのかもしれない。
今回のリリースでは少し自己書き換えの方法を変えて(SetUnhandledExceptionFilter自体ではなく/gs関連ルーチン内でSetUnhandledExceptionFilter(NULL)のcall部分にnopを入れる形。つまりSetUnhandledExceptionFilterは正常に動作)再実装することに。結果、くだんのイタリア環境では終了時例外は発生しなくなったとのこと。
(もし、問題がある場合は FastCopyの場合、fastcopy2.ini [main] debug_main_flags=1 を設定し、IPMsgの場合は HKEY_CURRENT_USER\Software\HSTools\Debugを1にすると自己書き換えしないようになっています)
(*) 10/20追記
探した範囲では MSDN の_set_security_error_handlerの注意以外に、あまり有益な情報がないように見えるのだが、やはり「ハンドラ内で必ず終了すること。ハンドラから例外を投げたり、継続しようとしたらダメだよ」という話のようだ。
すでにスタックが壊れているので、ハンドラから例外を投げて__except等で例外を受け止めようとしている関数まで巻き戻ろうとすれば、当然、巻き戻し先アドレス変更&実行されたり、途中での自動デストラクタ発動が利用されたり、何でもありの世界になる。
逆に、ハンドラ内でお作法通りdumpとexitするだけなら何の問題もないように思える…ということで、ダメハンドラをセットされる可能性を考慮して、仕組み自体を潰したという話に見える。
(その挙句に/gsをOFFにされる可能性が増えるなら、本末転倒のような気もするけれど(笑))
Categories
Android |
CeSleep |
comp_misc |
comp_tips |
fastcopy |
ipmsg |
mailman |
misc |
npop |
ScheEdit |
sigsleep |
tdiary |
thinkpad