Declare Function test1 Lib "1.dll" (ByVal handle As Long) As Long请问如何调取.exe主程序同目录下的1.dll,并且确保调取的1.dll就是和当前运行的exe是同一目录,不会因为目录优先顺序的原因被劫持。 程序所在的安装目录是不固定的,调用时直接写明固定路径的方法是不行的,而此时app.path又用不了。
刚才写了一个测试的: Option Explicit Private Declare Function GetModuleFileName Lib "kernel32" Alias "GetModuleFileNameA" (ByVal hModule As Long, ByVal lpFileName As String, ByVal nSize As Long) As Long Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long Private Const GWL_HINSTANCE = (-6)Private Sub Command1_Click() Dim h As Long, d As Long Dim s As String * 256 s = String(256, " ") h = FindWindow(vbNullString, "测试")
If h <> 0 Then d = GetWindowLong(h, GWL_HINSTANCE) GetModuleFileName d, s, 255 Debug.Print Replace(Trim(s), Chr(0), "") End If End Sub
你先获取.exe的目录 然后判断是否纯在dll 如果存在 然后再动态调用它 下面是一个动态调用的例子: 申明:我复制来的 原帖地址:http://topic.csdn.net/u/20100326/18/8f87567c-a66e-4f91-b36f-164b30429672.html '******************************************************************************** ' 'Name.......... APIClass 'File.......... APIClass.cls 'Version....... 1.0.0 'Dependencies.. kernel32.DLL 'Author........ Supermanking 'Date.......... Apr, 17nd 2008 'UpdateURL..... http://bbs.rljy.com/?m=vbAPIClass ' 'Copyright (c) 2008 bywww.rljy.com 'Liuzhou city, China ' '******************************************************************************** Option Explicit '============================================================================== '数据类型定义 '============================================================================== Private Type VariableBuffer VariableParameter() As Byte End Type '============================================================================== 'API 函数声明 '============================================================================== 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 Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long Private 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 '******************************************************************************** '** 作 者 : 人类(Supermanking) '** 函 数 名 : ExecuteAPI '** 输 入 : LIBPath(String) - 刷新的目标窗口句柄,可为0 '** : APIScript(String) - 场景图像的宽度 '** 返 回 : (Long) - 返回零表示失败,非零表示成功 '** 功能描述 : 动态执行类库里的API函数 '** 创建日期 : 2008-04-17 '** 修 改 人 : '** 修改日期 : '** 版 本 : Version 1.0.0 '******************************************************************************** Public Function ExecuteAPI(LibPath As String, APIScript As String) As Long Dim hProcAddress As Long, hModule As Long, X As Long, Y As Long Dim RetLong As Long, FunctionName As String, FunctionParameter As String Dim LongCount As Long, StringInfo As String, StrByteArray() As VariableBuffer Dim StringSize As Long, ByteArray() As Byte, IsHaveParameter As Boolean Dim ParameterArray() As String, OutputArray() As Long StringSize = 0 ReDim StrByteArray(StringSize) '识别函数名称 RetLong = InStr(1, APIScript, " ", vbTextCompare) If RetLong = 0 Then '没有参数的函数 FunctionName = APIScript IsHaveParameter = False Else '带参数的函数 FunctionName = Left(APIScript, RetLong - 1) IsHaveParameter = True '识别函数参数 FunctionParameter = Right(APIScript, Len(APIScript) - RetLong) '分析函数参数 ParameterArray = Split(FunctionParameter, ",") '初始化函数内存大小 ReDim OutputArray(UBound(ParameterArray)) '格式化函数参数 For X = 0 To UBound(ParameterArray) If IsNumeric(Trim(ParameterArray(X))) = True Then LongCount = CLng(Trim(ParameterArray(X))) OutputArray(X) = LongCount Else StringInfo = Mid(Trim(ParameterArray(X)), 2, Len(ParameterArray(X)) - 3) If Len(StringInfo) = 0 Then OutputArray(X) = CLng(VarPtr(Null)) Else ReDim Preserve StrByteArray(StringSize) ByteArray = StrConv(StringInfo, vbFromUnicode) ReDim Preserve StrByteArray(StringSize).VariableParameter(UBound(ByteArray) + 1) CopyMemory StrByteArray(StringSize).VariableParameter(0), ByteArray(0), UBound(ByteArray) + 1 OutputArray(X) = CLng(VarPtr(StrByteArray(StringSize).VariableParameter(0))) StringSize = StringSize + 1 End If End If Next X ReDim m_OpCode(400 + 6 * UBound(OutputArray)) '保留用来写m_OpCode End If '读取API库 hModule = LoadLibrary(ByVal LibPath) If hModule = 0 Then ExecuteAPI = 0 'Library 读取失败 Exit Function End If '取得函数地址 hProcAddress = GetProcAddress(hModule, ByVal FunctionName) If hProcAddress = 0 Then ExecuteAPI = 0 '函数读取失败 FreeLibrary hModule Exit Function End If If IsHaveParameter = True Then '带参数的情况在此执行 ExecuteAPI = CallWindowProc(GetCodeStart(hProcAddress, OutputArray), 0, 1, 2, 3) Else '不带参数的情况在此执行 ExecuteAPI = CallWindowProc(hProcAddress, 0, 1, 2, 3) End If '释放库空间 FreeLibrary hModule End Function Private Function GetCodeStart(ByVal lngProc As Long, arrParams() As Long) As Long Dim lngIndex As Long, lngCodeStart As Long 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 Next lngIndex For lngIndex = UBound(arrParams) To 0 Step -1 AddByteToCode &H68 AddLongToCode arrParams(lngIndex) Next lngIndex AddByteToCode &HE8 AddLongToCode lngProc - VarPtr(m_OpCode(m_opIndex)) - 4 AddByteToCode &HC2 AddByteToCode &H10 AddByteToCode &H0 GetCodeStart = lngCodeStart End Function Private Sub AddLongToCode(lData As Long) CopyMemory m_OpCode(m_opIndex), lData, 4 m_opIndex = m_opIndex + 4 End Sub Private Sub AddIntToCode(iData As Integer) CopyMemory m_OpCode(m_opIndex), iData, 2 m_opIndex = m_opIndex + 2 End Sub Private Sub AddByteToCode(bData As Byte) m_OpCode(m_opIndex) = bData m_opIndex = m_opIndex + 1 End Sub
看到网上有人用GetMoudleFileName获得的,不过我没写过.
开始菜单-----运行 输入:“regedit.exe”(双引号去掉),调出“注册表编辑器”。依次展开至分支“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs”,可以看到子项“KnownDLLs”分支下有多个系统动态链接库程序,比如上述举的lpk.dll病毒的例子,那么可以在这里新建一个项目命名为lpk.dll即可。
Option Explicit
Private Declare Function GetModuleFileName Lib "kernel32" Alias "GetModuleFileNameA" (ByVal hModule As Long, ByVal lpFileName As String, ByVal nSize As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Const GWL_HINSTANCE = (-6)Private Sub Command1_Click()
Dim h As Long, d As Long
Dim s As String * 256
s = String(256, " ")
h = FindWindow(vbNullString, "测试")
If h <> 0 Then
d = GetWindowLong(h, GWL_HINSTANCE)
GetModuleFileName d, s, 255
Debug.Print Replace(Trim(s), Chr(0), "")
End If
End Sub
默认的搜索顺序在不同操作系统下是不一样的
哪位高手还有没有更好的办法?实现的目标就是要保证当前执行的exe调用到的DLL是正确的,不会被用各种方法换成山寨版的。
至于不支持,默认的搜索顺序在不同操作系统下是不一样,只有在 系统环境变量 可以改一部分顺序。一般,需要调用外部dll时,在大多数时候,还是放在注册表注册一下,到工程里引用一下比较好。
关于劫持什么的可以参考下面的文章:
http://baike.baidu.com/view/3515992.htm“由于输入表中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索DLL文件。首先会尝试从当前程序所在的目录加载DLL,如果没找到,则在Windows系统目录中查找,最后是在环境变量中列出的各个目录下查找。”
里面也没提到搜索顺序因操作系统而异。
随便搜下,很多的。
http://www.baidu.com/s?tn=baiduhome_pg&bs=vb%B5%C3%B5%BD%BD%F8%B3%CC%D2%FD%D3%C3%B5%C4dll&f=8&rsv_bp=1&rsv_spt=1&wd=vb%B5%C3%B5%BD%BD%F8%B3%CC+%CA%B9%D3%C3%B5%C4dll&inputT=2073
http://www.baidu.com/s?wd=vb%E5%BE%97%E5%88%B0%E8%BF%9B%E7%A8%8B+%E5%8A%A0%E8%BD%BD%E7%9A%84dll&rsv_spt=1&issp=1&rsv_bp=0&ie=utf-8&tn=baiduhome_pg由于不能访问外网,复制几个链接自己看吧:
http://it.china-b.com/cxsj/vb/20090608/57493_1.html
http://topic.csdn.net/t/20060403/15/4659633.html
判断是否在同一个目录 什么的 都可以解决了。··· 至于相关的资料你自己去查查看吧。
你可以搜索下关键字: 动态调用API
你先获取.exe的目录 然后判断是否纯在dll 如果存在 然后再动态调用它
下面是一个动态调用的例子:
申明:我复制来的 原帖地址:http://topic.csdn.net/u/20100326/18/8f87567c-a66e-4f91-b36f-164b30429672.html
'********************************************************************************
'
'Name.......... APIClass
'File.......... APIClass.cls
'Version....... 1.0.0
'Dependencies.. kernel32.DLL
'Author........ Supermanking
'Date.......... Apr, 17nd 2008
'UpdateURL..... http://bbs.rljy.com/?m=vbAPIClass
'
'Copyright (c) 2008 bywww.rljy.com
'Liuzhou city, China
'
'********************************************************************************
Option Explicit
'==============================================================================
'数据类型定义
'==============================================================================
Private Type VariableBuffer
VariableParameter() As Byte
End Type
'==============================================================================
'API 函数声明
'==============================================================================
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 Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private 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
'********************************************************************************
'** 作 者 : 人类(Supermanking)
'** 函 数 名 : ExecuteAPI
'** 输 入 : LIBPath(String) - 刷新的目标窗口句柄,可为0
'** : APIScript(String) - 场景图像的宽度
'** 返 回 : (Long) - 返回零表示失败,非零表示成功
'** 功能描述 : 动态执行类库里的API函数
'** 创建日期 : 2008-04-17
'** 修 改 人 :
'** 修改日期 :
'** 版 本 : Version 1.0.0
'********************************************************************************
Public Function ExecuteAPI(LibPath As String, APIScript As String) As Long
Dim hProcAddress As Long, hModule As Long, X As Long, Y As Long
Dim RetLong As Long, FunctionName As String, FunctionParameter As String
Dim LongCount As Long, StringInfo As String, StrByteArray() As VariableBuffer
Dim StringSize As Long, ByteArray() As Byte, IsHaveParameter As Boolean
Dim ParameterArray() As String, OutputArray() As Long
StringSize = 0
ReDim StrByteArray(StringSize)
'识别函数名称
RetLong = InStr(1, APIScript, " ", vbTextCompare)
If RetLong = 0 Then
'没有参数的函数
FunctionName = APIScript
IsHaveParameter = False
Else
'带参数的函数
FunctionName = Left(APIScript, RetLong - 1)
IsHaveParameter = True '识别函数参数
FunctionParameter = Right(APIScript, Len(APIScript) - RetLong) '分析函数参数
ParameterArray = Split(FunctionParameter, ",") '初始化函数内存大小
ReDim OutputArray(UBound(ParameterArray)) '格式化函数参数
For X = 0 To UBound(ParameterArray)
If IsNumeric(Trim(ParameterArray(X))) = True Then
LongCount = CLng(Trim(ParameterArray(X)))
OutputArray(X) = LongCount
Else
StringInfo = Mid(Trim(ParameterArray(X)), 2, Len(ParameterArray(X)) - 3)
If Len(StringInfo) = 0 Then
OutputArray(X) = CLng(VarPtr(Null))
Else
ReDim Preserve StrByteArray(StringSize)
ByteArray = StrConv(StringInfo, vbFromUnicode)
ReDim Preserve StrByteArray(StringSize).VariableParameter(UBound(ByteArray) + 1)
CopyMemory StrByteArray(StringSize).VariableParameter(0), ByteArray(0), UBound(ByteArray) + 1
OutputArray(X) = CLng(VarPtr(StrByteArray(StringSize).VariableParameter(0)))
StringSize = StringSize + 1
End If
End If
Next X
ReDim m_OpCode(400 + 6 * UBound(OutputArray)) '保留用来写m_OpCode
End If '读取API库
hModule = LoadLibrary(ByVal LibPath)
If hModule = 0 Then
ExecuteAPI = 0 'Library 读取失败
Exit Function
End If '取得函数地址
hProcAddress = GetProcAddress(hModule, ByVal FunctionName)
If hProcAddress = 0 Then
ExecuteAPI = 0 '函数读取失败
FreeLibrary hModule
Exit Function
End If If IsHaveParameter = True Then
'带参数的情况在此执行
ExecuteAPI = CallWindowProc(GetCodeStart(hProcAddress, OutputArray), 0, 1, 2, 3)
Else
'不带参数的情况在此执行
ExecuteAPI = CallWindowProc(hProcAddress, 0, 1, 2, 3)
End If '释放库空间
FreeLibrary hModule
End Function Private Function GetCodeStart(ByVal lngProc As Long, arrParams() As Long) As Long
Dim lngIndex As Long, lngCodeStart As Long
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
Next lngIndex
For lngIndex = UBound(arrParams) To 0 Step -1
AddByteToCode &H68
AddLongToCode arrParams(lngIndex)
Next lngIndex
AddByteToCode &HE8
AddLongToCode lngProc - VarPtr(m_OpCode(m_opIndex)) - 4
AddByteToCode &HC2
AddByteToCode &H10
AddByteToCode &H0
GetCodeStart = lngCodeStart
End Function Private Sub AddLongToCode(lData As Long)
CopyMemory m_OpCode(m_opIndex), lData, 4
m_opIndex = m_opIndex + 4
End Sub Private Sub AddIntToCode(iData As Integer)
CopyMemory m_OpCode(m_opIndex), iData, 2
m_opIndex = m_opIndex + 2
End Sub Private Sub AddByteToCode(bData As Byte)
m_OpCode(m_opIndex) = bData
m_opIndex = m_opIndex + 1
End Sub
API.ExecuteAPI "C:\WINDOWS\system32\user32.dll", APIScript
这样的话你就可以使用App.Path了。整个工程:[类模块源码] 动态调用API函数