Executing Byte Array in Go
First, you don't need to (currently) use mmap
at all, since go memory is executable. If you do need mmap
, you can use anonymous memory and forgo the temp file:
b, e := syscall.Mmap(0, 0, len(shellcode), syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC, syscall.MAP_ANON)
copy(b, shellcode)
Otherwise, you can try to use shellcode
directly, since it's already backed by a contiguous array.
As for converting the bytes in shellcode
to a function, the analog from C would look like:
f := *(*func() int)(unsafe.Pointer(&d[0]))
which creates a function value named f
which can then be called like a normal function.
If the shellcode isn't specifically crafted fro Go, and you need to call it from a C stack, it would be easier to do it directly in C using cgo.
/*
call(char *code) {
int (*ret)() = (int(*)())code;
ret();
}
*/
import "C"
func main() {
...
// at your call site, you can send the shellcode directly to the C
// function by converting it to a pointer of the correct type.
C.call((*C.char)(unsafe.Pointer(&shellcode[0])))
There are multiple ways to do it, though I have not tested them myself.
You may want to have a look at https://github.com/nelhage/gojit/blob/master/jit.go It implements a solution based on cgo (which is safer, but slower), and a solution based on a direct call. Look at all the build related functions.