Skip to content

HardwareTurningPoint, Fully Go Compatible Hardware Breakpoint

Notifications You must be signed in to change notification settings

almounah/hardwareturningpoint

Repository files navigation

HardwareTurningPoint

hardwaretp

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 Runtime and EXCEPTION_SINGLE_STEP

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:

hardwarebp

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.

Evil-go to the rescue

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.

What is provided in the POC

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.

Examples

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.

Side Story: Why the name HardwareTurningPoint

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.

About

HardwareTurningPoint, Fully Go Compatible Hardware Breakpoint

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages