VB函数指针的应用(源码)

chenhui530 2010-07-15 10:39:13
加精
昨晚发了 “大事件,大事件,VB爱好者们都进来”http://topic.csdn.net/u/20100714/21/2EB7710E-A691-482B-8F43-0B2268283CF8.html反映很不错,看来大家对于vb的爱好不减,我也深深感动中,但是很多朋友都要求有测试程序,但是由于我最近忙,时间也不多,就稍微整理了下给大家把代码及测试程序发出来,希望有心人能把它封装好造福广大VB爱好者,让VB也疯狂起来,让我们大家继续挖掘vb无限的潜力。由于时间问题,代码注释不是很详细,望大家见谅,我也废话不说了,就贴代码吧!

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 '然后执行到原函数的第六个字节的地方,因为上面我们已经执行了原函数开始的六个字节代码
...全文
2760 130 打赏 收藏 转发到动态 举报
写回复
用AI写文章
130 条回复
切换为时间正序
请发表友善的回复…
发表回复
王二.麻子 2011-04-26
  • 打赏
  • 举报
回复
全局hook也在这个基础上呀。全局比这个多出来获取其他dll内存读写权限,确定需要hook的位置这2个步骤,后面一样是写入其他dll空间插入jmp代码。

就想老马说的,自己弄汇编,shellcode解决参数入栈也应该可以实现函数指针,这个封装就简单了很多步骤。

我其实是来留记号的
nanfei01055 2010-11-15
  • 打赏
  • 举报
回复
这个如何实现全局Hook,看样子还只是Hook了VB进程内的函数Hook,怎么实现全局的,VB进程内部很容易实现的。
嗷嗷叫的老马 2010-08-02
  • 打赏
  • 举报
回复
[Quote=引用 124 楼 vbadvisor 的回复:]
看看这个"Hook Win32 API Functions: includes a sample of customizing VB DTPicker by hooking GetLocaleInfo",如果不能证明是Hook API function,请不要骂我。
http://www.pscode.com/vb/scripts/ShowCode.asp?txtCodeId=31105&lngWId=1[/Quote]
我说下我的理解:

其实这份代码并不是为了说明一种HOOK API的方法.

而是利用HOOK API,进行类似函数指针的应用.

比如,你现在有一个DLL,里面已知一个地址是某个函数的入口,但是并未导出,这时想调用的话,得loadlibrary后再callwindowproc或自己写Shell Code,解决参数入栈,才行.

而现在这个代码,可以使用一套比较通用的方式完成这一套,并且由于不用管参数入栈,方便了.

对于会写Shell Code的人来说,自己压个栈当然不是什么问题,只是,麻烦不?

所以我觉得,这个代码就是给懒人用的,哈哈.
zzyong00 2010-08-01
  • 打赏
  • 举报
回复
又是shellcode..........
膜拜
chenhui530 2010-08-01
  • 打赏
  • 举报
回复
[Quote=引用 124 楼 vbadvisor 的回复:]
引用 87 楼 chenhui530 的回复:

引用 85 楼 vbadvisor 的回复:
引用 84 楼 chenhui530 的回复:

引用 83 楼 vbadvisor 的回复:
引用 81 楼 chenhui530 的回复:

用人实现了?给我地址看看

看看这个"Hook Win32 API Functions: includes a sample of cus……
[/Quote]

这个是输入表hook,并没有实现函数指针的功能
VBAdvisor 2010-08-01
  • 打赏
  • 举报
回复
[Quote=引用 87 楼 chenhui530 的回复:]

引用 85 楼 vbadvisor 的回复:
引用 84 楼 chenhui530 的回复:

引用 83 楼 vbadvisor 的回复:
引用 81 楼 chenhui530 的回复:

用人实现了?给我地址看看
[/Quote]
看看这个"Hook Win32 API Functions: includes a sample of customizing VB DTPicker by hooking GetLocaleInfo",如果不能证明是Hook API function,请不要骂我。
http://www.pscode.com/vb/scripts/ShowCode.asp?txtCodeId=31105&lngWId=1

Simon217 2010-07-31
  • 打赏
  • 举报
回复
原来还可以这样。。。
Gujianda 2010-07-31
  • 打赏
  • 举报
回复
抱歉!问错了,是我的错,模块里的代码没有贴全。
Gujianda 2010-07-31
  • 打赏
  • 举报
回复
InitHook 这个波尔变量在哪定义了?
myjisgreat 2010-07-30
  • 打赏
  • 举报
回复
太强大了
shishusheng1010 2010-07-28
  • 打赏
  • 举报
回复
学习了
嗷嗷叫的老马 2010-07-28
  • 打赏
  • 举报
回复
http://www.m5home.com/bbs/thread-3965-1-1.html

已经更新,可以在IDE里调试了
xuliu 2010-07-27
  • 打赏
  • 举报
回复
先顶下,在学VBA,这个对我来说可能难了点,不过非常感谢,将来可能用到
hllsoul 2010-07-27
  • 打赏
  • 举报
回复
挣个分下东西
shangxiaoxiang 2010-07-27
  • 打赏
  • 举报
回复
不错。。。。
xh_linyu_0324 2010-07-26
  • 打赏
  • 举报
回复
royallyliyuan 2010-07-26
  • 打赏
  • 举报
回复
写得太有深意了!
lyingbo 2010-07-26
  • 打赏
  • 举报
回复
学习下了
sky0036 2010-07-26
  • 打赏
  • 举报
回复
anypsky 2010-07-25
  • 打赏
  • 举报
回复
果然博大精深!
加载更多回复(101)

1,486

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧