【问题标题】:VB6 - Declaring and calling C DLL with pointersVB6 - 使用指针声明和调用 C DLL
【发布时间】:2012-10-28 03:53:26
【问题描述】:

我有一个旧的 C DLL 用于从 Ruby 调用,但现在我需要从 VB6 调用它,但我无法找到正确的方法。

这是我需要的函数的标题:

int Decrunch(const BYTE *src, BYTE *dest, DWORD src_length)

*src 是一个字节序列,将被函数解密

*dest 是一个缓冲区,它将接收解密的数据。我可以使用 dest=NULL 调用该函数,它会返回解密数据的大小,因此我可以使用它来创建具有正确大小的缓冲区。

我尝试将 src 和 dest 都声明为字符串(就像我在 Ruby 中所做的那样),但它不起作用。我还尝试将它们声明为 Byte 并传递字节数组的第一个元素,正如一些教程所指出的那样,但我认为我没有正确地做到这一点。

有人可以帮我解决这个问题吗?

谢谢!

【问题讨论】:

    标签: c dll vb6


    【解决方案1】:

    航空代码

    Private Declare DecrunchGetLength Alias "Decrunch" Lib "somedll.DLL" (ByRef src As Byte, ByVal nullptr As Long, ByVal SrcLength As Long) As Long 
    
    Private Declare Decrunch Alias "Decrunch" Lib "somedll.DLL" (ByRef src As Byte, ByRef dest As Byte, ByVal SrcLength As Long) As Long 
    
    Dim destLen As Long
     Dim src(0 To 9) As Byte 
    Dim dest() As Byte 
    
    ' get bytes into src somehow 
    
    ' get dest length 
    destLen = DecrunchGetLen( src(0), 0, 10) 
    
    ReDim dest(0 To destLen - 1) 
    destLen = Decrunch( src(0), dest(0), 10) 
    

    有用的链接

    【讨论】:

    • 谢谢!但是在调用 DecrunchGetLen 时,我仍然会收到“错误的 DLL 调用约定”。还有其他想法吗?也谢谢你的链接。
    • 这不是 cdecl DLL 是吗? factoryswblog.org/2007/10/25/…
    • 我不知道。我将不得不检查开发人员是否记得这一点。我有函数算法,如果我只是翻译代码或构建另一个DLL可能会少一些麻烦。
    • 抱歉,现在才注意到链接。我会按照说明进行操作,希望对您有所帮助 =) 谢谢
    • 已编译的应用程序在调用您的 API 函数后尝试“修复”堆栈。它并不总是成功,不用说这在生产代码中是多么危险。
    【解决方案2】:

    您可以像这样使用 CDECL 调用 thunk

    Option Explicit
    
    '--- for VirtualProtect'
    Private Const PAGE_EXECUTE_READWRITE    As Long = &H40
    
    Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
    Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
    Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    Private Const STR_MYDLL         As String = "my.dll"
    
    Private Type UcsParamThunk
        pfn                     As Long
        Call_(0 To 7)           As Long
    End Type
    
    Private m_hModule           As Long
    Private m_uCallThunk        As UcsParamThunk
    
    Private Sub Form_Load()
        Dim baSrc()         As Byte
        Dim baDst()         As Byte
    
        On Error GoTo EH
        ReDim baSrc(0 To 10000) As Byte
        ReDim baDst(0 To 20000) As Byte
        pvCallFunc "Decrunch", VarPtr(baSrc(0)), VarPtr(baDst(0)), UBound(baSrc) + 1
        Exit Sub
    EH:
        MsgBox Error$, vbCritical
    End Sub
    
    Private Function pvCallFunc(sFunc As String, ParamArray A()) As Long
        Dim pfn             As Long
        Dim lIdx            As Long
        Dim aParams()       As Long
    
        If m_hModule = 0 Then
            m_hModule = LoadLibrary(STR_MYDLL)
            If m_hModule = 0 Then
                Err.Raise vbObjectError, , STR_MYDLL & " not found"
            End If
            pvInitCallCdeclThunk m_uCallThunk
        End If
        pfn = GetProcAddress(m_hModule, sFunc)
        If pfn = 0 Then
            Err.Raise vbObjectError, , "Export not found: " & sFunc
        End If
        ReDim aParams(0 To UBound(A) + 1) As Long
        For lIdx = 0 To UBound(A)
            aParams(lIdx) = CLng(A(lIdx))
        Next
        pvCallFunc = CallWindowProc(m_uCallThunk.pfn, pfn, UBound(aParams), VarPtr(aParams(0)), 0)
    End Function
    
    Private Sub pvInitCallCdeclThunk(Thunk As UcsParamThunk)
    'void _stdcall thunk(int pfn, int count, int args, int dummy)
    '        push    ebp
    '        mov     ebp, esp
    '        mov     ecx, count
    '        jecxz   _skip_params
    '        mov     edx, args
    '_params_loop:
    '        push    dword ptr [edx + ecx * 4 - 4]
    '        loop    _params_loop
    '_skip_params:
    '        call pfn
    '        mov     esp,ebp
    '        pop     ebp
    '        ret     10h
    '        nop
    '        nop
        With Thunk
            .Call_(0) = &H8BEC8B55
            .Call_(1) = &H9E30C4D
            .Call_(2) = &HFF10558B
            .Call_(3) = &HE2FC8A74
            .Call_(4) = &H855FFFA
            .Call_(5) = &HC25DE58B
            .Call_(6) = &H90900010
            .pfn = VarPtr(.Call_(0))
            Call VirtualProtect(Thunk, Len(Thunk), PAGE_EXECUTE_READWRITE, 0)
        End With
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-02
      • 1970-01-01
      • 2012-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-04
      相关资源
      最近更新 更多