douqin1932 2018-07-24 20:55
浏览 74
已采纳

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

I'm trying to call procedure (without name) from a DLL using the ordinal value.

I can use this DLL in C#, setting the ordinal value to the property EntryPoint of DllImport.

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

Example in C#:

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

When try find the procedure with "#" sign in Go, it shows the the following error:

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

I used dumpbin to show the information of the DLL, no function has a name:

dumpbin results

Is there a way to find a procedure with its ordinal value (like C#)?

  • 写回答

1条回答 默认 最新

  • douti8321 2018-07-24 21:24
    关注

    There is a github issue here for this, but it seems not to have been merged as of Go 1.10.3 (the version I am using right now).

    Anyway, the github issue links to a changeset with the respective function from which I extracted the code to do what you want here:

    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
    }
    

    For completeness, here is the full example with which I tested this, using the Dependecy Walker I found that the first function in kernel32.dll is AcquireSRWLockExclusive and using the new function it shows that the proc addresses really match.

    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
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?