2017-02-13 6 views
0

Я хотел бы распечатать содержимое виртуальной памяти текущей программы от 0x10000 до 0x50000(область, в которой есть батут в центре моей системы).Как fmt.Println() память не выделена программой go?

package main 

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

Однако, когда я пытался скомпилировать я получаю эту ошибку:

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

В моем случае, cgo отключен (import "C" терпит неудачу во время компиляции).
Также делает syscall.Syscall(SYS_WRITE это единственный способ сделать это?

+0

Я знаю, что в голанге. Я знаю, что это можно рассматривать как чтение за пределами границ, но это необходимо для того, чтобы узнать, включен ли какой-либо конкретный системный вызов. – user2284570

ответ

2

Вы можете преобразовать этот адрес в кусок байтов, который затем может быть передан любому методу Write.

Для преобразования адреса 0x10000 среза байт с длиной 0x30000, вы бы использовать

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

Если размер всегда статичен, вы можете просто установить массив нужного размера, чтобы начать

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

Что делает часть [1 << 30] byte'means? – user2284570

+0

@ user2284570: это тип массива с размером '1 << 30' – JimB

+0

Есть ли способ распечатать этот массив без пакета syscall? – user2284570

1

Непосредственная проблема, с которой вы сталкиваетесь, заключается в том, что вы должны преобразовать 0x10000 непосредственно в uintptr, а не через unsafe.Pointer. Я не знаю, будет ли исправление, которое решит остальную часть вашей проблемы или нет.

+0

спасибо, есть ли способ сделать это с помощью 'fmt.Printf()' или 'syscall.Write()' вместо того, чтобы использовать 'syscall.Syscall'directly? – user2284570

+0

Похоже, ответ JimB охватывает его. – andybalholm

Смежные вопросы