1,482
社区成员




form:
VERSION 5.00
Begin VB.Form frmMain
Caption = "Hook 测试"
ClientHeight = 3030
ClientLeft = 120
ClientTop = 450
ClientWidth = 4560
LinkTopic = "Form1"
ScaleHeight = 3030
ScaleWidth = 4560
StartUpPosition = 3 '窗口缺省
End
Attribute VB_Name = "frmMain"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Private Sub Form_Load()
Dim dwFunAddress As Long
Dim dwProxyFunAddress As Long
Dim dwProxyFunAddress1 As Long
If InitHook Then
HookDllFunctionCall 'Hook DllFunctionCall好实现函数指针功能
Call HookApi("kernel32.dll", "DeleteFileA", AddressOf DeleteFileACallback, glpdwFunAddresses, glpdwFunNames) 'Hook DeleteFileA
Call HookApi("kernel32.dll", "DeleteFileW", AddressOf DeleteFileWCallback, glpdwFunAddresses + 4, glpdwFunNames + 128) 'Hook DeleteFileW
'
CopyMemory ByVal VarPtr(dwProxyFunAddress), ByVal glpdwFunAddresses, 4
CopyMemory ByVal VarPtr(dwProxyFunAddress1), ByVal glpdwFunAddresses + 4, 4
'MsgBox "代理函数地址:" & Hex(dwProxyFunAddress) & vbNewLine & Hex(dwProxyFunAddress1)
' KillFile StrPtr("C:\123.txt")
'
RemoveHookApi "kernel32.dll", "DeleteFileA", dwProxyFunAddress
RemoveHookApi "kernel32.dll", "DeleteFileW", dwProxyFunAddress1
UnhookDllFunctionCall
' KillFile StrPtr("C:\123.txt")
' KillFileA "C:\123.txt"
End If
End Sub
module:
Attribute VB_Name = "modHookInfo"
Private Const PAGE_NOACCESS = 1
Private Const PAGE_READONLY = 2
Private Const PAGE_READWRITE = 4
Private Const PAGE_WRITECOPY = &H8
Private Const PAGE_EXECUTE = &H10
Private Const PAGE_EXECUTE_READ = &H20
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Const PAGE_EXECUTE_WRITECOPY = &H80
Private Const PAGE_GUARD = &H100
Private Const PAGE_NOCACHE = &H200
Private Const PAGE_WRITECOMBINE = &H400
Private Const MEM_COMMIT = &H1000
Private Const MEM_RELEASE = &H8000&
Public Declare Function DeleteFileW Lib "msvbvm60.dll" (ByVal lpszFileName As Long) As Long
Public Declare Function DeleteFileA Lib "msvbvm60.dll" (ByVal lpszFileName As Long) As Long
Public Declare Function ZwDeleteFile Lib "ntdll.dll" (ByVal lpszFileName As Long) As Long
Public Declare Function DbgBreakPoint Lib "ntdll.dll" () As Long
Public Declare Function KillFile Lib "kernel32" Alias "DeleteFileW" (ByVal lpszFileName As Long) As Long
Public Declare Function KillFileA Lib "kernel32" Alias "DeleteFileA" (ByVal lpszFileName As String) As Long
Public Declare Function MessageBox Lib "user32" Alias "MessageBoxW" (ByVal hWnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) 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
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
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 VirtualFree Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function VirtualAlloc Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public mszmsvbvm60 As String
Public glpdwFunAddresses As Long
Public glpdwFunNames As Long
Public glpHookFunCount As Long
Public glpdwDllFunCallProxyAddress As Long
Public gbytDllFunCallOldCode(0 To 5) As Byte
Public Function MessageBoxWCallback(ByVal hWnd As Long, ByVal lpText As Long, ByVal lpCaption As Long, ByVal wType As Long) As Long
MessageBoxWCallback = CallWindowProc(glpProxyFunAddress, hWnd, StrPtr("我改的值"), lpCaption, wType)
End Function
'DeleteFileW的处理函数
Public Function DeleteFileWCallback(ByVal lpszFileName As Long) As Long
If lstrcmpiW(lpszFileName, StrPtr("C:\234.txt")) = 0 Then
'如果检测是删除"C:\234.txt"我们就拒绝
DeleteFileWCallback = 0
Exit Function
ElseIf lstrcmpiW(lpszFileName, StrPtr("C:\123.txt")) = 0 Then
'如果删除的文件是C:\123.txt我们就让其删除C:\345.txt
DeleteFileWCallback = DeleteFileW(StrPtr("C:\345.txt"))
Exit Function
End If
DeleteFileWCallback = DeleteFileW(lpszFileName)
End Function
'DeleteFileA的处理函数
Public Function DeleteFileACallback(ByVal lpszFileName As Long) As Long
DeleteFileACallback = DeleteFileA(lpszFileName) '使用函数指针来调用原函数的功能,不然象以前就需要先恢复钩子再执行api函数DeleteFileA然后再挂钩,效率非常差也存在不安全的因素
End Function
'这段ShellCode函数反汇编码如下
'00540000 55 push ebp
'00540001 8bec mov ebp,esp
'00540003 83ec08 sub esp,8
'00540006 8b4508 mov eax,dword ptr [ebp+8]
'00540009 53 push ebx
'0054000a 56 push esi
'0054000b 8b3530504000 mov esi,dword ptr [HookInfo+0x5030 (00405030)]
'00540011 8b08 mov ecx,dword ptr [eax]
'00540013 8b4004 mov eax,dword ptr [eax+4]
'00540016 57 push edi
'00540017 8b3d2c504000 mov edi,dword ptr [HookInfo+0x502c (0040502c)]
'0054001d 681c3f2300 push 233F1Ch
'00540022 51 push ecx
'00540023 c745f800000000 mov dword ptr [ebp-8],0
'0054002a 8d9e00200000 lea ebx,[esi+2000h]
'00540030 8945fc mov dword ptr [ebp-4],eax
'00540033 b828a8f576 mov eax,offset ntdll!stricmp (76f5a828)
'00540038 ffd0 call eax '对比是不是msvbvm60.dll
'0054003a 83c408 add esp,8
'0054003d 85c0 test eax,eax
'0054003f 753e jne 0054007f
'00540041 8b4dfc mov ecx,dword ptr [ebp-4]
'00540044 51 push ecx
'00540045 56 push esi
'00540046 b828a8f576 mov eax,offset ntdll!stricmp (76f5a828)
'0054004b ffd0 call eax '对比是不是我们表内的函数
'0054004d 83c408 add esp,8
'00540050 85c0 test eax,eax
'00540052 7420 je 00540074 '如果是就取其对应函数地址
'00540054 81c680000000 add esi,80h '开始循环检测,名称表是 每次128个字节的增长
'0054005a 83c704 add edi,4 '地址表是每次4个单位的增长
'0054005d 3bf3 cmp esi,ebx
'0054005f 731e jae 0054007f '当超出检测就证明目标函数不是我们表内的函数就调用原函数获取函数地址
'00540061 8b55fc mov edx,dword ptr [ebp-4]
'00540064 52 push edx
'00540065 56 push esi
'00540066 b828a8f576 mov eax,offset ntdll!stricmp (76f5a828)
'0054006b ffd0 call eax '对比是不是我们表内的函数
'0054006d 83c408 add esp,8
'00540070 85c0 test eax,eax
'00540072 75e0 jne 00540054
'00540074 8b07 mov eax,dword ptr [edi] '获取对应函数的地址,这个地址是地址表维护的
'00540076 5f pop edi
'00540077 5e pop esi
'00540078 5b pop ebx
'00540079 8be5 mov esp,ebp
'0054007b 5d pop ebp
'0054007c c20400 ret 4
'0054007f ff7508 push dword ptr [ebp+8]
'00540082 b800025400 mov eax,540200h
'00540087 ffd0 call eax '执行原函数
'00540089 8945f8 mov dword ptr [ebp-8],eax
'0054008c 8b45f8 mov eax,dword ptr [ebp-8]
'0054008f 5f pop edi
'00540090 5e pop esi
'00540091 5b pop ebx
'00540092 8be5 mov esp,ebp
'00540094 5d pop ebp
'00540095 c20400 ret 4
'调用原始函数的,代理函数。用于获取原函数的执行结果
'00540200 55 push ebp
'00540201 8bec mov ebp,esp
'00540203 83ec0c sub esp,0Ch '执行原函数头部覆盖的几个字节代码
'*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\system32\MSVBVM60.DLL -
'00540206 b8fda09472 mov eax,offset MSVBVM60!DllFunctionCall (7294a0fd)
'0054020b 83c006 add eax,6
'0054020e ffe0 jmp eax '然后执行到原函数的第六个字节的地方,因为上面我们已经执行了原函数开始的六个字节代码