doupoji3856 2015-05-26 20:44 采纳率: 100%
浏览 102
已采纳

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

I was wondering how can I execute bytes (shellcode, basically) in GoLang. Anyway I found something that helped me getting started, check the code below:

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
")
}

It works, it executes the NOP and the RET and the program exits sucessfully. The thing is: if I replace b[] with a shellcode (WinExec calc.exe) like this

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

It does not run anymore. Shouldnt it run properly or am I missing something here?

This is the shellcode in C/Python, for reference:

"\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

And the error

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.

Thanks

  • 写回答

1条回答 默认 最新

  • dongying9712 2015-05-27 16:51
    关注

    syscall.Syscall don't do what you think.

    It make a System Call, a call to OS kernel function, not an arbitrary jump to a location

    Moreover the shellcode expect the C calling conventions, for example the stack pointer to be to a C stack etc. this conditions are not fulfilled in go runtime

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥17 pro*C预编译“闪回查询”报错SCN不能识别
  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向