0

I’d like to print the virtual memory content of the current program from 0x10000 to 0x50000 (an area containing a syscall trampoline on my system).

package main

import (
    "syscall"
    "unsafe"
)
func main() {
    syscall.Syscall(SYS_WRITE, uintptr(1), uintptr(unsafe.Pointer(0x10000)), uintptr(0x40000))
}

However when I tried to compile I’m getting that error :

cannot convert 65536 (type int) to type unsafe.Pointer

In my case,cgo is disabled (import "C" fails at compile time).
Also does syscall.Syscall(SYS_WRITE is the only way to do it ?

user2284570
  • 2,891
  • 3
  • 26
  • 74
  • I am knew in golang. I know this is can be considered as out of bounds reads, but this is required to know if a particular system call is enabled. – user2284570 Feb 13 '17 at 17:13

2 Answers2

2

You can convert that address to a slice of bytes, which can then be passed to any Write method.

To convert the address 0x10000 to a slice of bytes with a length of 0x30000, you would use

mem := (*[1 << 30]byte)(unsafe.Pointer(uintptr(0x10000)))[:0x30000:0x30000]

If the size is always static, you could just set the array to the proper size to start

mem := (*[0x30000]byte)(unsafe.Pointer(uintptr(0x10000)))[:]
JimB
  • 104,193
  • 13
  • 262
  • 255
  • What does the part`[1 << 30]byte`means ? – user2284570 Feb 13 '17 at 17:59
  • @user2284570: that's an array type with a size of `1<<30` – JimB Feb 13 '17 at 18:01
  • Is there a way to print that kind of array without the syscall package ? – user2284570 Feb 13 '17 at 21:59
  • @user2284570: You can't print _anything_ without the syscall package, because writing to a file descriptor requires a syscall. Or are you asking how to write the data to stdout/stderr without importing syscall yourself? e.g. `os.Stdout.Write(mem)`? – JimB Feb 13 '17 at 22:04
  • Yes, I need something that can be used with the`fmt`package. You should noticed that I was using the number`1`as file descriptor in my question. – user2284570 Feb 13 '17 at 22:05
  • A slice can be use with the format package, what is it you expect to see by printing the binary memory contents? – JimB Feb 13 '17 at 22:12
  • Hemmm thanks, finally it appears the unsafe package isn’t available`bad import "unsafe" in main.go`. This what I feared. – user2284570 Feb 13 '17 at 22:13
  • Is there a way without the `unsafe` `syscall` and `cgo` package ? – user2284570 Feb 13 '17 at 22:33
  • @user2284570: Go is a memory safe language, you can't read arbitrary memory without specifically using the unsafe package (or a syscall to do it for you) – JimB Feb 13 '17 at 22:34
1

The immediate problem you are facing is that you should convert 0x10000 directly to uintptr instead of through unsafe.Pointer. I don't know if fixing that will solve the rest of your problem or not.

andybalholm
  • 15,395
  • 3
  • 37
  • 41