【问题标题】:Go syscall EnumProcessModulesGo 系统调用 EnumProcessModules
【发布时间】:2015-12-19 19:35:29
【问题描述】:

我正在尝试调用 ;EnumProcessModules;使用给定句柄的 Go

var (
    psapi = syscall.NewLazyDLL("Psapi.dll")
    procEnumProcessModules = psapi.NewProc("EnumProcessModules")
)

func EnumProcessModules(handle uintptr) {
    log.Println(handle)
    modules := make([]interface{}, 2049)
    var needed int
    procEnumProcessModules.Call(
        handle,
        uintptr(unsafe.Pointer(&modules)),
        uintptr(2048),
        uintptr(unsafe.Pointer(&needed)),
    )
    log.Println(needed)
    for i := 0; i < needed; i++ {
        log.Println(modules[i])
    }
}

一切似乎都正常...需要设置,但是当我尝试访问模块变量时,我收到以下错误:

unexpected fault address 0x12d0000
fatal error: fault
[signal 0xc0000005 code=0x0 addr=0x12d0000 pc=0x455b56]

模块数组应该是什么样子的?

【问题讨论】:

  • 根据 EnumProcessModules 文档,模块是句柄数组。所以它应该是模块 := make(syscall.Handle, 2049)。 EnumProcessModules 的最后一个参数是 *uint32,所以你的“需要”变量应该是 uint32,而不是 int。 int 没有固定大小(在 386 上是 int32,在 amd64 上是 int64)。
  • 您将切片指针传递给对切片一无所知的 Windows 函数。你需要使用数组或者使用第一个元素的地址。

标签: go system-calls


【解决方案1】:

是的,您必须引用第一个元素。

var n uint32
var needed uint32

// How many I need?
ret, _, _ := procEnumProcessModules.Call(
  uintptr(handle),
  0,
  uintptr(n),
  uintptr(unsafe.Pointer(&needed)))

if int(ret) == 1 && needed > 0 {

  procHandles := make([]syscall.Handle, needed) 
  procHandlesPtr := unsafe.Pointer(&procHandles[0])

  n = needed
  ret2, _, _ := procEnumProcessModules.Call(
    uintptr(n),
    uintptr(procHandlesPtr),
    uintptr(n), 
    uintptr(unsafe.Pointer(&needed))))

  if int(ret2) == 1 {
    for i:= 0; i < needed / 4; i++ {
       fmt.Println(procHandles[i])
  }
}

【讨论】:

    猜你喜欢
    • 2016-03-26
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 2014-12-25
    • 2016-02-09
    相关资源
    最近更新 更多