gpt4 book ai didi

go - 如何使用其序数值从 DLL 中查找过程?

转载 作者:IT王子 更新时间:2023-10-29 02:09:31 24 4
gpt4 key购买 nike

我正在尝试使用序号值从 DLL 调用过程(没有名称)。

我可以在 C# 中使用此 DLL,将 序号值 设置为属性 EntryPointDllImport

... or you can identify the entry point by its ordinal. Ordinals are prefixed with the # sign, for example, #1. [...]

C# 示例:

[DllImport("dllname.dll", EntryPoint = "#3", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern int DeviceList(ref IntPtr hDeviceList);

在Go中尝试查找带有“#”符号的过程时,出现如下错误:

Failed to find #3 procedure in dllname.dll: The specified procedure could not be found.

我用了dumpbin显示DLL的信息,没有函数有名字:

dumpbin results

有没有一种方法可以找到具有其序数值的过程(如 C#)?

最佳答案

a github issue here为此,但从 Go 1.10.3(我现在使用的版本)开始,它似乎还没有被合并。

无论如何,github 问题链接到 a changeset with the respective function我从中提取了代码来执行您在这里想要执行的操作:

var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetProcAddress = kernel32.NewProc("GetProcAddress")
)

// GetProcAddressByOrdinal retrieves the address of the exported
// function from module by ordinal.
func GetProcAddressByOrdinal(module syscall.Handle, ordinal uintptr) (uintptr, error) {
r0, _, _ := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0)
proc := uintptr(r0)
if proc == 0 {
return 0, syscall.EINVAL
}
return proc, nil
}

为了完整起见,这里是我测试它的完整示例,使用 Dependecy Walker 我发现 kernel32.dll 中的第一个函数是 AcquireSRWLockExclusive 并使用新函数它显示了 proc地址确实匹配。

package main

import (
"fmt"
"syscall"
)

func main() {
dll, err := syscall.LoadDLL("kernel32.dll")
check(err)

want, err := syscall.GetProcAddress(dll.Handle, "AcquireSRWLockExclusive")
check(err)
fmt.Println(want)

first, err := GetProcAddressByOrdinal(dll.Handle, 1)
check(err)
fmt.Println(first)
}

func check(err error) {
if err != nil {
panic(err)
}
}

var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetProcAddress = kernel32.NewProc("GetProcAddress")
)

// GetProcAddressByOrdinal retrieves the address of the exported
// function from module by ordinal.
func GetProcAddressByOrdinal(module syscall.Handle, ordinal uintptr) (uintptr, error) {
r0, _, _ := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), ordinal, 0)
proc := uintptr(r0)
if proc == 0 {
return 0, syscall.EINVAL
}
return proc, nil
}

关于go - 如何使用其序数值从 DLL 中查找过程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51507398/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com