i know its ugly, but i had to finish it asap.
include 'win64a.inc'
format PE64 console 4.0
UNW_FLAG_EHANDLER = 1
STATUS_BREAKPOINT = 80000003h
EXCEPTION_CONTINUE_SEARCH = 0
virtual at r8
context:
dq 6 dup(?) ; skip p1-6home i have no interest
dd 5 dup(?) ; skip bunch of stuff
.EFlags dd ?
dq 6 dup(?) ; skip debug registers, again im not interested
.Rax dq ?
.Rcx dq ?
.Rdx dq ?
.Rbx dq ?
.Rsp dq ?
.Rbp dq ?
.Rsi dq ?
.Rdi dq ?
.R8 dq ?
.R9 dq ?
.R10 dq ?
.R11 dq ?
.R12 dq ?
.R13 dq ?
.R14 dq ?
.R15 dq ?
.Rip dq ?
; rest of the structure ...
end virtual
section '.text' code readable executable
start_of_main:
enter 20h,0
int3 ; generate breakpoint exception
ret
xor rcx,rcx
and r9,rcx
lea rdx,[_int3_exception]
lea r8,[_seh]
call [MessageBox]
xor rax,rax
add [rax],al ; memory access violation
i_will_terminate_it:
mov ecx,[exception_code]
lea rdx,[_buffer]
mov r8,10h
call [itoa]
xor rcx,rcx
and r9,rcx
lea rdx,[_access_violation]
lea r8,[_seh]
call [MessageBox]
mov eax,0
leave
ret
end_of_main:
int1
int3
main_routine_exception_handler:
; rcx exception code (pointer)
; rdx old stack frame
; r8 context record (stack based)
; r9 exception address (rip)
mov eax,dword [rcx]
mov [exception_code],eax
sub eax,STATUS_BREAKPOINT
jnz i_cant_handle_that
add [context.Rip],2 ; its our breakpoint lets skip over it and over the ret
mov eax,EXCEPTION_CONTINUE_SEARCH
ret
i_cant_handle_that:
mov rsp,rdx
mov rbp,[context.Rbp]
; if its not the main routine, then you may want to restore old register as well
; either from context record or by PUSHing registers before any exception happens
; and POP them here
jmp short i_will_terminate_it
section '.data' data readable writeable
exception_code dd 0
_seh db 'seh',0
_int3_exception db 'int3 exception is skipped',0
_access_violation db 'program must terminate',0Dh,0Ah
_buffer rb 9
section '.rdata' data readable
main_routine_unwind_data dd (UNW_FLAG_EHANDLER shl 3) or 1,rva main_routine_exception_handler
section '.xdata' data readable
data 3
dd rva start_of_main,rva end_of_main,rva main_routine_unwind_data
end data
section '.idata' import data readable writeable
library ntdll,'ntdll.dll',\
user32,'user32.dll'
import ntdll,\
itoa,'_itoa'
import user32,\
MessageBox,'MessageBoxA'