用消息拦截技术制作系统日志
来源:互联网 发布:网络节点加速器 编辑:程序博客网 时间:2024/06/13 05:36
能够完整记录计算机使用情况的日志文件在 视窗系统系统安全管理方面的作用是不可低估的。本文介绍了利用消息拦截技术制作日志文件的方法,其中的关键函数是个未公开的 API系统调用。
一、利用钩子(Hook)拦截系统消息
日志文件对于一个大企业内部网络的维护和管理是至关重要的。另外更有许多其他场合也离不开日志的使用,例如:多人共享一台计算机,或在家庭中要记录儿童使用计算机的细节,等等。
日志程式若想完整记录计算机运行期间有哪些软件启动过、各使用了多长时间、及使用浏览器访问互连网的情况等,必须对系统级消息进行拦截。 RegisterShellHook是个未公开的 API系统函数,他能帮助日志程式在整个视窗系统系统范围内感知到其他窗体的创建、激活或关闭等消息,而且不需求这些窗体和日志程式有父子关系,哪怕是 视窗系统最高级别的窗体也能。RegisterShellHook 调用方法为:
Public Declare Function RegisterShellHook Lib "Shell32" Alias"#181" _
(ByVal hwnd As Long, ByVal nAction As Long) As Long
其中参数hwnd为日志程式的句柄,参数 nAction为所要进行操作的代码。具体的调用细节参见下面的例子及其注释。
二、将日志程式隐藏起来
把日志程式的Visible属性设为False当然是必要的一步。然后是 ShowInTaskbar属性也设为 False,以便其在 视窗系统的任务栏中不出现。最后,为了在 CTRL+ALT+DEL 所弹出的列表中隐藏日志程式,需要调用RegisterServiceProcess函数:
Public Declare Function RegisterServiceProcess Lib "kernel32" _
(ByVal dwProcessID As Long, ByVal dwType As Long) As Long
其中参数dwType是操作代码,值“1”表示从CTRL+ALT+DEL列表中去除,值“0”表示在列表中恢复;参数 dwProcessID是要在列表中去除或恢复的进程标识,能用GetCurrentProcessId()API 函数得到日志程式的进程标识,也能用更简便的方法,即把 dwProcessID参数置为空值,其含义是用当前程式的进程标识作为参数(见下例)。
另外,为了让日志程式在 视窗系统每次启动时都能自动运行,需要修改注册表,即在注册表的下述位置新建一个以日志程式的路径及名称为值的“串值”:
\HKEY_LOCAL_MACHINE\Software\Microsoft\视窗系统\CurrentVersion\Run
此外,产生的日志文件也应妥为隐藏,最佳用 Winsock控件随时向服务器传送。
为了简洁,下面的例子仅将日志文件放在了根目录,并且略去了用TCP/IP传送文件的代码。
三、一个完整的例子
下面的代码虽然短小,却是个完整的能自我隐藏的日志程式(用 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 ’ 视窗系统 任务栏被刷新(本例未用)
’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
下面列出的即为上述日志程式所产生的日志文件(长约十分钟的片段)。从中能看出在该时间段内的计算机使用情况:曾拨号上网、浏览过“计算机世界”、收过邮件、访问过注册表等。左列的数字是相应窗体的句柄。
002624 激活:Project1 - Microsoft Visual Basic [设计]
002624 关闭:Microsoft Visual Basic [设计]
001692 创建:正在连接到 95963
001692 激活:正在连接到 95963
003512 关闭:Hotmail - 通行全球的免费 Web电子邮件 - Microsoft Internet Explorer
001880 创建:未命名 01-6-6 16:01:25
001880 激活:未命名 01-6-6 16:01:25
001880 激活:计算机世界网-应用和方案-首页 - Microsoft Internet Explorer
001880 激活:计算机世界网-应用和方案-应用编程 - Microsoft Internet Explorer
003488 创建:Microsoft Internet Explorer 01-6-6 16:07:40
003488 激活:Microsoft Internet Explorer 01-6-6 16:07:41
003488 关闭:计算机世界网-用屏幕取词技术实现动态标注- Microsoft Internet Explorer
001880 激活:计算机世界网-e海航标-首页 - Microsoft Internet Explorer
001880 关闭:计算机世界网-e海航标-首页 - Microsoft Internet Explorer
001132 激活:浏览 - C:\
001132 关闭:浏览 - C:\
002772 创建:Outlook Express 01-6-6 16:10:41
002772 激活:Outlook Express 01-6-6 16:10:41
002772 激活:收件箱 - Outlook Express
002772 关闭:收件箱 - Outlook Express
003920 关闭:浏览 - 我的计算机
000640 创建:注册表编辑器
000640 激活:注册表编辑器
000640 关闭:注册表编辑器
003756 创建:未命名 01-6-6 16:11:30
003756 关闭:未命名 01-6-6 16:11:30
001328 创建:网络监视器
001328 激活:网络监视器
001328 激活:网络监视器 - 0 连接到 \\CD_PROGRAM
001328 关闭:网络监视器 - 0 连接到 \\CD_PROGRAM
002700 关闭:连接到 95963
001804 关闭:未命名
- 用消息拦截技术制作系统日志
- C#拦截系统消息
- Windows消息拦截技术的应用
- Windows消息拦截技术的应用
- Windows消息拦截技术的应用
- javascript发表日志系统制作
- C# 重写WndProc 拦截 发送 系统消息
- Android 中利用XPosed拦截系统消息
- Struts2拦截器实现日志管理系统
- Struts2拦截器实现日志管理系统
- struts+mybatis 拦截器系统日志生成
- C#制作一个消息拦截器(intercept)1
- C#制作一个消息拦截器(intercept)2
- C#制作一个消息拦截器(intercept)3
- C#制作一个消息拦截器(intercept)4
- 用BCB拦截Windows消息
- Hook技术之消息拦截(Windows Hook )
- 用Spring写系统日志(AOP技术)
- 怎么也想不到能在昆明待这么长时间!
- 在Windows 64位操作系统安装Weblogic的注意事项
- 无题
- sphinx代码结构
- SSH(struts 1.x+spring 2.5+hibernate 3.2)开发文件配置
- 用消息拦截技术制作系统日志
- breakpad
- jfreechart显示具体数值
- 文件上传后Apusic应用服务器内存溢出并宕机的一种处理方式
- 转:windows下Critical Section、Event、Mutex、Semaphores区别 收
- Can't open file 'svn/db/txn-current-locks':permission denied
- javascript显示对象所有属性的方法
- 第6章 包含多个段的程序 笔记
- Subversion如何刪除檔案庫