SEH、構造化例外処理のテスト
try ... catch() や __try ... __except() を使用できれば、そちらが簡単。
#include <stdio.h> #include <windows.h> LONG CALLBACK ExceptionHandler(EXCEPTION_POINTERS *ExceptionInfo) { printf("ExceptionHandler\n"); // c で次の命令へのアドレスを取得する方法が現在の所は不明。 ExceptionInfo->ContextRecord->Eip += 10; // 例外が発生した次の命令へ飛ばす return(EXCEPTION_CONTINUE_EXECUTION); } int main() { printf("null pointer exception\n"); SetUnhandledExceptionFilter(ExceptionHandler); *(int*)0 = 0x12345678; printf("end.\n\n"); return 0; }
インラインアセンブラで fs:[0] を使用する
#include <stdio.h> #include <windows.h> // __cdecl __stdcall のどちらでも動作したけれど、要確認 int __cdecl exception(EXCEPTION_RECORD *lpException, DWORD *lpFrame, CONTEXT *lpContext, DWORD* lpDispatch) { printf("ExceptionHandler\n"); context->Eip = context->Edx; return ExceptionContinueExecution; } int main() { printf("null pointer exception\n"); __asm { xor ebx,ebx mov eax, exception push eax push fs:[ebx] mov fs:[ebx], esp mov edx, offset nextstep // edx にジャンプ先アドレスを格納 xor ebx, ebx mov dword ptr [ebx], 12345678h nextstep: xor ebx, ebx mov eax, [esp] mov fs:[ebx], eax add esp, 8 } printf("end.\n\n"); return 0; }