J
jingzux
Unregistered / Unconfirmed
GUEST, unregistred user!
这是我从网上看到的一个VB源程序,在VB下正常,可是转换成DELPHI后总是找不到RegisterShellHook
请高手指点。VB源程序如下:
下面的代码虽然短小,却是一个完整的能自我隐藏的日志程序(用 VB6.0实现,在 Win98下测试通过)。
;
' 窗体部分的代码(Form1.frm)
Option Explicit
Private Sub Form_Load()
Dim tmp As Long
' 将日志程序的名称从 CTRL+ALT+DEL 列表中清除
tmp = RegisterServiceProcess(ByVal 0&, 1)
Timer1.Interval = 60000 ' 定时器的作用是每隔一分钟将日志存盘
' 定义一个新的系统级的消息类型
Msg_ID = RegisterWindowMessage("SHELLHOOK")
Call RegisterShellHook(hwnd, 1) ' 调用未公开的函数(进行注册)
' 实施拦截:在存储了原入口地址的同时,将新地址指向自定义的函数WindowProc
Original = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim tmp As Long
Call RegisterShellHook(hwnd, 0) ' 调用未公开的函数(取消注册)
tmp = SetWindowLong(hwnd, GWL_WNDPROC, Original) ' 将入口地址还原
End Sub
Private Sub Timer1_Timer()
If Len(Text1.Text) > 0 Then
Open "C:/SystemLog.Sys" For Append As #1 ' 以“添加”方式打开日志
Print #1, Text1.Text ' 日志自动存盘
Text1.Text = ""
Close #1
End If
End Sub
' 模块部分的代码(模块1.bas)
Public Declare Function RegisterShellHook Lib "Shell32" Alias "#181" _
(ByVal hwnd As Long, ByVal nAction As Long) As Long
Public Declare Function RegisterWindowMessage Lib "user32" Alias _
"RegisterWindowMessageA" (ByVal lpString As String) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Public 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 Function RegisterServiceProcess Lib "kernel32" _
(ByVal dwProcessID As Long, ByVal dwType As Long) As Long
Const HSHELL_WINDOWCREATED = 1 ' 系统级的窗体被创建
Const HSHELL_WINDOWDESTROYED = 2 ' 系统级的窗体即将被关闭
'Const HSHELL_ACTIVATESHELLWINDOW = 3 ' SHELL 的主窗体将被激活(本例未用)
Const HSHELL_WINDOWACTIVATED = 4 ' 系统级的窗体被激活
'Const HSHELL_GETMINRECT = 5 ' 窗体被最大化或最小化(本例未用)
'Const HSHELL_REDRAW = 6 ' Windows 任务栏被刷新(本例未用)
'Const HSHELL_TASKMAN = 7 ' 任务列表的内容被选中(本例未用)
'Const HSHELL_LANGUAGE = 8 ' 中英文切换或输入法切换(本例未用)
Public Const GWL_WNDPROC = -4 ' 该索引用来创建窗口类的子类
Public Msg_ID As Long, Original As Long
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal _
wParam As Long, ByVal lParam As Long) As Long ' 回调函数
Dim tmp1 As String, tmp2 As String, i As Long
If uMsg = Msg_ID Then
tmp1 = String(200, "*")
i = GetWindowText(lParam, tmp1, 200) ' 取窗体的标题
If i > 0 Then tmp1 = Left(tmp1, i) Else tmp1 = "未命名"
tmp1 = tmp1 + " " + Str(Date) + " " + Str(Time) + vbCrLf ' 加入日期
' 下面对窗体句柄值进行格式化的目的是为了日志文件在视觉上更美观
tmp2 = Format(lParam, "000000")
If Right(Form1.Text1, 2) <> vbCrLf Then tmp2 = vbCrLf + tmp2
Select Case wParam
Case HSHELL_WINDOWCREATED
Form1.Text1 = Form1.Text1 + tmp2 + " 创建:" + tmp1
Case HSHELL_WINDOWDESTROYED
Form1.Text1 = Form1.Text1 + tmp2 + " 关闭:" + tmp1
Case HSHELL_WINDOWACTIVATED
Form1.Text1 = Form1.Text1 + tmp2 + " 激活:" + tmp1
' 为了程序简洁,本例仅处理“创建”、“激活”和“关闭”这三个消息,
' 其实就生成日志文件的目的,上述三个消息已基本够用。
' Case ...
' ...
End Select
Else
' 使用已被存储下来的原入口地址
WindowProc = CallWindowProc(Original, hwnd, uMsg, wParam, lParam)
End If
End Function
;
请高手指点。VB源程序如下:
下面的代码虽然短小,却是一个完整的能自我隐藏的日志程序(用 VB6.0实现,在 Win98下测试通过)。
;
' 窗体部分的代码(Form1.frm)
Option Explicit
Private Sub Form_Load()
Dim tmp As Long
' 将日志程序的名称从 CTRL+ALT+DEL 列表中清除
tmp = RegisterServiceProcess(ByVal 0&, 1)
Timer1.Interval = 60000 ' 定时器的作用是每隔一分钟将日志存盘
' 定义一个新的系统级的消息类型
Msg_ID = RegisterWindowMessage("SHELLHOOK")
Call RegisterShellHook(hwnd, 1) ' 调用未公开的函数(进行注册)
' 实施拦截:在存储了原入口地址的同时,将新地址指向自定义的函数WindowProc
Original = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim tmp As Long
Call RegisterShellHook(hwnd, 0) ' 调用未公开的函数(取消注册)
tmp = SetWindowLong(hwnd, GWL_WNDPROC, Original) ' 将入口地址还原
End Sub
Private Sub Timer1_Timer()
If Len(Text1.Text) > 0 Then
Open "C:/SystemLog.Sys" For Append As #1 ' 以“添加”方式打开日志
Print #1, Text1.Text ' 日志自动存盘
Text1.Text = ""
Close #1
End If
End Sub
' 模块部分的代码(模块1.bas)
Public Declare Function RegisterShellHook Lib "Shell32" Alias "#181" _
(ByVal hwnd As Long, ByVal nAction As Long) As Long
Public Declare Function RegisterWindowMessage Lib "user32" Alias _
"RegisterWindowMessageA" (ByVal lpString As String) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Public 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 Function RegisterServiceProcess Lib "kernel32" _
(ByVal dwProcessID As Long, ByVal dwType As Long) As Long
Const HSHELL_WINDOWCREATED = 1 ' 系统级的窗体被创建
Const HSHELL_WINDOWDESTROYED = 2 ' 系统级的窗体即将被关闭
'Const HSHELL_ACTIVATESHELLWINDOW = 3 ' SHELL 的主窗体将被激活(本例未用)
Const HSHELL_WINDOWACTIVATED = 4 ' 系统级的窗体被激活
'Const HSHELL_GETMINRECT = 5 ' 窗体被最大化或最小化(本例未用)
'Const HSHELL_REDRAW = 6 ' Windows 任务栏被刷新(本例未用)
'Const HSHELL_TASKMAN = 7 ' 任务列表的内容被选中(本例未用)
'Const HSHELL_LANGUAGE = 8 ' 中英文切换或输入法切换(本例未用)
Public Const GWL_WNDPROC = -4 ' 该索引用来创建窗口类的子类
Public Msg_ID As Long, Original As Long
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal _
wParam As Long, ByVal lParam As Long) As Long ' 回调函数
Dim tmp1 As String, tmp2 As String, i As Long
If uMsg = Msg_ID Then
tmp1 = String(200, "*")
i = GetWindowText(lParam, tmp1, 200) ' 取窗体的标题
If i > 0 Then tmp1 = Left(tmp1, i) Else tmp1 = "未命名"
tmp1 = tmp1 + " " + Str(Date) + " " + Str(Time) + vbCrLf ' 加入日期
' 下面对窗体句柄值进行格式化的目的是为了日志文件在视觉上更美观
tmp2 = Format(lParam, "000000")
If Right(Form1.Text1, 2) <> vbCrLf Then tmp2 = vbCrLf + tmp2
Select Case wParam
Case HSHELL_WINDOWCREATED
Form1.Text1 = Form1.Text1 + tmp2 + " 创建:" + tmp1
Case HSHELL_WINDOWDESTROYED
Form1.Text1 = Form1.Text1 + tmp2 + " 关闭:" + tmp1
Case HSHELL_WINDOWACTIVATED
Form1.Text1 = Form1.Text1 + tmp2 + " 激活:" + tmp1
' 为了程序简洁,本例仅处理“创建”、“激活”和“关闭”这三个消息,
' 其实就生成日志文件的目的,上述三个消息已基本够用。
' Case ...
' ...
End Select
Else
' 使用已被存储下来的原入口地址
WindowProc = CallWindowProc(Original, hwnd, uMsg, wParam, lParam)
End If
End Function
;