diff --git a/README.md b/README.md index 4d9a76e..6eb8041 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,11 @@ Experimental CSGO external game exploit. +## Features + +- Trigger Bot (hold shift) +- Bunny Hop (hold space) + ![Screenshot](docs/screenshot.png) ## Usage diff --git a/docs/screenshot.png b/docs/screenshot.png index 8fa46fa..34e40b1 100644 Binary files a/docs/screenshot.png and b/docs/screenshot.png differ diff --git a/gohack_windows.go b/gohack_windows.go index 2520218..05a6d2a 100644 --- a/gohack_windows.go +++ b/gohack_windows.go @@ -2,11 +2,9 @@ package gohack import ( "errors" - "fmt" "github.com/jamesmoriarty/gohack/internal/gohack" "github.com/jamesmoriarty/gomem" log "github.com/sirupsen/logrus" - "strconv" ) var ( @@ -14,14 +12,6 @@ var ( Date string ) -func ToHexString(ptr uintptr) string { - s := fmt.Sprintf("%d", ptr) - n, _ := strconv.Atoi(s) - h := fmt.Sprintf("0x%x", n) - - return h -} - func Instrument() (*gohack.Client, error) { log.SetFormatter(&log.TextFormatter{ForceColors: true}) @@ -42,14 +32,17 @@ func Instrument() (*gohack.Client, error) { return nil, err } log.WithFields(log.Fields{"handle": process.Handle}).Info("OpenProcess ", process.ID) - log.WithFields(log.Fields{"value": ToHexString(client.Address)}).Info("- Address") - log.WithFields(log.Fields{"value": ToHexString(client.OffsetForceJump())}).Info("- OffsetForceJump") - log.WithFields(log.Fields{"value": ToHexString(client.OffsetPlayer())}).Info("- OffsetPlayer") - log.WithFields(log.Fields{"value": ToHexString(client.OffsetPlayerFlags())}).Info("- OffsetPlayerFlags") + log.WithFields(log.Fields{"value": gohack.ToHexString(client.Address)}).Info("- Address") + log.WithFields(log.Fields{"value": gohack.ToHexString(client.OffsetForceJump())}).Info("- OffsetForceJump") + log.WithFields(log.Fields{"value": gohack.ToHexString(client.OffsetForceAttack())}).Info("- OffsetForceAttack") + log.WithFields(log.Fields{"value": gohack.ToHexString(client.OffsetPlayer())}).Info("- OffsetPlayer") + log.WithFields(log.Fields{"value": gohack.ToHexString(client.OffsetPlayerFlags())}).Info("- OffsetPlayerFlags") + log.WithFields(log.Fields{"value": gohack.ToHexString(client.OffsetEntityId())}).Info("- OffsetEntityId") return client, err } func Execute(c *gohack.Client) { + go gohack.RunTrigger(c) gohack.RunBHOP(c) } diff --git a/internal/gohack/bhop.go b/internal/gohack/bhop.go index e9ac99b..f72ba98 100644 --- a/internal/gohack/bhop.go +++ b/internal/gohack/bhop.go @@ -3,6 +3,7 @@ package gohack import ( "github.com/jamesmoriarty/gomem" "time" + "runtime" "unsafe" ) @@ -22,7 +23,10 @@ func RunBHOP(client *Client) { client.Process.Write(client.OffsetForceJump(), writeValuePtr, unsafe.Sizeof(writeValue)) } + // N.B. writing can silently fails so we need to verify the write. I suspect we might need to re-open the process handle. + readValue = 0x0 + client.Process.Read(client.OffsetForceJump(), readValuePtr, unsafe.Sizeof(readValuePtr)) if readValue == 0x0 { @@ -31,5 +35,9 @@ func RunBHOP(client *Client) { } time.Sleep(90) + + // N.B. guard against buffer gc. + runtime.KeepAlive(&readValue) + runtime.KeepAlive(&writeValue) } } diff --git a/internal/gohack/client.go b/internal/gohack/client.go index ba21e7f..1f3b0c9 100644 --- a/internal/gohack/client.go +++ b/internal/gohack/client.go @@ -34,6 +34,10 @@ func (a *Client) OffsetForceJump() uintptr { return a.Address + a.Offsets.Signatures.OffsetdwForceJump } +func (a *Client) OffsetForceAttack() uintptr { + return a.Address + a.Offsets.Signatures.OffsetdwForceAttack +} + func (a *Client) OffsetPlayer() uintptr { var ( readValue uintptr @@ -48,3 +52,14 @@ func (a *Client) OffsetPlayer() uintptr { func (a *Client) OffsetPlayerFlags() uintptr { return a.OffsetPlayer() + a.Offsets.Netvars.Offsetm_fFlags } + +func (a *Client) OffsetEntityId() uintptr { + var ( + readValue uintptr + readValuePtr = (uintptr)(unsafe.Pointer(&readValue)) + ) + + a.Process.Read(a.OffsetPlayer() + a.Offsets.Netvars.Offsetm_iCrosshairId, readValuePtr, 4) + + return readValue +} diff --git a/internal/gohack/offsets.go b/internal/gohack/offsets.go index 2f12dca..12ccf0d 100644 --- a/internal/gohack/offsets.go +++ b/internal/gohack/offsets.go @@ -16,9 +16,11 @@ type Offsets struct { Signatures struct { OffsetdwLocalPlayer uintptr `yaml:"dwLocalPlayer"` OffsetdwForceJump uintptr `yaml:"dwForceJump"` + OffsetdwForceAttack uintptr `yaml:"dwForceAttack"` } `yaml:"signatures"` Netvars struct { Offsetm_fFlags uintptr `yaml:"m_fFlags"` + Offsetm_iCrosshairId uintptr `yaml:"m_iCrosshairId"` } `yaml:"netvars"` } diff --git a/internal/gohack/trigger.go b/internal/gohack/trigger.go new file mode 100644 index 0000000..16f757e --- /dev/null +++ b/internal/gohack/trigger.go @@ -0,0 +1,30 @@ +package gohack + +import ( + "github.com/jamesmoriarty/gomem" + "time" + "runtime" + "unsafe" +) + + +func RunTrigger(client *Client) { + var ( + writeValue = byte(0x6) + writeValuePtr = (uintptr)(unsafe.Pointer(&writeValue)) + ) + + for { + if gomem.IsKeyDown(0x10) { // https://docs.microsoft.com/en-gb/windows/win32/inputdev/virtual-key-codes + if client.OffsetEntityId() > 0 && client.OffsetEntityId() <= 64 { + client.Process.Write(client.OffsetForceAttack(), writeValuePtr, unsafe.Sizeof(writeValue)) + } + } + + time.Sleep(50) + + // N.B. guard against buffer gc. + runtime.KeepAlive(&writeValue) + } + +} diff --git a/internal/gohack/util.go b/internal/gohack/util.go new file mode 100644 index 0000000..10acf47 --- /dev/null +++ b/internal/gohack/util.go @@ -0,0 +1,14 @@ +package gohack + +import ( + "fmt" + "strconv" +) + +func ToHexString(ptr uintptr) string { + s := fmt.Sprintf("%d", ptr) + n, _ := strconv.Atoi(s) + h := fmt.Sprintf("0x%x", n) + + return h +}