在Go

时间:2015-11-18 21:32:28

标签: windows dll go 32bit-64bit wow64

使用Windows,猜测当前32位进程是在32位还是64位架构上运行的官方方式(如此在WOW64上也是如此)是从kernel32.dll调用IsWow64Process函数,并查看它是否存在(据我理解的文档)。

在Go中,我们可以使用syscall包调用dll文件中导出的函数,所以这是我的尝试:

package main

import (
    "fmt"
    "os"
    "syscall"
)

func main() {
    dll, err := syscall.LoadDLL("kernel32.dll")
    if err != nil {
        fmt.Println(err)
    }
    defer dll.Release()
    proc, err := dll.FindProc("IsWow64Process")
    if err != nil {
        fmt.Println("Proc not found") // not a WOW64 so a 32 bit system?
        fmt.Println(err)
    }
    fmt.Printf("%v\n", proc)

    var handle uintptr = uintptr(os.Getpid())

    var result uintptr
    v, x, y := proc.Call(handle, result)

    fmt.Printf("%v %v %v\n", v, x, y)
    fmt.Printf("%v\n", result)
}

不幸的是,使用或不使用WOW64系统的测试在stdout中显示相同的内容:

&{0x10ada110 IsWow64Process 2088961457}
0 7 The handle is invalid.
0

我做错了什么?如何实现测试以确定我们的32位Go程序是在64位CPU(WOW64)上模拟的32位还是在真正的32位Windows上运行?

3 个答案:

答案 0 :(得分:4)

I believe the issue is the handle parameter on your proc.Call. The expected parameter for IsWow64Process is a HANDLE which is not the same as a pid. Which is why it is indicating that the handle is invalid.

The following SO question How to get process handle from process id时,Jquery Ajax调用表示您需要在pid中调用OpenProcess passse并返回句柄。

编辑:GetCurrentProcess在syscall中定义。所以我认为您可以使用以下内容替换Getpid调用:

handle, err := syscall.GetCurrentProcess()

答案 1 :(得分:2)

好的,所以这是一个有效的代码:

package main

import (
    "syscall"
    "fmt"
    "unsafe"
)
func main() {
    dll, err := syscall.LoadDLL("kernel32.dll")
    if err != nil {
        fmt.Println("Can't load kernel32")
        fmt.Println(err)
    }
    defer dll.Release()
    proc, err := dll.FindProc("IsWow64Process")
    if err != nil {
        fmt.Println("Proc not found")
        fmt.Println(err)
    }
    fmt.Printf("%v\n",proc)

    handle, err := syscall.GetCurrentProcess()  
    if err != nil {
        fmt.Println("Handle not found")
        fmt.Println(err)
    }
    fmt.Printf("%v\n",handle)

    var result bool

    v, x, y := proc.Call(uintptr(handle), uintptr(unsafe.Pointer(&result)))

    fmt.Printf("%v %v %v\n",v,x,y)
    fmt.Printf("%v\n",result)
}

对于WOW64系统,result var将为true,对于32位系统则为false。

答案 2 :(得分:0)

您也可以使用True

golang.org/x/sys/windows