如何在 GoLang 中执行本机指令?
How can I execute native instructions in GoLang?
我想知道如何在 GoLang 中执行字节(基本上是 shellcode)。无论如何,我找到了一些可以帮助我入门的东西,请查看下面的代码:
package main
import (
"fmt"
"log"
"syscall"
"unsafe"
)
const (
MEM_COMMIT = 0x1000
MEM_RESERVE = 0x2000
PAGE_EXECUTE_READWRITE = 0x40
)
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
VirtualAlloc = kernel32.MustFindProc("VirtualAlloc")
)
func SysAlloc(n uintptr) (uintptr, error) {
addr, _, err := VirtualAlloc.Call(0, n, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE)
if addr == 0 {
return 0, err
}
return addr, nil
}
func mkprog() error {
const size = 64 * 1024
addr, err := SysAlloc(size)
if err != nil {
return err
}
b := (*[size]byte)(unsafe.Pointer(addr))
b[0] = 0xc3 // RET
b[1] = 0x90 // NOP
syscall.Syscall(addr, 0, 0, 0, 0)
return nil
}
func main() {
err := mkprog()
if err != nil {
log.Fatal(err)
}
fmt.Printf("HELLO\n")
}
成功了,执行了NOP和RET,程序成功退出。
问题是:如果我用这样的 shellcode (WinExec calc.exe) 替换 b[]
b[0] = 0x33
b[1] = 0xc0
b[2] = 0x50
b[3] = 0x68
b[4] = 0x2E
b[5] = 0x65
b[6] = 0x78
b[7] = 0x65
b[8] = 0x68
b[9] = 0x63
b[10] = 0x61
b[11] = 0x6C
b[12] = 0x63
b[13] = 0x8B
b[14] = 0xC4
b[15] = 0x6A
b[16] = 0x01
b[17] = 0x50
b[18] = 0xBB
b[19] = 0xED
b[20] = 0x2A
b[21] = 0x86
b[22] = 0x7C
b[23] = 0xFF
b[24] = 0xD3
它不再 运行。它不应该 运行 正确还是我在这里遗漏了什么?
这是C/Python中的shellcode,供参考:
"\x33\xc0" # XOR EAX,EAX
"\x50" # PUSH EAX => padding for lpCmdLine
"\x68\x2E\x65\x78\x65" # PUSH ".exe"
"\x68\x63\x61\x6C\x63" # PUSH "calc"
"\x8B\xC4" # MOV EAX,ESP
"\x6A\x01" # PUSH 1
"\x50" # PUSH EAX
"\xBB\xED\x2A\x86\x7C" # MOV EBX,kernel32.WinExec
"\xFF\xD3" # CALL EBX
错误
Exception 0xc0000005 0x8 0x7c862aed 0x7c862aed
PC=0x7c862aed
signal arrived during cgo execution
main.mkprog(0x0, 0x0)
C:/Users/guitmz/Documents/Go_test4/test_4.go:64 +0xfe
main.main()
C:/Users/guitmz/Documents/Go_test4/test_4.go:69 +0x2e
goroutine 2 [runnable]:
runtime.forcegchelper()
c:/go/src/runtime/proc.go:90
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
goroutine 3 [runnable]:
runtime.bgsweep()
c:/go/src/runtime/mgc0.go:82
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
goroutine 4 [runnable]:
runtime.runfinq()
c:/go/src/runtime/malloc.go:712
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
rax 0x7fe10
rbx 0x7c862aed
rcx 0x0
rdx 0x0
rdi 0x7ff5ffffd000
rsi 0xc082021ec0
rbp 0x569ae0
rsp 0x7fdf8
r8 0x0
r9 0x50
r10 0x8
r11 0x4d5520
r12 0x3d
r13 0x0
r14 0x0
r15 0x0
rip 0x7c862aed
rflags 0x10246
cs 0x33
fs 0x53
gs 0x2b
Error: process exited with code 2.
谢谢
syscall.Syscall
不要随心所欲
它调用 System Call 内核函数,而不是任意跳转到某个位置
此外,shellcode 期望 C 调用约定,例如堆栈指针指向 C 堆栈等。go 运行时不满足此条件
我想知道如何在 GoLang 中执行字节(基本上是 shellcode)。无论如何,我找到了一些可以帮助我入门的东西,请查看下面的代码:
package main
import (
"fmt"
"log"
"syscall"
"unsafe"
)
const (
MEM_COMMIT = 0x1000
MEM_RESERVE = 0x2000
PAGE_EXECUTE_READWRITE = 0x40
)
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
VirtualAlloc = kernel32.MustFindProc("VirtualAlloc")
)
func SysAlloc(n uintptr) (uintptr, error) {
addr, _, err := VirtualAlloc.Call(0, n, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE)
if addr == 0 {
return 0, err
}
return addr, nil
}
func mkprog() error {
const size = 64 * 1024
addr, err := SysAlloc(size)
if err != nil {
return err
}
b := (*[size]byte)(unsafe.Pointer(addr))
b[0] = 0xc3 // RET
b[1] = 0x90 // NOP
syscall.Syscall(addr, 0, 0, 0, 0)
return nil
}
func main() {
err := mkprog()
if err != nil {
log.Fatal(err)
}
fmt.Printf("HELLO\n")
}
成功了,执行了NOP和RET,程序成功退出。 问题是:如果我用这样的 shellcode (WinExec calc.exe) 替换 b[]
b[0] = 0x33
b[1] = 0xc0
b[2] = 0x50
b[3] = 0x68
b[4] = 0x2E
b[5] = 0x65
b[6] = 0x78
b[7] = 0x65
b[8] = 0x68
b[9] = 0x63
b[10] = 0x61
b[11] = 0x6C
b[12] = 0x63
b[13] = 0x8B
b[14] = 0xC4
b[15] = 0x6A
b[16] = 0x01
b[17] = 0x50
b[18] = 0xBB
b[19] = 0xED
b[20] = 0x2A
b[21] = 0x86
b[22] = 0x7C
b[23] = 0xFF
b[24] = 0xD3
它不再 运行。它不应该 运行 正确还是我在这里遗漏了什么?
这是C/Python中的shellcode,供参考:
"\x33\xc0" # XOR EAX,EAX
"\x50" # PUSH EAX => padding for lpCmdLine
"\x68\x2E\x65\x78\x65" # PUSH ".exe"
"\x68\x63\x61\x6C\x63" # PUSH "calc"
"\x8B\xC4" # MOV EAX,ESP
"\x6A\x01" # PUSH 1
"\x50" # PUSH EAX
"\xBB\xED\x2A\x86\x7C" # MOV EBX,kernel32.WinExec
"\xFF\xD3" # CALL EBX
错误
Exception 0xc0000005 0x8 0x7c862aed 0x7c862aed
PC=0x7c862aed
signal arrived during cgo execution
main.mkprog(0x0, 0x0)
C:/Users/guitmz/Documents/Go_test4/test_4.go:64 +0xfe
main.main()
C:/Users/guitmz/Documents/Go_test4/test_4.go:69 +0x2e
goroutine 2 [runnable]:
runtime.forcegchelper()
c:/go/src/runtime/proc.go:90
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
goroutine 3 [runnable]:
runtime.bgsweep()
c:/go/src/runtime/mgc0.go:82
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
goroutine 4 [runnable]:
runtime.runfinq()
c:/go/src/runtime/malloc.go:712
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
rax 0x7fe10
rbx 0x7c862aed
rcx 0x0
rdx 0x0
rdi 0x7ff5ffffd000
rsi 0xc082021ec0
rbp 0x569ae0
rsp 0x7fdf8
r8 0x0
r9 0x50
r10 0x8
r11 0x4d5520
r12 0x3d
r13 0x0
r14 0x0
r15 0x0
rip 0x7c862aed
rflags 0x10246
cs 0x33
fs 0x53
gs 0x2b
Error: process exited with code 2.
谢谢
syscall.Syscall
不要随心所欲
它调用 System Call 内核函数,而不是任意跳转到某个位置
此外,shellcode 期望 C 调用约定,例如堆栈指针指向 C 堆栈等。go 运行时不满足此条件