MOV EAX, F0450569
LEA ECX, DWORD PTR DS:[EAX+1000129E] ; ecx will be 00451807
MOV DWORD PTR DS:[ECX+1], EAX ; 451808 will hold f0450569
MOV EDX, DWORD PTR SS:[ESP+4] ; ExceptionRecord
MOV EDX, DWORD PTR DS:[EDX+C] ; ExceptionRecord->ExceptionAddress == 401016
MOV BYTE PTR DS:[EDX], 0E9 ; byte@exceptionAddress to e9 five byte jump
ADD EDX, 5 ; ExceptionAddress+5 ==40101b
SUB ECX, EDX ; 451807-edx = 507ec
MOV DWORD PTR DS:[EDX-4], ECX ; assembles jmp 507ec @exception address
XOR EAX, EAX ; retn 0 == exception has been handled
RETN ; 401016 == jmp 507ec instead of mov [eax],ecx
由于异常处理程序不会修改 eip 而是更改旧 eip 的操作码,您最终将执行相同的旧 eip
纯巧合
通常您应该在退出 seh 处理程序之前检查 ContextRecord->Eip 这包含将在 retun 时执行的 eip从内核检查 [[ESP+C]+0XB8] 在 retn 上查看 seh 处理程序中的 Context->Eip
您还可以在 ntdll.NtContinue 中设置断点,这是
在命中时在 seh 出口上跨越 um->km 边界的函数,您可以在 CONTEXT->Eip 上设置 bp(x86 32 位上的 xxx* + 0xb8)