我正在尝试使用序数值从DLL调用过程(无名称)。
我可以在C#中使用此DLL,将原始值设置为Error.php
的属性EntryPoint
。
...,也可以按顺序标识入口点。普通字首带有#号,例如#1。 [...]
C#示例:
$_SESSION['message'] = "Some Message";
$MSG = $_SESSION['message'];
header('location: ../Pages/Error.php');
session_destroy();
die();
当尝试在Go中找到带有“#”符号的过程时,它显示以下错误:
在dllname.dll中找不到#3过程:找不到指定的过程。
我使用dumpbin
来显示DLL的信息,没有函数具有名称:
是否可以使用序号(例如C#)查找过程?
答案 0 :(得分:1)
有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
}