2

My application accepts a pointer from os.Args.

For example

pointer := os.Args[1] //"0x7ffc47e43200"

How can I use that pointer and get the value that is stored on that location?

6
  • 3
    How can you possibly know if that address is even valid? What do you plan to do with the data? Commented Jun 20, 2016 at 13:17
  • @zmb Another application calls this application (not go) with the memory address. Commented Jun 20, 2016 at 13:19
  • 2
    But most operating systems use virtual memory these days, so that other application won't share a virtual address space with the Go app. Commented Jun 20, 2016 at 13:20
  • You can try your luck with the unsafe package, converting from str to int and then casting to an unsafe pointer. Commented Jun 20, 2016 at 13:21
  • 2
    "How can I use that pointer and get the value that is stored on that location?" By writing your own OS. Seriously: You can't and you shouldn't. Commented Jun 20, 2016 at 13:22

1 Answer 1

8

Disclaimer: As you are probably aware, this is dangerous and if you're going to do this in a production application, you'd better have a really good reason. That being said...

You need to do a few things. Here's the code, and then we'll walk through it.

package main

import (
    "fmt"
    "os"
    "strconv"
    "unsafe"
)

func main() {
    str := "7ffc47e43200" // strconv.ParseUint doesn't like a "0x" prefix
    u, err := strconv.ParseUint(str, 16, 64)
    if err != nil {
        fmt.Fprintln(os.Stderr, "could not parse pointer:", err)
        os.Exit(1)
    }

    ptr := unsafe.Pointer(uintptr(u)) // generic pointer (like void* in C)
    intptr := (*int)(ptr)             // typed pointer to int
    fmt.Println(*intptr)
}

You can run this on the Go Playground.

First, we need to parse the string as a numerical value. In your example, you gave a hexadecimal number, so we'll parse in base 16 (that's the "16" argument to strconv.ParseUint). Note that strconv.ParseUint doesn't like the "0x" prefix, so I removed it.

Then, we need to convert the number into a pointer type. For this, we will use the unsafe.Pointer type, which is special to the Go compiler. Normally, the compiler won't let you convert between pointer types. The exception is that, according to the unsafe.Pointer documentation:

  • A pointer value of any type can be converted to a Pointer.
  • A Pointer can be converted to a pointer value of any type.
  • A uintptr can be converted to a Pointer.
  • A Pointer can be converted to a uintptr.

Thus, in order to convert to a pointer, we'll need to first convert to a uintptr and then to an unsafe.Pointer. From here, we can convert to any pointer type we want. In this example, we will convert to an int pointer, but we could choose any other pointer type as well. We then dereference the pointer (which panics in this case).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.