分享
 
 
 

深入浅出HOOKS(之伍)

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

用消息拦截技术制作系统日志

康帕斯(中国)国际信息服务有限公司 马文骞

01-6-7 下午 03:33:05

--------------------------------------------------------------------------------

能够完整记录电脑使用情况的日志文件在 Windows系统安全管理方面的作用是不可低估的。本文介绍了利用消息拦截技术制作日志文件的方法,其中的关键函数是一个未公开的 API系统调用。

一、利用钩子(Hook)拦截系统消息

日志文件对于一个大企业内部网络的维护与管理是至关重要的。另外还有许多其它场合也离不开日志的使用,例如:多人共享一台电脑,或在家庭中要记录儿童使用电脑的细节,等等。

日志程序若想完整记录电脑运行期间有哪些软件启动过、各使用了多长时间、以及使用浏览器访问互联网的情况等,必须对系统级消息进行拦截。RegisterShellHook是一个未公开的 API系统函数,它可以帮助日志程序在整个 Windows系统范围内感知到其它窗体的创建、激活或关闭等消息,而且不要求这些窗体与日志程序有父子关系,哪怕是 Windows最高级别的窗体也可以。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,以便其在 Windows的任务栏中不出现。最后,为了在 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参数置为空值,其含义是用当前程序的进程标识作为参数(见下例)。

另外,为了让日志程序在 Windows每次启动时都能自动运行,需要修改注册表,即在注册表的下述位置新建一个以日志程序的路径及名称为值的“串值”:

\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\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 ' 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

下面列出的即为上述日志程序所产生的日志文件(长约十分钟的片段)。从中可以看出在该时间段内的电脑使用情况:曾拨号上网、浏览过“计算机世界”、收过邮件、访问过注册表等。左列的数字是相应窗体的句柄。

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 关闭:未命名 01-6-6 16:13:13

下载程序!

(网页编辑:徐向阳)

相关文章

用屏幕取词技术实现动态标注

几种注册ODBC数据源的方法

在VB中播放Flash动画

对Windows网络权限机制的改进

用VB6控制Excel处理数据

您的姓名: 您朋友的E-mail:

[关闭窗口]

--------------------------------------------------------------------------------

Copyright(C) ccw.com.cn,All rights reserved

中国计算机世界出版服务公司版权所有

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有