使用Golang创建作弊工具的实用指南

使用Golang创建作弊工具的实用指南 大家好,我打算用Go语言创建一个作弊程序,为此我需要了解一些信息:

是否有可能像在C++中那样进行内存的读取和写入。

类似下面这样的C++代码:

HWND hwnd = FindWindowA(NULL, "mywindow");

在Go语言中是否也有效?

6 回复

我想知道Go语言是否适合用于游戏黑客。

更多关于使用Golang创建作弊工具的实用指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我仍然认为我们不清楚您想要做什么。您可能可以使用Go,但我怀疑您可能也可以使用C、C++或Python。如果您能把问题描述得更具体一些,我们就能给您一个更好的答案。

不。 如果你想制作作弊工具,Golang 并不合适。 作弊工具需要写入内存,这不仅仅是使用 Windows API 那么简单。 Golang 有指针,但它与 C++ 的指针不同。 Go 无法直接操作内存。

Evadoys_12:

HWND hwnd = FindWindowA(NULL, “mywindow”);

如果你指的是这个函数,它

检索其类名和窗口名与指定字符串匹配的顶级窗口的句柄。此函数不搜索子窗口。此函数不执行区分大小写的搜索。

我认为这是用于 Windows 的 C++ 代码,与 Go 完全无关。

但这个问题与 Go 可能存在的作弊行为有什么关系呢?

在我上次开发一个寻求零字节内存删除的密码学库时,我可以分享一下我的发现:使用 C 或 C++ 会更好。第二种选择是通过 cgo 进行集成,然后使用 C/C++ 在非常底层的领域管理那些内存位置。

我接触过的与底层内存最接近的方法是:https://stackoverflow.com/questions/39968084/is-it-possible-to-zero-a-golang-strings-memory-safely

我很好奇,并且愿意学习 Go 中可用的其他选项,所以也请其他人指点一下。

在Go语言中直接调用Windows API进行内存操作是可行的,但需要使用系统调用和适当的包。以下是实现内存读取写入的示例:

package main

import (
    "fmt"
    "syscall"
    "unsafe"
)

var (
    kernel32 = syscall.NewLazyDLL("kernel32.dll")
    user32   = syscall.NewLazyDLL("user32.dll")
    
    procFindWindowA        = user32.NewProc("FindWindowA")
    procOpenProcess        = kernel32.NewProc("OpenProcess")
    procReadProcessMemory  = kernel32.NewProc("ReadProcessMemory")
    procWriteProcessMemory = kernel32.NewProc("WriteProcessMemory")
    procCloseHandle        = kernel32.NewProc("CloseHandle")
)

const (
    PROCESS_ALL_ACCESS = 0x1F0FFF
)

func FindWindowA(className, windowName string) (uintptr, error) {
    var cClassName, cWindowName uintptr
    if className != "" {
        cClassName = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(className)))
    }
    if windowName != "" {
        cWindowName = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(windowName)))
    }
    
    ret, _, err := procFindWindowA.Call(cClassName, cWindowName)
    if ret == 0 {
        return 0, err
    }
    return ret, nil
}

func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (uintptr, error) {
    inherit := 0
    if inheritHandle {
        inherit = 1
    }
    
    ret, _, err := procOpenProcess.Call(
        uintptr(desiredAccess),
        uintptr(inherit),
        uintptr(processId),
    )
    if ret == 0 {
        return 0, err
    }
    return ret, nil
}

func ReadProcessMemory(processHandle uintptr, baseAddress uintptr, buffer []byte, size uintptr) (bool, error) {
    var bytesRead uintptr
    
    ret, _, err := procReadProcessMemory.Call(
        processHandle,
        baseAddress,
        uintptr(unsafe.Pointer(&buffer[0])),
        size,
        uintptr(unsafe.Pointer(&bytesRead)),
    )
    
    if ret == 0 {
        return false, err
    }
    return true, nil
}

func WriteProcessMemory(processHandle uintptr, baseAddress uintptr, data []byte, size uintptr) (bool, error) {
    var bytesWritten uintptr
    
    ret, _, err := procWriteProcessMemory.Call(
        processHandle,
        baseAddress,
        uintptr(unsafe.Pointer(&data[0])),
        size,
        uintptr(unsafe.Pointer(&bytesWritten)),
    )
    
    if ret == 0 {
        return false, err
    }
    return true, nil
}

func CloseHandle(handle uintptr) error {
    ret, _, err := procCloseHandle.Call(handle)
    if ret == 0 {
        return err
    }
    return nil
}

func main() {
    // 查找窗口
    hwnd, err := FindWindowA("", "mywindow")
    if err != nil {
        fmt.Printf("查找窗口失败: %v\n", err)
        return
    }
    fmt.Printf("找到窗口句柄: 0x%X\n", hwnd)
    
    // 获取进程ID(需要额外的API调用)
    // 这里假设你已经有了进程ID
    processID := uint32(1234) // 替换为实际进程ID
    
    // 打开进程
    processHandle, err := OpenProcess(PROCESS_ALL_ACCESS, false, processID)
    if err != nil {
        fmt.Printf("打开进程失败: %v\n", err)
        return
    }
    defer CloseHandle(processHandle)
    
    // 读取内存示例
    baseAddress := uintptr(0x12345678) // 替换为实际地址
    buffer := make([]byte, 4)
    
    success, err := ReadProcessMemory(processHandle, baseAddress, buffer, 4)
    if success {
        fmt.Printf("读取到的值: %v\n", buffer)
    }
    
    // 写入内存示例
    data := []byte{0x90, 0x90, 0x90, 0x90} // NOP指令
    success, err = WriteProcessMemory(processHandle, baseAddress, data, 4)
    if success {
        fmt.Println("内存写入成功")
    }
}

对于更高级的操作,可以使用golang.org/x/sys/windows包:

package main

import (
    "fmt"
    "golang.org/x/sys/windows"
)

func main() {
    // 使用windows包查找窗口
    hwnd, err := windows.FindWindow(nil, windows.StringToUTF16Ptr("mywindow"))
    if err != nil {
        fmt.Printf("查找窗口失败: %v\n", err)
        return
    }
    fmt.Printf("窗口句柄: %v\n", hwnd)
    
    // 打开进程
    processHandle, err := windows.OpenProcess(
        windows.PROCESS_ALL_ACCESS,
        false,
        1234, // 进程ID
    )
    if err != nil {
        fmt.Printf("打开进程失败: %v\n", err)
        return
    }
    defer windows.CloseHandle(processHandle)
    
    // 内存操作需要继续使用ReadProcessMemory和WriteProcessMemory系统调用
}

注意:实际使用时需要处理错误检查、权限问题,并确保遵守相关法律法规。

回到顶部