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;
}

アセンブラではよいけれど、マシン語環境でハンドラ関数のアドレスの扱い方が今後の課題