我正在尝试使用序号值从 DLL 调用过程(没有名称)。
我可以在 C# 中使用此 DLL,将 序号值 设置为属性 EntryPoint
的 DllImport
。
... 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的信息,没有函数有名字:
有没有一种方法可以找到具有其序数值的过程(如 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/