如何在GoLang中执行本机指令?

时间:2015-05-26 20:44:23

标签: go shellcode

我想知道如何在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.

由于

1 个答案:

答案 0 :(得分:1)

syscall.Syscall不按你的想法行事。

它产生System Call,调用OS内核函数,而不是任意跳转到某个位置

此外,shellcode需要C调用约定,例如堆栈指针指向C堆栈等。在运行时不满足此条件