gpt4 book ai didi

go - 在 Go 中执行字节数组

转载 作者:IT王子 更新时间:2023-10-29 00:36:58 25 4
gpt4 key购买 nike

我正在尝试在 Go 程序中执行 shellcode,类似于使用其他语言执行此操作的方式。

示例 1 - Shellcode in C program

示例 2 - http://www.debasish.in/2012/04/execute-shellcode-using-python.html

所有方法都有大致相似的技术 - 通过操作系统特定分配(mmap、virtualalloc 等)将 shellcode 分配给可执行内存,然后通过在执行前创建指向该位置的函数指针来执行代码。

这是我在 Go 中执行相同操作的可怕 hacky 示例。 shellcode 在传递给函数之前对其进行了操作,因此它的格式为 []byte 是固定的。说 mmap 需要传入一个文件描述符,这就是为什么存在可怕的“写入 tmp 文件”部分的原因。

func osxExec(shellcode []byte) {
f, err := os.Create("data/shellcode.tmp")
if err != nil {
fmt.Println(err)
}
defer f.Close()
_,_ = f.Write(shellcode)
f.Sync()

b, err := syscall.Mmap(int(f.Fd()), 0, len(shellcode), syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC, syscall.MAP_SHARED)
if err != nil {
fmt.Println(err)
}

fmt.Printf("%p", b)
}

在代码的末尾,我有一个指针( slice ?)指向我认为是可执行内存中的代码 - 但我不知道如何将此地址转换为函数指针以供执行。我在一些 IRC channel 上询问过,但有人建议这可能是不可能的。

非常感谢任何帮助。

干杯。

最佳答案

首先,您根本不需要(当前)使用 mmap,因为 go 内存是可执行的。如果你确实需要 mmap,你可以使用匿名内存并放弃临时文件:

b, e := syscall.Mmap(0, 0, len(shellcode), syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC, syscall.MAP_ANON)
copy(b, shellcode)

否则,您可以尝试直接使用 shellcode,因为它已经由连续数组支持。

至于将 shellcode 中的字节转换为一个函数,C 中的模拟如下所示:

f := *(*func() int)(unsafe.Pointer(&d[0]))

它创建一个名为 f 的函数值,然后可以像普通函数一样调用它。

如果 shellcode 不是专门为 Go 编写的,并且您需要从 C 堆栈调用它,那么使用 cgo 直接在 C 中调用它会更容易。

/*
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])))

关于go - 在 Go 中执行字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30263520/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com