HardwareTurningPoint, is the implementation of the HardwareBreakPoint in pure Go.
The purpose is to trigger an EXCEPTION_SINGLE_STEP, then get control of the thread context in our custom handler. This is will allow us to block function execution and or tamper their parameters and return results.
This is just a POC. However Contributions are welcome if anyone is interested in making this a stable and working Go package.
Go by default, will handle the signal in the Go runtime. As no specific handler is dedicated to hardware breakpoint in the Go runtime (EXCEPTION_SINGLE_STEP), the go runtime default handler will lead to a winthrow
function call.
The stacktrace will be printed and the program will fail. An example is given here, where a hardware breakpoint is launched:
Even if you use AddVectoredExceptionHandler
in your Go code, the behavior will not be as expected. If you are lucky, you may enter in your handler, but you can never continue the excecution flow.
You can check https://github.com/golang/go/blob/master/src/runtime/signal_windows.go#L310. As Go never know you handled your exception, you will go to firstcontinuehandler
then at some point lastcontinuehandler
resulting in the winthrow
.
PS: After discussing on Golang nuts, you may find a way of getting around that using CGO, but I chose a different aproach.
I decided to upgrade my evil-go (a fork of go) in such a way that it tells Go runtime "Ok, there is a EXCEPTION_SINGLE_STEP, chillax, don't use your handler, the exception is already handled elsewhere"
You can check the commit here https://github.com/almounah/evil-go/commit/cbf714b9fc69d64b2f4d6ba0b0854cb578708827#diff-4258ac84502a706905546e3ffd4b998bd4ef187ace40d66cdcfc1a839b265cc7R155
Basically what I am doing, is telling go to not use his firstcontinuehandler
and lastcontinuehandler
, rather I am return directly before. The Exception handler will hopefully be searched elsewhere.
So, if someone want to use HardwareTurningPoint, He or She needs to compile with evil-go
. That works for me because I already use evil-go
everywhere now for generating windows exe.
You import the package:
import (
"hardwareturningpoint"
"hardwareturningpoint/utils/handler"
)
You can then add and remove HardwareTurningPoint on all the threads using:
func SetHardwareTurningPointOnAllCurrentThread(pAddress uintptr, DRX int)
func RemoveHardwareTurningPointOnAllThread(DRX int)
Then you can create a Handler and Register it. The handler is a custom function you write in Go. It needs to have this signature:
func HandlerBlockExecution(exceptionInfo *handler.EXCEPTION_POINTERS) uintptr {
// You code here.
}
// Register Handler
handler.AddVEH(HandlerBlockExecution)
Inside your handler, you can:
// Block Function Execution (this will search for the nearest Ret and set the RIP to it)
func BLOCK_REAL(ctx *winapi.CONTEXT)
// Get and Set Argument
func GetArgument(ctx *winapi.CONTEXT, argnum int) uintptr
func SetArgument(ctx *winapi.CONTEXT, value uintptr, argnum int)
// Continue Execution, this will set the Resume Flag to 1
func CONTINUE_EXECUTION(ctx *winapi.CONTEXT)
// Set the return value
func SET_RETURN_VALUE(ctx *winapi.CONTEXT, value uintptr)
Kudos to mr.d0x and VX-Underground for their hardwarebreakpoint implementation that inspired HardwareTurningPoint.
Full examples are given in examples/messagebox/main.go
You compile with
GOOS=windows GOARCH=amd64 /home/kali/Desktop/crazy/go-linux-amd64-bootstrap/bin/go build -trimpath -ldflags="-s -w" examples/messagebox/main.go
Basically, I am adding a HardwareTurningPoint on MessageBoxW
by populating DR1.
In the first case, I am adding a handler that Blocks MessageBoxW
. So it won't be executed even when calling it.
Then, I am adding a handler that Tamper MessageBoxW
argument. So the text message will be changed.
At the end I am removing the HardwareTurningPoint and running MessageBoxW
normally.
In Mushoku Tensei, a Turning Point is a critical event that significantly alters the story's direction. There are four major Turning Points (TP1, TP2, TP3, and TP4) in the saga, each marking a moment where the narrative takes an unexpected and irreversible shift.
I named this project HardwareTurningPoint because these Turning Points (TP1, TP2, TP3, TP4) reminded me of the hardware debug registers DR0, DR1, DR2, and DR3. Just as each Turning Point in Mushoku Tensei disrupts the protagonist's expected path, HardwareTurningPoint shifts a program’s normal execution flow by redirecting it to a custom Vectored Exception Handler.