863
社区成员
发帖
与我相关
我的任务
分享
typedef HRESULT (__stdcall * pfnHello)(REFCLSID,REFIID,void**);
pfnHello fnHello= NULL;
HINSTANCE hdllInst = LoadLibrary("组件所在目录myCom.dll");
fnHello=(pfnHello)GetProcAddress(hdllInst,"DllGetClassObject");
if (fnHello != 0)
{
IClassFactory* pcf = NULL;
HRESULT hr=(fnHello)(CLSID_GetRes,IID_IClassFactory,(void**)&pcf);
if (SUCCEEDED(hr) && (pcf != NULL))
{
IGetRes* pGetRes = NULL;
hr = pcf->CreateInstance(NULL, IID_IFoo, (void**)&pGetRes);
if (SUCCEEDED(hr) && (pFoo != NULL)) //这里pFoo应该改成pGetRes,不过hr成功了,pGetRes应该不会null
{
pGetRes->Hello();
pGetRes->Release();
}
pcf->Release();
}
}
FreeLibrary(hdllInst);
Option Explicit
Private Declare Function CoInitialize Lib "ole32.dll" (ByVal pvReserved As Long) As Long
Private Declare Function LoadLibrary Lib "Kernel32.dll" Alias "LoadLibraryW" (ByVal lpFileName As Long) As Long
Private Declare Function FreeLibrary Lib "Kernel32.dll" (ByVal hModule As Long) As Long
Private Declare Function GetProcAddress Lib "Kernel32.dll" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function DllFunAdrCall Lib "D:\Administrator\Documents\Visual Studio 2008\Projects\dllfunadrcall\Debug\dllfunadrcall.dll" (ByVal hfun As Long, pargs As Long, ByVal count As Long) As Long
Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcW" (ByVal lpPrevWndFunc As Long, hWnd As Long, Msg As Long, wParam As Long, lParam As Long) As Long
Private Declare Function CLSIDFromString Lib "ole32.dll" (ByVal lpsz As Long, pclsid As Long) As Long
'IID_IClassFactory"00000001-0000-0000-C000-000000000046"
Public Function LoadDll_cf(dllname As String, sclsid As String) As BOOL
Dim dll As Long
Dim fun As Long
Dim rt As Long
Dim ccf As CLSID
Dim ccl As CLSID
Dim icf As IClassFactory3
Dim n As Long
Dim pargs(3) As Long
Dim iid2 As CLSID
rt = CoInitialize(0)
dll = LoadLibrary(StrPtr(dllname))
If dll > 0 Then
fun = GetProcAddress(dll, "DllGetClassObject")
If fun > 0 Then
rt = CLSIDFromString(StrPtr(sclsid), ccf.Data1)
rt = CLSIDFromString(StrPtr("{00000001-0000-0000-C000-000000000046}"), ccl.Data1)
rt = CLSIDFromString(StrPtr("{507B7E6A-DA56-4893-A701-95EA372EA15F}"), iid2.Data1)
pargs(0) = VarPtr(ccf.Data1)
pargs(1) = VarPtr(ccl.Data1)
pargs(2) = VarPtr(icf)
rt = DllFunAdrCall(fun, pargs(0), 3)
icf.CreateInstance ByVal 0, iid2.Data1, n
'rt = CallWindowProc(fun, ccf.Data1, ccl.Data1, n, ByVal 0)
End If
FreeLibrary dll
End If
End Function
Option Explicit
Private Sub Command1_Click()
Dim objTest As Object
Dim lRetVal As Integer
Set objTest = Dll_GetClassObject("E:\Temp\mp3info.dll", _
"{AAFA1E73-4842-4BEC-BC46-48C62E1C5C9C}", _
"{F31A1156-1CC0-4130-9FCB-B69116480C93}")
' function IsMP3File(fileName:BSTR): bool;
Me.Print objTest.IsMP3File("E:\Temp\123.mp3")
lRetVal = objTest.IsMP3File("E:\Temp\123.mp3")
Me.Print lRetVal
Set objTest = Nothing
End Sub
Option Explicit
Private Type CLSID
d1 As Long
d2 As Integer
d3 As Integer
d4 As Integer
d5(5) As Byte
End Type
Private Declare Function LoadLibraryW Lib "kernel32.dll" (ByVal lpFileName As Long) As Long
Private Declare Function GetProcAddress Lib "kernel32.dll" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Any, ByVal Source As Any, Optional ByVal Length As Long = 4) As Long
Private Declare Function VirtualProtect Lib "kernel32" (ByVal lpAddress As Any, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Private Declare Function CLSIDFromString Lib "ole32.dll" (ByVal lpsz As Long, pclsid As Long) As Long
Dim fMdfFunCode As Boolean
Function CallFunAddr1(ByVal addr As Long) As Long
MsgBox "CallFunAddr1 未修改"
End Function
'00401312 FF6424 04 JMP DWORD PTR SS:[ESP+4]
'00401316 90 NOP
Sub MdfCallFunAddr1code()
Dim n As Long
Dim r As Long
r = VirtualProtect(AddressOf CallFunAddr1, 4, &H40, n)
r = &H42464FF
CopyMemory AddressOf CallFunAddr1, VarPtr(r), 4
fMdfFunCode = True
End Sub
Public Function CallFunAddrArgs(ByVal addr As Long, ParamArray args() As Variant) As Long
Dim code(30) As Long
Dim i As Long
Dim j As Long
On Error Resume Next
i = 0
j = -1
For j = UBound(args) To 0 Step -1
code(i) = &H68909090
code(i + 1) = args(j)
i = i + 2
Next
code(i) = &HB8909090
code(i + 1) = addr
code(i + 2) = &HC290D0FF
code(i + 3) = 4
If fMdfFunCode = False Then MdfCallFunAddr1code
CallFunAddrArgs = CallFunAddr1(VarPtr(code(0)))
End Function
'77174AF3 68 78563412 push 12345678
'77174AF8 OLEAUT32.> B8 12345678 mov eax,78563412
'77174AFD FFD0 call eax
'77174AFF FFE0 jmp eax
'77174B01 C2 1000 retn 10
'77174B04 90 nop
Public Sub MdfFunAddr(ByVal vbfun As Long, ByVal newAddr As Long)
Dim r As Long
Dim n As Long
Dim code(2) As Long
code(0) = &HB8909090
code(1) = newAddr
code(2) = &H9090E0FF
r = VirtualProtect(ByVal vbfun, 12, &H40, n)
CopyMemory ByVal vbfun, VarPtr(code(0)), 12
End Sub
'member索引从0开始,IUnknown3个成员函数,IDispatch4个成员函数,IClassFactory.CreateInstance在3号位置
Public Function GetClassMemberAddr(ByVal cthis As Long, ByVal member As Long) As Long
Dim vtab As Long
Dim fun As Long
CopyMemory VarPtr(vtab), ByVal cthis, 4
CopyMemory VarPtr(fun), ByVal vtab + member * 4, 4
GetClassMemberAddr = fun
End Function
Public Function Dll_GetClassObject(dllname As String, sclsid As String, siid As String) As Object
Dim dll As Long
Dim hr As Long
Dim clsid_icf As CLSID
Dim clsid_cls As CLSID
Dim clsid_iid As CLSID
Dim icf As Long 'IClassFactory
Dim funDllGetClassObject As Long
Dim funCreateInstance As Long
Dim funRelease As Long
Dim obj As Object
dll = LoadLibraryW(StrPtr(dllname))
If dll > 0 Then
funDllGetClassObject = GetProcAddress(dll, "DllGetClassObject")
If funDllGetClassObject > 0 Then
hr = CLSIDFromString(StrPtr("{00000001-0000-0000-C000-000000000046}"), clsid_icf.d1)
hr = CLSIDFromString(StrPtr(sclsid), clsid_cls.d1)
hr = CLSIDFromString(StrPtr(siid), clsid_iid.d1)
hr = CallFunAddrArgs(funDllGetClassObject, VarPtr(clsid_cls.d1), VarPtr(clsid_icf.d1), VarPtr(icf))
funCreateInstance = GetClassMemberAddr(icf, 3)
hr = CallFunAddrArgs(funCreateInstance, icf, 0, VarPtr(clsid_iid.d1), VarPtr(obj))
funRelease = GetClassMemberAddr(icf, 2)
hr = CallFunAddrArgs(funRelease, icf)
MsgBox TypeName(obj)
Set Dll_GetClassObject = obj
End If
'FreeLibrary dll
Else
MsgBox "dll加载失败"
End If
End Function
Private Sub Form_Load()
Dim c 'As aatest2.Class1
Set c = Dll_GetClassObject("aatest2.dll", "{6D926E71-56E7-467D-B64F-E7571EF1B806}", "{B1F1024A-7CF1-44C8-B34B-B7BE383F4825}")
c.testadd 1, 2, "a"
End Sub
需要生成exe才有效,win7 64位测试通过 Public Function MyMessageBox(ByVal nhwnd As Long, ByVal m As String, ByVal c As String, ByVal i As Long) As Long
Dim t As Long
t = 1
t = t + 2
t = t + 5
MyMessageBox = t
End Function
Public Function GetFunAddr(ByVal vbfun As Long) As Long
GetFunAddr = vbfun
End Function
'77174AF3 68 78563412 push 12345678
'77174AF8 OLEAUT32.> B8 12345678 mov eax,78563412
'77174AFD FFD0 call eax
'77174AFF FFE0 jmp eax
'77174B01 C2 1000 retn 10
'77174B04 90 nop
Public Sub MdfFunAddr(ByVal vbfun As Long, ByVal newAddr As Long)
Dim r As Long
Dim n As Long
Dim code(2) As Long
code(0) = &HB8909090
code(1) = newAddr
code(2) = &H9090E0FF
r = VirtualProtect(ByVal vbfun, 12, &H40, n)
CopyMemory ByVal vbfun, code(0), 12
End Sub
Sub Test_CallFunAddr()
Dim a As Long
a = LoadLibrary(StrPtr("user32.dll"))
a = GetProcAddress(a, "MessageBoxW")
MdfFunAddr AddressOf MyMessageBox, a
a = MyMessageBox(0, "消息内容", "标题", vbOKCancel)
MsgBox a
End Sub