VB函数指针的应用(源码)
昨晚发了 “大事件,大事件,VB爱好者们都进来”http://topic.csdn.net/u/20100714/21/2EB7710E-A691-482B-8F43-0B2268283CF8.html反映很不错,看来大家对于vb的爱好不减,我也深深感动中,但是很多朋友都要求有测试程序,但是由于我最近忙,时间也不多,就稍微整理了下给大家把代码及测试程序发出来,希望有心人能把它封装好造福广大VB爱好者,让VB也疯狂起来,让我们大家继续挖掘vb无限的潜力。由于时间问题,代码注释不是很详细,望大家见谅,我也废话不说了,就贴代码吧!
form:VERSION 5.00Begin VB.Form frmMain Caption = "Hook 测试" ClientHeight = 3030 ClientLeft = 120 ClientTop = 450 ClientWidth = 4560 LinkTopic = "Form1" ScaleHeight = 3030 ScaleWidth = 4560 StartUpPosition = 3 '窗口缺省EndAttribute VB_Name = "frmMain"Attribute VB_GlobalNameSpace = FalseAttribute VB_Creatable = FalseAttribute VB_PredeclaredId = TrueAttribute VB_Exposed = FalseOption ExplicitPrivate 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 Submodule:Attribute VB_Name = "modHookInfo"Private Const PAGE_NOACCESS = 1Private Const PAGE_READONLY = 2Private Const PAGE_READWRITE = 4Private Const PAGE_WRITECOPY = &H8Private Const PAGE_EXECUTE = &H10Private Const PAGE_EXECUTE_READ = &H20Private Const PAGE_EXECUTE_READWRITE = &H40Private Const PAGE_EXECUTE_WRITECOPY = &H80Private Const PAGE_GUARD = &H100Private Const PAGE_NOCACHE = &H200Private Const PAGE_WRITECOMBINE = &H400Private Const MEM_COMMIT = &H1000Private Const MEM_RELEASE = &H8000&Public Declare Function DeleteFileW Lib "msvbvm60.dll" (ByVal lpszFileName As Long) As LongPublic Declare Function DeleteFileA Lib "msvbvm60.dll" (ByVal lpszFileName As Long) As LongPublic Declare Function ZwDeleteFile Lib "ntdll.dll" (ByVal lpszFileName As Long) As LongPublic Declare Function DbgBreakPoint Lib "ntdll.dll" () As LongPublic Declare Function KillFile Lib "kernel32" Alias "DeleteFileW" (ByVal lpszFileName As Long) As LongPublic Declare Function KillFileA Lib "kernel32" Alias "DeleteFileA" (ByVal lpszFileName As String) As LongPublic Declare Function MessageBox Lib "user32" Alias "MessageBoxW" (ByVal hWnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As LongPrivate 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 LongPublic 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 LongPrivate Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As LongPrivate Declare Function VirtualProtect Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As LongPrivate Declare Function VirtualFree Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As LongPrivate Declare Function VirtualAlloc Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As LongPrivate Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)Public mszmsvbvm60 As StringPublic glpdwFunAddresses As LongPublic glpdwFunNames As LongPublic glpHookFunCount As LongPublic glpdwDllFunCallProxyAddress As LongPublic gbytDllFunCallOldCode(0 To 5) As BytePublic 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 '然后执行到原函数的第六个字节的地方,因为上面我们已经执行了原函数开始的六个字节代码
[解决办法]
你,厉害,俺佩服的六体投地
[解决办法]
[解决办法]
[解决办法]
学习学习
[解决办法]
顶起
玩玩看
[解决办法]
不错,参数问题解决了,顶.
[解决办法]
顶...
[解决办法]
膜拜ing~~~~~~~~~
[解决办法]
太长了,先留个脚印,不过支持楼主的精神!
[解决办法]
顶…………
[解决办法]
额的神啊~
[解决办法]
应该一起推荐才对,明显了大家就方便注意了