Created
June 8, 2023 11:58
-
-
Save zimnyaa/d2d6a7ac8ce4c821be902fde60ca43ec to your computer and use it in GitHub Desktop.
Golang VEH example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"syscall" | |
"golang.org/x/sys/windows" | |
"C" | |
"time" | |
) | |
const ( | |
_EXCEPTION_CONTINUE_EXECUTION = 0xffffffff | |
_EXCEPTION_CONTINUE_SEARCH = 0x0 | |
_EXCEPTION_ACCESS_VIOLATION = 0xc0000005 | |
) | |
type exceptionpointers struct { | |
record *exceptionrecord | |
context *context | |
} | |
type m128a struct { | |
low uint64 | |
high int64 | |
} | |
type context struct { | |
p1home uint64 | |
p2home uint64 | |
p3home uint64 | |
p4home uint64 | |
p5home uint64 | |
p6home uint64 | |
contextflags uint32 | |
mxcsr uint32 | |
segcs uint16 | |
segds uint16 | |
seges uint16 | |
segfs uint16 | |
seggs uint16 | |
segss uint16 | |
eflags uint32 | |
dr0 uint64 | |
dr1 uint64 | |
dr2 uint64 | |
dr3 uint64 | |
dr6 uint64 | |
dr7 uint64 | |
rax uint64 | |
rcx uint64 | |
rdx uint64 | |
rbx uint64 | |
rsp uint64 | |
rbp uint64 | |
rsi uint64 | |
rdi uint64 | |
r8 uint64 | |
r9 uint64 | |
r10 uint64 | |
r11 uint64 | |
r12 uint64 | |
r13 uint64 | |
r14 uint64 | |
r15 uint64 | |
rip uint64 | |
anon0 [512]byte | |
vectorregister [26]m128a | |
vectorcontrol uint64 | |
debugcontrol uint64 | |
lastbranchtorip uint64 | |
lastbranchfromrip uint64 | |
lastexceptiontorip uint64 | |
lastexceptionfromrip uint64 | |
} | |
type exceptionrecord struct { | |
exceptioncode uint32 | |
exceptionflags uint32 | |
exceptionrecord *exceptionrecord | |
exceptionaddress uintptr | |
numberparameters uint32 | |
exceptioninformation [15]uintptr | |
} | |
func vehHandler(ep *exceptionpointers) uintptr { | |
fmt.Printf("ep: %+v\n", ep) | |
fmt.Printf("er: %+v\n", ep.record) | |
if ep.record.exceptioncode == _EXCEPTION_ACCESS_VIOLATION { | |
fmt.Printf("got _EXCEPTION_ACCESS_VIOLATION in a separate thread\n") | |
kernel32 := windows.NewLazySystemDLL("kernel32.dll") | |
exitt := kernel32.NewProc("ExitThread") | |
exitt.Call(uintptr(0)) | |
return _EXCEPTION_CONTINUE_EXECUTION // never reached | |
} | |
return _EXCEPTION_CONTINUE_SEARCH | |
} | |
func main() { | |
kernel32 := windows.NewLazySystemDLL("kernel32.dll") | |
addveh := kernel32.NewProc("AddVectoredExceptionHandler") | |
vehcallback := syscall.NewCallback(vehHandler) | |
addveh.Call(uintptr(2), vehcallback) | |
go syscall.SyscallN(uintptr(0), uintptr(0)) | |
time.Sleep(1 * time.Second) | |
fmt.Printf("main thread is alive, but the runtime is now fucked in unforseeable ways") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment