一个动态调用DLL的源码

Option Explicit

Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Public Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Public 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
Public Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)

Private m_opIndex As Long '写入位置
Private m_OpCode() As Byte  'Assembly 的OPCODE

Public Function DynamicRunDll32(ByVal isUnload As Boolean, ByVal strLibFileName As String, strProcName As String, ParamArray Params()) As Long
    Dim hProc As Long
    Dim hModule As Long
    ReDim m_OpCode(400 + 6 * UBound(Params)) '保留用来写m_OpCode
    '读取API库
    hModule = LoadLibrary(ByVal strLibFileName)
    If hModule = 0 Then
        MsgBox "Library读取失败!"
        DynamicRunDll32 = 0
        Exit Function
    End If
   
    '取得函数地址
    hProc = GetProcAddress(hModule, ByVal strProcName)
    If hProc = 0 Then
       MsgBox "函数读取失败!", vbCritical
       FreeLibrary hModule
       DynamicRunDll32 = 0
       Exit Function
    End If
    '执行Assembly Code部分
    DynamicRunDll32 = CallWindowProc(GetCodeStart(hProc, Params), 0, 1, 2, 3)
    '一些函数需要驻留这就先不释放
    If isUnload Then FreeLibrary hModule  '释放空间
End Function

'Public Function RunDll32(LibFileName As String, ProcName As String, ParamArray Params()) As Long
'    Dim hProc As Long
'    Dim hModule As Long
'
'    ReDim m_OpCode(400 + 6 * UBound(Params)) '保留用来写m_OpCode
'    '读取API库
'    hModule = LoadLibrary(ByVal LibFileName)
'    If hModule = 0 Then
'        MsgBox "Library读取失败!"
'        Exit Function
'    End If
'
'    '取得函数地址
'    hProc = GetProcAddress(hModule, ByVal ProcName)
'    If hProc = 0 Then
'       MsgBox "函数读取失败!", vbCritical
'       FreeLibrary hModule
'       Exit Function
'    End If
'
'
'    '执行Assembly Code部分
'    RunDll32 = CallWindowProc(GetCodeStart(hProc, Params), 0, 1, 2, 3)
'
'    FreeLibrary hModule '释放空间
'End Function

Private Function GetCodeStart(ByVal lngProc As Long, ByVal arrParams As Variant) As Long
'---以下为Assembly部分--
'作用:将函数的参数压入堆栈
   
    Dim lngIndex As Long, lngCodeStart As Long
   
    '程序起始位址必须是16的倍数
    'VarPtr函数是用来取得变量的地址
    lngCodeStart = (VarPtr(m_OpCode(0)) Or &HF) + 1
   
    m_opIndex = lngCodeStart - VarPtr(m_OpCode(0)) '程序开始的元素的位置
   
    '前面部分以中断点添满
    For lngIndex = 0 To m_opIndex - 1
        m_OpCode(lngIndex) = &HCC 'int 3
    Next lngIndex
   
    '--------以下开始放入所需的程序----------
   
    '将参数push到堆栈
    '由于是STDCall CALL 参数由最后一个开始放到堆栈
    For lngIndex = UBound(arrParams) To 0 Step -1
       AddByteToCode &H68 'push的机器码为H68
       AddLongToCode CLng(arrParams(lngIndex))  '参数地址
    Next lngIndex
   
    'call hProc
    AddByteToCode &HE8 'call的机器码为HE8
    AddLongToCode lngProc - VarPtr(m_OpCode(m_opIndex)) - 4 '函数地址 用call的定址
   
    '-----------结束所需的程序--------------
   
    '返回呼叫函數
    AddByteToCode &HC2 'ret 10h
    AddByteToCode &H10
    AddByteToCode &H0
   
    GetCodeStart = lngCodeStart
End Function

Private Sub AddLongToCode(lData As Long)
'将Long类型的参数写到m_OpCode中
    CopyMemory m_OpCode(m_opIndex), lData, 4
    m_opIndex = m_opIndex + 4
End Sub

Private Sub AddIntToCode(iData As Byte)
'将Integer类型的参数写道m_OpCode中
    CopyMemory m_OpCode(m_opIndex), iData, 2
    m_opIndex = m_opIndex + 2
End Sub

Private Sub AddByteToCode(bData As Byte)
    '将Byte类型的参数写道m_OpCode中
    m_OpCode(m_opIndex) = bData
    m_opIndex = m_opIndex + 1
End Sub


窗体源码:

Private Sub cmdOk_Click()
    Call DynamicRunDll32(False, "test.dll", "ShowMessage")
End Sub

Private Sub Form_Load()
   Dim s1() As Byte, s2() As Byte
   Dim ret As Long
   s1 = StrConv("123", vbFromUnicode)
   s2 = StrConv("VBNote", vbFromUnicode)
   ret = DynamicRunDll32(True, "user32", "SetWindowTextA", hWnd, VarPtr(s1(0)))
   ret = DynamicRunDll32(True, "user32", "SetWindowTextA", hWnd, StrPtr(s2))
   Call DynamicRunDll32(True, "kernel32", "DeleteFileA", StrPtr(StrConv("c:/111.txt", vbFromUnicode)))
End Sub 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值