|
老外很厉害,多年前我就想要的东西,有了VB6版本
顺势迁移了一个VBA 32位版本,用到的技术如下:
1、函数指针,本方法仅用于32位,64位需要用其他方法
2、内存查找未导出函数
声明:
1、目前应该能用于VBA6和VBA7,如果你的32位Office不能用,请上传相应VBE6.dll或VBE7.dll
2、仅提供一种新玩法,不保证所有人电脑都能用,水平有限,也不一定能给所有人解决问题
3、欢迎上传移植成功的64位版本
代码如下:
'mCallingProcName.bas
- Option Explicit
- Option Base 0
- Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleW" (ByVal lpModuleName As Long) As Long
- Private Declare Sub memcpy Lib "kernel32" Alias "RtlMoveMemory" (dst As Any, src As Any, ByVal Length As Long)
- '函数原型
- Private Function EbSetMode(ByVal Addr As Long, ByVal Mode As Long) As Long
- End Function
- Private Function EbGetCallstackCount(ByVal Addr As Long, ByRef lCount As Long) As Long
- End Function
- Private Function EbGetCallstackFunction(ByVal Addr As Long, _
- ByVal lIndex As Long, _
- ByVal pProject As Long, _
- ByVal pModule As Long, _
- ByVal pFunction As Long, _
- ByRef lRet As Long) As Long
- End Function
- Sub Test()
- MsgBox GetCallingProcName()
- End
- End Sub
- Public Function GetCallingProcName(Optional ByVal lReserved As Long) As String
- Dim lStackCount As Long
- Dim sProject As String
- Dim sModule As String
- Dim sFunction As String
- Dim hEbSetMode As Long
- Dim hEbGetCallstackCount As Long
- Dim hEbGetCallstackFunction As Long
- Dim hVbe As Long
- Dim pSection As Long
- Dim pStartScan As Long
- Dim pEndScan As Long
- Dim e_lfanew As Long
- Dim iNumOfSec As Integer
- Dim iOptSize As Integer
- Dim lIndex As Long
- Dim cName As Currency
- #If VBA7 Then
- hVbe = GetModuleHandle(StrPtr("VBE7"))
- #ElseIf VBA6 Then
- hVbe = GetModuleHandle(StrPtr("VBE6"))
- #End If
- If hVbe = 0 Then Exit Function
- #If VBA6 Or VBA7 Then
- memcpy e_lfanew, ByVal hVbe + &H3C, 4
- memcpy iNumOfSec, ByVal hVbe + e_lfanew + 6, 2
- memcpy iOptSize, ByVal hVbe + e_lfanew + &H14, 2
- pSection = hVbe + e_lfanew + &H18 + iOptSize
- For lIndex = 0 To iNumOfSec - 1
- memcpy cName, ByVal pSection, 8
- If cName = 50023612.1134@ Then
- memcpy pStartScan, ByVal pSection + &HC, 4
- memcpy pEndScan, ByVal pSection + &H8, 4
- pStartScan = pStartScan + hVbe
- pEndScan = pEndScan + pStartScan - 1
- Exit For
- End If
- pSection = pSection + &H28
- Next
- If pStartScan = 0 Or pEndScan = 0 Then Exit Function
- #End If
-
- #If VBA7 Then
- hEbSetMode = SearchFunction(pStartScan, pEndScan, "8B FF 53 55 56 57 E8 XX XX XX XX 8B 3D XX XX XX XX 8B F0 33 ED 8B DD 83 XX 01 75 0C E8 XX XX XX XX 85 C0 74 XX 6A 02 5E", 0)
- hEbGetCallstackCount = SearchFunction(pStartScan, pEndScan, "E8 XX XX XX XX 83 E8 00 74 XX 48 74 XX 48 75 XX A1 XX XX XX XX 8B 4C 24 04 83 21 00 05 XX XX XX XX 74 XX FF 01 8B 00 85 C0 75 XX EB XX", 0)
- hEbGetCallstackFunction = SearchFunction(pStartScan, pEndScan, "81 EC XX XX XX XX A1 XX XX XX XX 33 C4 89 XX XX XX 8B 84 XX XX XX 00 00 53 8B XX XX XX XX 00 00 55 33 ED 56 89 XX XX XX 8B 84 XX XX XX 00 00 57 8B XX XX XX XX 00 00 89 44", 0)
- #ElseIf VBA6 Then
- hEbSetMode = SearchFunction(pStartScan, pEndScan, "55 8B EC 51 56 57 E8 XX XX XX XX XX XX XX XX 8B 35 XX XX XX XX 8B F8 83 XX 01 75 0C E8 XX XX XX XX 85 C0 74 XX 6A 02 5F", 0)
- hEbGetCallstackCount = SearchFunction(pStartScan, pEndScan, "E8 XX XX XX XX 83 E8 00 74 XX 48 74 XX 48 75 XX A1 XX XX XX XX 8B 4C 24 04 05 XX XX XX XX 83 21 00 EB XX FF 01 8B 00 85 C0 7C XX EB XX", 0)
- hEbGetCallstackFunction = SearchFunction(pStartScan, pEndScan, "55 8B EC 81 EC XX XX XX XX A1 XX XX XX XX 33 C5 89 XX XX 8B XX XX 53 8B XX XX 89 XX XX 8B XX XX 56 33 F6 89 XX XX 8B XX XX 57 89 XX XX 8B XX XX 33 FF 89 XX XX 89 XX XX 89", 0)
- #End If
- PatchFunc AddressOf EbSetMode
- PatchFunc AddressOf EbGetCallstackCount
- PatchFunc AddressOf EbGetCallstackFunction
-
- EbSetMode hEbSetMode, 2
- If EbGetCallstackCount(hEbGetCallstackCount, lStackCount) >= 0 Then
- If lStackCount > 1 Then
- If EbGetCallstackFunction(hEbGetCallstackFunction, 1, VarPtr(sProject), VarPtr(sModule), VarPtr(sFunction), 0) >= 0 Then
- GetCallingProcName = sModule & "::" & sFunction
- End If
- End If
- End If
- EbSetMode hEbSetMode, 1
- End Function
- Private Sub PatchFunc(ByVal Addr As Long)
- memcpy Addr, ByVal Addr + &H16, 4
- memcpy ByVal Addr, &HFF505958, 4
- memcpy ByVal Addr + 4, &HE1, 4
- End Sub
复制代码
'mSearchFunc.bas
- Option Explicit
- Option Base 0
- Private Const FADF_AUTO As Long = 1
- Private Type SAFEARRAYBOUND
- cElements As Long
- lLbound As Long
- End Type
- Private Type SAFEARRAY
- cDims As Integer
- fFeatures As Integer
- cbElements As Long
- cLocks As Long
- pvData As Long
- Bounds As SAFEARRAYBOUND
- End Type
- Private Declare Sub DupArray Lib "kernel32" _
- Alias "RtlMoveMemory" ( _
- ByRef Destination() As Any, _
- ByRef pSA As Any, _
- Optional ByVal Length As Long = 4)
- Public Function SearchFunction(ByVal pStartScan As Long, ByVal pEndScan As Long, ByVal strHex As String, Optional ByVal offset As Long = 0) As Long
- Dim bData() As Byte
- Dim tSAMap As SAFEARRAY
- Dim lIndex As Long
- tSAMap.cbElements = 1
- tSAMap.cDims = 1
- tSAMap.fFeatures = FADF_AUTO
- tSAMap.Bounds.cElements = CLng(pEndScan - pStartScan) + 1
- tSAMap.pvData = pStartScan
- DupArray bData, VarPtr(tSAMap)
- Dim bTemplate() As Byte
- Dim bMask() As Byte
- Dim arrTemp
- Dim i As Long
- arrTemp = Split(strHex)
- ReDim bTemplate(UBound(arrTemp) - LBound(arrTemp)) As Byte
- ReDim bMask(UBound(arrTemp) - LBound(arrTemp)) As Byte
- For i = LBound(arrTemp) To UBound(arrTemp)
- If arrTemp(i) <> "XX" Then
- bMask(i) = 1
- bTemplate(i) = Val("&H" & arrTemp(i))
- End If
- Next i
- lIndex = FindSignature(bData(), bTemplate(), bMask())
- DupArray bData, 0@
- If lIndex = -1 Then Exit Function
- SearchFunction = pStartScan + lIndex + offset
- End Function
- Public Function FindSignature(ByRef bData() As Byte, ByRef bSignature() As Byte, ByRef bMask() As Byte) As Long
- Dim lDataIndex As Long
- Dim lSignIndex As Long
- lDataIndex = 0: lSignIndex = 0
- Do While lDataIndex <= UBound(bData)
- If bData(lDataIndex) = bSignature(lSignIndex) Or bMask(lSignIndex) = 0 Then
- lSignIndex = lSignIndex + 1
- If lSignIndex > UBound(bSignature) Then '
- FindSignature = lDataIndex - UBound(bSignature)
- Exit Function
- End If
- Else
- If lSignIndex Then
- lDataIndex = lDataIndex - lSignIndex + 1
- lSignIndex = 0
- End If
- End If
- lDataIndex = lDataIndex + 1
- Loop
- FindSignature = -1
- End Function
复制代码
|
评分
-
1
查看全部评分
-
|