Чтение памяти другого процесса (linux) в golang

Я пытаюсь сделать консольную версию "чит-движка", это программа, в которой пользователь может найти и изменить любые байты / байты памяти в каком-то другом процессе. Для обучения моим навыкам го я выбрал этот язык. Однако я столкнулся с некоторыми трудностями. Во-первых, я хотел бы задать несколько вопросов не о golang, а о чтении памяти процесса в linux:

  1. Могу ли я прочитать память, используя только ptrace без чтения / proc / $ pid / mem?
  2. Как узнать начальный и конечный адреса процесса без чтения / proc / $ pid / maps?
  3. Если я могу найти начальный и конечный адреса из / proc / $ pid / maps, какой раздел мне выбрать?

Возвращаясь к Голангу, я нашел 2 библиотеки, которые предоставляют оболочку системных вызовов и ptrace: https://godoc.org/github.com/hjr265/ptrace.go/ptrace https://gowalker.org/github.com/tfogal/ptrace

Обе эти библиотеки используют uintptr как тип адреса, где вы можете читать данные из памяти. Но когда я ввожу адрес, он имеет тип int64. Как я могу привести его из int64 в uintptr? Если я скомпилирую программу с жестко закодированным значением адреса, она будет работать нормально. Но, если я использую переменную для этого, я получил ошибку.

Мой черновой вариант программы:

package main

import (
    "fmt"
    "os"
    "strconv"
    "log"
    "github.com/tfogal/ptrace"
)

func findValueInProcessMemory(pid int) {
    _, err := os.FindProcess(pid)

    if err != nil {
        fmt.Printf("Error opening process: %v\n", err)
        panic("FindProcess")
    }

    t, err := ptrace.Attach(pid)

    if err != nil {
        fmt.Printf("Error attaching to process: %v\n", err)
        panic("AttachProcess")
    }
    fmt.Printf("Process [%d] attached.\n", pid)

    var startAddr uintptr = 0x00400000;
    wd, err := t.ReadWord(startAddr) // THIS WORKS FINE

    if err != nil {
        log.Fatalf("Could not read first word of program image: %v\n", err)
    }
    fmt.Printf("We've found value: %d at 0x00400000.\n", wd)

    /*
    for addr := start; addr < end; addr += searchValLen {
        res, err := t.ReadWord(addr) // HERE IS AN ISSUE WITH READING MEMORY
        resInt := int64(res)

        if err != nil {
            log.Fatalf("Read error: %s\n", err.Error())
        }

        if resInt == searchVal {
            fmt.Printf("Value found at [0x%x].\n", addr)
        }
    }
    */

    err = t.Detach()

    if err != nil {
        log.Fatalf("Detach error: %s\n", err.Error())
    }
    fmt.Printf("Process [%d] detached.\n", pid)
}

func main() {
    pid, err := strconv.Atoi(os.Args[1])
    if err != nil {
        fmt.Printf("Error getting process id: %v\n", err)
    }

    start, err := strconv.ParseInt(os.Args[2], 0, 32)
    if err != nil {
        fmt.Printf("Error getting start address: %v\n", err)
    }

    end, err := strconv.ParseInt(os.Args[3], 0, 32)
    if err != nil {
        fmt.Printf("Error getting end address: %v\n", err)
    }

    searchVal, err := strconv.ParseInt(os.Args[4], 0, 32)
    if err != nil {
        fmt.Printf("Error getting search value: %v\n", err)
    }

    searchValLen, err := strconv.ParseInt(os.Args[5], 0, 32)
    if err != nil {
        fmt.Printf("Error getting length of search value: %v\n", err)
    }

    fmt.Printf("Process id: %v\n", pid)
    fmt.Printf("Start addr: %v\n", start)
    fmt.Printf("End addr: %v\n", end)
    fmt.Printf("Search value: %v\n", searchVal)
    fmt.Printf("Length of search value: %v\n", searchValLen)

    findValueInProcessMemory(pid)
}

Команда для запуска: ./test 26484 0x400000 0x401000 125 1

0 ответов

Другие вопросы по тегам