HOOK监控任务管理器
- 格式:docx
- 大小:17.88 KB
- 文档页数:7
基于HOOK技术的监控软件设计
张勇;邢红宏;张继磊
【期刊名称】《计算机应用与软件》
【年(卷),期】2009(026)002
【摘要】介绍了Windows系统钩子的运行机制,给出了在Delphi编辑环境中利用WH_CALLWNDPROCXITONG系统钩子实现对特定窗口的创建和销毁消息进行截获和处理的具体实现方法,解决了在软件源代码未知的前提下对软件实施外围监控的问题.该种方法可应用于软件运行状态监控、IE广告过滤,软件助手制作等领域.
【总页数】3页(P120-121,124)
【作者】张勇;邢红宏;张继磊
【作者单位】海军航空工程学院基础实验部,山东,烟台,264001;海军航空工程学院基础实验部,山东,烟台,264001;海军航空工程学院基础实验部,山东,烟台,264001【正文语种】中文
【中图分类】TP3
【相关文献】
1.基于Filter-Hook技术的防火墙软件设计与实现 [J], 潘瑜
2.基于HOOK技术的实验室软件监控系统研究 [J], 杨竹青
3.基于HOOK技术的本地打印监控系统开发 [J], 李华来;刘载文;许继平;戴军;陈晨
4.基于HOOK API技术的进程监控系统设计与实现 [J], 徐江峰;邵向阳
5.恶意脚本程序研究以及基于API HOOK的注册表监控技术 [J], 李珂洓;宁超
因版权原因,仅展示原文概要,查看原文内容请购买。
hook技术--代码hook1.简介:对于IAT hook ⽅法,它只能hook掉在iat中的API,如果是通过动态加载的就不⾏了因为动态加载的dll的API不在iat中,⽽是动态⽣成的.这时可以预先加载该dll和API,并对API前⼏个字节进⾏保存然后修改成跳转到⾃⼰的某函数中,然后进⾏⼀些操作后可以再跳回到原来的API.这就是所谓的API修改hook.2.以hook掉任务管理器的进程遍历功能,为例,⽤此来隐藏calc.exe这个进程windows上ring3层的遍历进程API底层都调⽤了ZwQuerySystemInformation 函数该函数在ntdll中,但没有公开在⽹上寻找该API的参数和返回值信息,在代码中体现代码思路是: 先获取ZwQuerySystemInformation的地址,保存前5个字节的代码. 再覆盖为⼀个跳转到我们实现的⼀个伪ZwQuerySystemInformation函数地址的jmp指令的机器代码.在我们的函数中找到calc.exe的进程名,然后再跳过这个节点即可.#include "stdafx.h"#include <Windows.h>#include <wchar.h>#include <malloc.h>#include<stdio.h>#define funcName "ZwQuerySystemInformation"#define dllName "ntdll.dll"#define processName L"calc.exe"typedef LONG NTSTATUS;typedef enum _SYSTEM_INFORMATION_CLASS {SystemBasicInformation = 0,SystemPerformanceInformation = 2,SystemTimeOfDayInformation = 3,SystemProcessInformation = 5,SystemProcessorPerformanceInformation = 8,SystemInterruptInformation = 23,SystemExceptionInformation = 33,SystemRegistryQuotaInformation = 37,SystemLookasideInformation = 45} SYSTEM_INFORMATION_CLASS;typedef struct _SYSTEM_PROCESS_INFORMATION {ULONG NextEntryOffset;ULONG NumberOfThreads;BYTE Reserved1[48];PVOID Reserved2[3];HANDLE UniqueProcessId;PVOID Reserved3;ULONG HandleCount;BYTE Reserved4[4];PVOID Reserved5[11];SIZE_T PeakPagefileUsage;SIZE_T PrivatePageCount;LARGE_INTEGER Reserved6[6];} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;typedef NTSTATUS(WINAPI *PFZWQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength,PULONG ReturnLength);BYTE orgCode[5];//原始指令BYTE fakeCode[5]; //伪造的jmp指令DWORD funcBase; //我们的函数基址// char debug[100]={0};DWORD WINAPI myZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength,PULONG ReturnLength);DWORD hook(DWORD funcbase, DWORD fakeFunc);DWORD unhook(DWORD funcbase);BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved){ //获取⽬标函数基址和伪造函数基址DWORD fakeFunc;funcBase = (DWORD)GetProcAddress(GetModuleHandleA(dllName), funcName);fakeFunc = (DWORD)myZwQuerySystemInformation;switch (ul_reason_for_call){case DLL_PROCESS_ATTACH: //加载时就hook掉hook(funcBase, fakeFunc);break;case DLL_PROCESS_DETACH:unhook(funcBase);break;}return TRUE;}DWORD hook(DWORD funcbase, DWORD fakeFunc){DWORD page;//如果已经被hook了就不再继续if(*(BYTE*)funcbase==0xe9){return0;}VirtualProtect((LPVOID)funcbase, 5, PAGE_EXECUTE_READWRITE, &page);memcpy(orgCode, (LPVOID)funcbase, 5);fakeCode[0] = 0xe9;DWORD opCode = fakeFunc -funcBase - 5;//jmp指令的操作码计算公式为:⽬标地址-当前指令地址-5 // sprintf(debug,"hook fakeFunc is %p, funcbase is %p",fakeFunc,funcbase);memcpy(fakeCode + 1, &opCode, 4);//填充为指令memcpy((LPVOID)funcBase, fakeCode, 5); //修改代码VirtualProtect((LPVOID)funcbase, 5, page, &page);return1;}DWORD unhook(DWORD funcbase){DWORD page;if(*(BYTE*)funcbase!=0xe9){return0;}VirtualProtect((LPVOID)funcbase, 5, PAGE_EXECUTE_READWRITE, &page);memcpy((LPVOID)funcBase, orgCode, 4); //恢复代码VirtualProtect((LPVOID)funcbase, 5, page, &page);return1;}DWORD WINAPI myZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength,PULONG ReturnLength)/*这个函数的hook和⼀般的函数不同,这种函数属于查询类的函数,真正有⽤的信息在该函数调⽤完了后才会写到缓冲区类的参数,⽽调⽤前的参数信息基本没⽤,因此我们要对该函数进⾏正常调⽤,完后了再截取信息*/{DWORD fakeFunc;funcBase = (DWORD)GetProcAddress(GetModuleHandleA(dllName), funcName);fakeFunc = (DWORD)myZwQuerySystemInformation;PSYSTEM_PROCESS_INFORMATION p, pPre;unhook(funcBase); //取消hook以正常调⽤DWORD status=4;status=((PFZWQUERYSYSTEMINFORMATION)funcBase)(SystemInformationClass,SystemInformation,SystemInformationLength,ReturnLength);//正常调⽤该函数if(status!=0){hook(funcBase, fakeFunc); //hook住return0;}if (SystemInformationClass== SystemProcessInformation) //只对查询进程的信息感兴趣 {p = ((PSYSTEM_PROCESS_INFORMATION)SystemInformation);while (1){if(p->Reserved2[1]!=0){if (lstrcmpiW((WCHAR*)p->Reserved2[1], processName)==0){if (p->NextEntryOffset==0)//说明是最后⼀个了{pPre->NextEntryOffset = 0; //将后⾯⼀个节点的next指针置0即可}else{//跳过本节点 NextEntryOffset字段是相对于本节点的偏移,⽽不是绝对地址 //当当前节点是第⼀个节点时这个式⼦也成⽴pPre->NextEntryOffset += p->NextEntryOffset;}}else{pPre = p;}}if(p->NextEntryOffset==0){break;}p =((PSYSTEM_PROCESS_INFORMATION)((DWORD)p + p->NextEntryOffset)); }}hook(funcBase, fakeFunc); //hook住return1;}。
基于SSDT HOOK技术的Ring0级进程保护组件设计与实现北京理工大学12110606 杨蛟龙(jiaolong@)摘要本文介绍了Windows下利用SSDT(系统服务描述符表)HOOK技术实现对进程的保护功能——包括进程信息隐藏(进程防打开)和进程防结束——的原理,同时介绍了通过开发Windows驱动程序的方式获得Ring0级权限实现对SSDT的读取操作,以及进程保护组件的DLL封装、接口定义;最后通过对组件的测试验证了SSDT HOOK技术实现进程保护的有效性以及本组件的可用性及可移植性。
关键字:SSDT,Hook,驱动,Ring0,进程保护目录1.背景介绍 (3)2.SSDT Hook技术 (4)2.1SSDT简介 (4)2.2进程保护功能分析 (5)2.3SSDT HOOK实现 (6)2.4钩子函数实现 (9)3.内核驱动程序 (11)3.1WDM基本结构 (11)3.2驱动程序开发 (12)4.组件封装 (15)4.1DLL简介 (15)4.2DLL开发 (16)5.组件测试 (18)5.1MFC程序调用测试 (18)5.2C#.Net程序调用测试 (20)6.参考文献 (21)1.背景介绍进程保护这一思想很早就出现,现在大多数的杀毒软件等安全防护软件均带有对自身进程保护的功能,这是为了防止病毒等恶意程序破坏进程的运行。
相对的,很多病毒为了防止被发现或终止,提高自己的运行权限,隐藏自己、保护自己不被终止。
然而并不是只有病毒及杀毒软件有对自己的进程进行保护的需求,很多软件,如网吧、机房等的监控系统、计费系统等,以及一些必须确保自身运行过程中不被强行中断,否则会导致数据丢失、操作系统崩溃等严重后果的软件系统,都需要对自身进行必要的防护,防止恶意行为或者操作者的误操作引起的损失。
高权限的进程保护关系到操作系统底层,并不是所有语言都容易开发高权限进程保护功能,尤其是基于代码托管的语言。
目前,实现进程保护的软件均将进程保护功能嵌入在软件内,没有专门的组件提供进程保护功能。
hook函数的作用Hook函数的作用Hook函数是一种在软件开发中常用的技术,它可以在程序运行过程中监控并拦截某些事件或动作,并执行特定的操作。
这种技术通常用于系统级软件中,例如操作系统、防火墙、病毒扫描器等,也可应用于应用程序中的某些功能模块。
Hook函数的作用主要有以下几个方面:一、拦截和监控系统事件Hook函数可以用于拦截和监控系统事件,例如鼠标、键盘、窗口等事件。
通过这种方式,可以实现响应特定事件的定制化操作。
例如,用户可以自定义鼠标右键点击的功能,或者在窗口关闭时自动保存数据等。
二、修改系统行为Hook函数还可以用于修改系统行为。
例如,当系统启动时,Hook函数可以在系统加载完成后自动运行特定程序,或者隐藏和取消某些系统图标和菜单。
此外,Hook还可以监控并限制特定程序的行为,以确保系统的安全性和稳定性。
三、防止恶意软件攻击Hook函数可以作为防御恶意软件攻击的一种手段。
例如,在浏览器中使用Hook函数来拦截恶意网站的访问,或者在电子邮件程序中拦截携带病毒的邮件。
通过这种方法,可以有效防止恶意软件对系统的破坏和安全威胁。
四、加速程序响应速度Hook函数还可以用于加速程序响应速度。
例如,在玩游戏时,Hook 可以实时监控用户的输入操作,并在用户输入后立即响应,从而获得更好的游戏体验。
此外,Hook还可以优化程序内存的使用,缩短程序加载时间等。
总体来说,Hook函数是一种非常强大的工具,它可以为开发人员提供很多灵活的解决方案。
虽然Hook函数非常有用,但使用不当也可能会带来风险和安全问题。
因此,在使用Hook函数之前,应该仔细评估其安全性和正确性,并尽可能保证代码的完整性和安全性。
总结起来:Hook函数是一种能够在程序运行过程中进行事件拦截、系统行为修改、恶意软件攻击防御、程序响应加速等功能的技术,它可以为开发人员提供很多灵活的解决方案,但使用不当也可能会带来风险和安全问题。
本文将试图以下面的顺序讲解HOOK的大部分内容:1、 WINDOWS的消息机制2、 HOOK介绍3、 HOOK链4、 HOOK钩子的作用范围5、 HOOK类型6、回调函数7、 HOOK钩子的安装与卸载8、 HOOK实例演示+++++++++++++++++++WINDOWS的消息机制+++++++++++++++++++Windows系统是以消息处理为其控制机制,系统通过消息为窗口过程(windowsprocedure)传递输入。
系统和应用两者都可以产生消息。
对于每个输入事件,例如用户按下了键盘上的某个键、移动了鼠标、单击了一个控件上的滚动条,等等,系统都将产生一系列消息。
此外,对于应用带给系统的变化,如字体资源的改变、应用本身窗口的改变,系统都将通过消息以响应这种变化。
应用通过产生消息指示应用的窗口完成特定的任务,或与其他应用的窗口进行通信。
每个窗口都有一个处理Windows系统发送消息的处理程序,称为窗口程序。
它是隐含在窗口背后的一段程序脚本,其中包含对事件进行处理的代码。
Windows系统为每条消息指定了一个消息编号,例如当一个窗口变为活动窗口时,它事实上是收到一条来自Windows系统的WM_ACTIVATE消息,该消息的编号为6,它对应于VB窗口的Activate事件。
对于窗口来说,诸如Open、Activate、MouseDown、Resize 等事件,实际上对应的是窗口内部的消息处理程序,这些程序对于用户来讲是不可见的。
类似地,命令按钮也有消息处理程序,它的处理程序响应诸如WM_LBUTTONDOWN和WM_RBUTTONDOWN之类的消息,即激活命令按钮的MouseDown事件。
WINDOWS的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供了挂接各种回调函数(HOOK)的功能。
这种挂钩函数(HOOK)类似扩充中断驱动程序,挂钩上可以挂接多个反调函数构成一个挂接函数链。
HOOK监控任务管理器思路:其实比较简单,还是利用DLL,首写跟据API函数OpenProcess与TerminateProcess的结构自已编写两个与这两个API一样的函数,再利用GetProcAddress获取系统的那两个API函数入口地址,最后用WriteProcessMemory将你写的函数的地址替换掉原来系统的函数地址。
这样所有调用这两系统API都将先执行你的函数。
如果只Hook其中一个函数比如只hook OpenProcess的话那么任务管理器将不能获取到你的进程信息那么会出错。
如果只hook TerminateProcess那样也不行,因为一个进程的句柄在本进程与别的进程中是不一样的,所以如果你不知道自已进程在别人进程中的句柄那么是没办法hook TerminateProcess的。
本例中首先利用OpenProcess获取自已在别的进程中的句柄,然后hook TerminateProcess进程监控,如果发现有程序调用TerminateProcess并且所结束的对象正是自已,那么就给出提示窗口。
貌似讲了一大堆废话。
还是看代码直接------------------------------------------------调用部分unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;typeTForm1 = class(TForm)Button1: TButton;Button2: TButton;procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;procedure StartHook(pid: DWORD); stdcall; external 'hookdll.dll';procedure EndHook; stdcall; external 'hookdll.dll';implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);beginStartHook(GetCurrentProcessId);end;procedure TForm1.Button2Click(Sender: TObject);beginEndHook;end;end.-----------------------------------------------------------------------------------------DLL文件,全部实现都在这里--------------------- Hookdll.dprlibrary Hookdll;usesSysUtils,Classes,Windows,Dialogs,unitHook in 'unitHook.pas';constHOOK_MEM_FILENAME = 'tmp.hkt';varhhk: HHOOK;Hook: array[0..2] of TNtHookClass;//内存映射MemFile: THandle;startPid: PDWORD; //保存PIDfhProcess: THandle; //保存本进程在远程进程中的句柄//拦截 OpenProcessfunction NewOpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THand le; stdcall;typeTNewOpenProcess = function (dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): T Handle; stdcall;beginif startPid^ = dwProcessId then beginHook[1].UnHook;Result := TNewOpenProcess(Hook[1].BaseAddr)(dwDesiredAccess, bInheritHandle, dwProcessId);fhProcess:=Result;Hook[1].Hook;exit;end;Hook[1].UnHook;Result := TNewOpenProcess(Hook[1].BaseAddr)(dwDesiredAccess, bInheritHandle, dwProcessId);Hook[1].Hook;end;function NewTerminateProcess(hProcess: THandle;uExitCode: UINT): BOOL; Stdcall;typeTNewTerminateProcess = function (hProcess: THandle;uExitCode: UINT): BOOL; Stdcall;beginif fhProcess = hProcess then beginshowmessage('不准关闭我!');result := true;exit;end;Hook[2].UnHook;Result := TNewTerminateProcess(Hook[2].BaseAddr)(hProcess, uExitCode );Hook[2].Hook;end;procedure InitHook; //安装 HookbeginHook[1] := TNtHookClass.Create('kernel32.dll', 'OpenProcess', @NewOpenProcess);hook[2] := TNtHookClass.Create('kernel32.dll', 'TerminateProcess', @NewTerminateProcess);end;procedure UninitHook; //删除 HookvarI: Integer;beginfor I := 0 to High(Hook) dobeginFreeAndNil(Hook[I]);end;end;procedure MemShared();beginMemFile:=OpenFileMapping(FILE_MAP_ALL_ACCESS,False, HOOK_MEM_FILENAME); //打开内存映射文件if MemFile = 0 then beginMemFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 4, HOOK_MEM_FILENAME);end;if MemFile <> 0 then//映射文件到变量startPid := MapViewOfFile(MemFile,FILE_MAP_ALL_ACCESS,0,0,0); end;//传递消息function HookProc(nCode, wParam, lParam: Integer): Integer; stdcall;beginResult := CallNextHookEx(hhk, nCode, wParam, lParam);end;//开始HOOKprocedure StartHook(pid: DWORD); stdcall;beginstartPid^ := pid;hhk := SetWindowsHookEx(WH_CALLWNDPROC, HookProc, hInstance, 0); end;//结束HOOKprocedure EndHook; stdcall;beginif hhk <> 0 thenUnhookWindowsHookEx(hhk);end;//环境处理procedure DllEntry(dwResaon: DWORD);begincase dwResaon ofDLL_PROCESS_A TTACH: InitHook; //DLL载入DLL_PROCESS_DETACH: UninitHook; //DLL删除end;end;exportsStartHook, EndHook;beginMemShared;{ 分配DLL程序到 DllProc 变量 }DllProc := @DllEntry;{ 调用DLL加载处理 }DllEntry(DLL_PROCESS_A TTACH);end.--------------------------- 单元unitHook.pasunit unitHook;interfaceusesWindows, Messages, Classes, SysUtils;type//NtHook类相关类型TNtJmpCode=packed record //8字节MovEax:Byte;Addr:DWORD;JmpCode:Word;dwReserved:Byte;end;TNtHookClass=class(TObject)privatehProcess:THandle;NewAddr:TNtJmpCode;OldAddr:array[0..7] of Byte;ReadOK:Boolean;publicBaseAddr:Pointer;constructor Create(DllName,FuncName:string;NewFunc:Pointer);destructor Destroy; override;procedure Hook;procedure UnHook;end;implementation//==================================================//NtHOOK 类开始//==================================================constructor TNtHookClass.Create(DllName: string; FuncName: string;NewFunc:Pointer);varDllModule:HMODULE;dwReserved:DWORD;begin//获取模块句柄DllModule:=GetModuleHandle(PChar(DllName));//如果得不到说明未被加载if DllModule=0 then DllModule:=LoadLibrary(PChar(DllName));//得到模块入口地址(基址)BaseAddr:=Pointer(GetProcAddress(DllModule,PChar(FuncName)));//获取当前进程句柄hProcess:=GetCurrentProcess;//指向新地址的指针NewAddr.MovEax:=$B8;NewAddr.Addr:=DWORD(NewFunc);NewAddr.JmpCode:=$E0FF;//保存原始地址ReadOK:=ReadProcessMemory(hProcess,BaseAddr,@OldAddr,8,dwReserved); //开始拦截Hook;end;//释放对象destructor TNtHookClass.Destroy;beginUnHook;CloseHandle(hProcess);inherited;end;//开始拦截procedure TNtHookClass.Hook;vardwReserved:DWORD;beginif (ReadOK=False) then Exit;//写入新的地址WriteProcessMemory(hProcess,BaseAddr,@NewAddr,8,dwReserved);end;//恢复拦截procedure TNtHookClass.UnHook;vardwReserved:DWORD;beginif (ReadOK=False) then Exit;//恢复地址WriteProcessMemory(hProcess,BaseAddr,@OldAddr,8,dwReserved); end;end.。
【转】C#.Net鼠标和键盘全局监控勾子(hook)【转】C#.Net 鼠标和键盘全局监控勾子(hook )//C#鼠标和键盘全局监控hookusing System;using System.Runtime.InteropServices;using System.Reflection;using System.Threading;using System.Windows.Forms;using ponentModel;namespace ScreenCapyure2{public class UserActivityHook{#region Windows structure definitions[StructLayout(LayoutKind.Sequential)]private class POINT{public int x;public int y;}[StructLayout(LayoutKind.Sequential)]private class MouseHookStruct{public POINT pt;public int hwnd;public int wHitTestCode;public int dwExtraInfo;}[StructLayout(LayoutKind.Sequential)]private class MouseLLHookStruct{public POINT pt;public int mouseData;public int flags;public int time;public int dwExtraInfo;}[StructLayout(LayoutKind.Sequential)]private class KeyboardHookStruct{public int vkCode;public int scanCode;public int flags;public int time;public int dwExtraInfo;}#endregion#region Windows function imports[DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall, SetLastError = true)]private static extern int SetWindowsHookEx(int idHook,HookProc lpfn,IntPtr hMod,int dwThreadId);[DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall, SetLastError = true)]private static extern int UnhookWindowsHookEx(int idHook);[DllImport("user32.dll", CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall)]private static extern int CallNextHookEx(int idHook,int nCode,int wParam,IntPtr lParam);private delegate int HookProc(int nCode, int wParam, IntPtr lParam);[DllImport("user32")]private static extern int ToAscii(int uVirtKey,int uScanCode,byte[] lpbKeyState,byte[] lpwTransKey,int fuState);[DllImport("user32")]private static extern int GetKeyboardState(byte[] pbKeyState);[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]private static extern short GetKeyState(int vKey);#endregion#region Windows constantsprivate const int WH_MOUSE_LL = 14;private const int WH_KEYBOARD_LL = 13;private const int WH_MOUSE = 7;private const int WH_KEYBOARD = 2;private const int WM_MOUSEMOVE = 0x200;private const int WM_LBUTTONDOWN = 0x201;private const int WM_RBUTTONDOWN = 0x204;private const int WM_MBUTTONDOWN = 0x207;private const int WM_LBUTTONUP = 0x202;private const int WM_RBUTTONUP = 0x205;private const int WM_MBUTTONUP = 0x208;private const int WM_LBUTTONDBLCLK = 0x203;private const int WM_RBUTTONDBLCLK = 0x206;private const int WM_MBUTTONDBLCLK = 0x209;private const int WM_MOUSEWHEEL = 0x020A;private const int WM_KEYDOWN = 0x100;private const int WM_KEYUP = 0x101;private const int WM_SYSKEYDOWN = 0x104;private const int WM_SYSKEYUP = 0x105;private const byte VK_SHIFT = 0x10;private const byte VK_CAPITAL = 0x14;private const byte VK_NUMLOCK = 0x90;#endregionpublic UserActivityHook(){Start();}public UserActivityHook(bool InstallMouseHook, bool InstallKeyboardHook){Start(InstallMouseHook, InstallKeyboardHook);}~UserActivityHook(){Stop(true, true, false);}public event MouseEventHandler OnMouseActivity;public event KeyEventHandler KeyDown;public event KeyPressEventHandler KeyPress;public event KeyEventHandler KeyUp;private int hMouseHook = 0;private int hKeyboardHook = 0;private static HookProc MouseHookProcedure;private static HookProc KeyboardHookProcedure;public void Start(){this.Start(true, true);}public void Start(bool InstallMouseHook, bool InstallKeyboardHook){if (hMouseHook == 0 && InstallMouseHook){MouseHookProcedure = new HookProc(MouseHookProc);hMouseHook = SetWindowsHookEx(WH_MOUSE_LL,MouseHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);if (hMouseHook == 0){int errorCode = Marshal.GetLastWin32Error();Stop(true, false, false);try{ throw new Win32Exception(errorCode); }catch{ }}}if (hKeyboardHook == 0 && InstallKeyboardHook){KeyboardHookProcedure = new HookProc(KeyboardHookProc);hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL,KeyboardHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);if (hKeyboardHook == 0){int errorCode = Marshal.GetLastWin32Error();Stop(false, true, false);try{throw new Win32Exception(errorCode);}catch { }}}}public void Stop(){this.Stop(true, true, true);}public void Stop(bool UninstallMouseHook, bool UninstallKeyboardHook, bool ThrowExceptions){if (hMouseHook != 0 && UninstallMouseHook){int retMouse = UnhookWindowsHookEx(hMouseHook);hMouseHook = 0;if (retMouse == 0 && ThrowExceptions){int errorCode = Marshal.GetLastWin32Error();throw new Win32Exception(errorCode);}}if (hKeyboardHook != 0 && UninstallKeyboardHook){int retKeyboard = UnhookWindowsHookEx(hKeyboardHook);hKeyboardHook = 0;if (retKeyboard == 0 && ThrowExceptions){int errorCode = Marshal.GetLastWin32Error();throw new Win32Exception(errorCode);}}}private int MouseHookProc(int nCode, int wParam, IntPtr lParam){if ((nCode >= 0) && (OnMouseActivity != null)){MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)Marshal.PtrToStructure(lParam,typeof(MouseLLHookStruct));MouseButtons button = MouseButtons.None;short mouseDelta = 0;switch (wParam){case WM_LBUTTONDOWN:button = MouseButtons.Left;break;case WM_RBUTTONDOWN:button = MouseButtons.Right;break;case WM_MOUSEWHEEL:mouseDelta = (short)((mouseHookStruct.mouseData >> 16) & 0xffff);break;}int clickCount = 0;if (button != MouseButtons.None)if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK) clickCount = 2;else clickCount = 1;MouseEventArgs e = new MouseEventArgs(button,clickCount,mouseHookStruct.pt.x,mouseHookStruct.pt.y,mouseDelta);OnMouseActivity(this, e);}return CallNextHookEx(hMouseHook, nCode, wParam, lParam);}private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam){bool handled = false;if ((nCode >= 0) && (KeyDown != null || KeyUp != null || KeyPress != null)){KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam,typeof(KeyboardHookStruct));if (KeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)){Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;KeyEventArgs e = new KeyEventArgs(keyData);KeyDown(this, e);handled = handled || e.Handled;}if (KeyPress != null && wParam == WM_KEYDOWN){bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80 ? true : false);bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true : false);byte[] keyState = new byte[256];GetKeyboardState(keyState);byte[] inBuffer = new byte[2];if (ToAscii(MyKeyboardHookStruct.vkCode,MyKeyboardHookStruct.scanCode,keyState,inBuffer,MyKeyboardHookStruct.flags) == 1){char key = (char)inBuffer[0];if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) key = Char.T oUpper(key);KeyPressEventArgs e = new KeyPressEventArgs(key);KeyPress(this, e);handled = handled || e.Handled;}}if (KeyUp != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)){Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;KeyEventArgs e = new KeyEventArgs(keyData);KeyUp(this, e);handled = handled || e.Handled;}}if (handled)return 1;elsereturn CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);}}}//////////////////////可以把以上程序单独存为一个文件如:SC.CS;然后在项目里“添加现有项”找到该文件记住引用using ScreenCapyure2;//以下为在窗体中监视事件//本程序调试不起作用,运行时才起作用UserActivityHook choosesc;choosesc = new UserActivityHook();choosesc.OnMouseActivity += new MouseEventHandler(choose_OnMouseActivity);choosesc.KeyDown += new KeyEventHandler(MyKeyDown);choosesc.KeyPress += new KeyPressEventHandler(MyKeyPress);choosesc.KeyUp += new KeyEventHandler(MyKeyUp);//上面部分写到 InitializeComponent()后面public void MyKeyDown(object sender, KeyEventArgs e){}public void MyKeyPress(object sender, KeyPressEventArgs e) {}public void MyKeyUp(object sender, KeyEventArgs e){}private void choose_OnMouseActivity(object sender, MouseEventArgs e){if (e.Clicks > 0){if ((MouseButtons)(e.Button) == MouseButtons.Left){point[0] = e.Location;}if ((MouseButtons)(e.Button) == MouseButtons.Right){point[1] = e.Location;}}//throw new Exception("The method or operation is not implemented.");}。
HOOK监控任务管理器思路:其实比较简单,还是利用DLL,首写跟据API函数OpenProcess与TerminateProcess的结构自已编写两个与这两个API一样的函数,再利用GetProcAddress获取系统的那两个API函数入口地址,最后用WriteProcessMemory将你写的函数的地址替换掉原来系统的函数地址。
这样所有调用这两系统API都将先执行你的函数。
如果只Hook其中一个函数比如只hook OpenProcess的话那么任务管理器将不能获取到你的进程信息那么会出错。
如果只hook TerminateProcess那样也不行,因为一个进程的句柄在本进程与别的进程中是不一样的,所以如果你不知道自已进程在别人进程中的句柄那么是没办法hook TerminateProcess的。
本例中首先利用OpenProcess获取自已在别的进程中的句柄,然后hook TerminateProcess进程监控,如果发现有程序调用TerminateProcess并且所结束的对象正是自已,那么就给出提示窗口。
貌似讲了一大堆废话。
还是看代码直接------------------------------------------------调用部分unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;typeTForm1 = class(TForm)Button1: TButton;Button2: TButton;procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;procedure StartHook(pid: DWORD); stdcall; external 'hookdll.dll';procedure EndHook; stdcall; external 'hookdll.dll';implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);beginStartHook(GetCurrentProcessId);end;procedure TForm1.Button2Click(Sender: TObject);beginEndHook;end;end.-----------------------------------------------------------------------------------------DLL文件,全部实现都在这里--------------------- Hookdll.dprlibrary Hookdll;usesSysUtils,Classes,Windows,Dialogs,unitHook in 'unitHook.pas';constHOOK_MEM_FILENAME = 'tmp.hkt';varhhk: HHOOK;Hook: array[0..2] of TNtHookClass;//内存映射MemFile: THandle;startPid: PDWORD; //保存PIDfhProcess: THandle; //保存本进程在远程进程中的句柄//拦截 OpenProcessfunction NewOpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THand le; stdcall;typeTNewOpenProcess = function (dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): T Handle; stdcall;beginif startPid^ = dwProcessId then beginHook[1].UnHook;Result := TNewOpenProcess(Hook[1].BaseAddr)(dwDesiredAccess, bInheritHandle, dwProcessId);fhProcess:=Result;Hook[1].Hook;exit;end;Hook[1].UnHook;Result := TNewOpenProcess(Hook[1].BaseAddr)(dwDesiredAccess, bInheritHandle, dwProcessId);Hook[1].Hook;end;function NewTerminateProcess(hProcess: THandle;uExitCode: UINT): BOOL; Stdcall;typeTNewTerminateProcess = function (hProcess: THandle;uExitCode: UINT): BOOL; Stdcall;beginif fhProcess = hProcess then beginshowmessage('不准关闭我!');result := true;exit;end;Hook[2].UnHook;Result := TNewTerminateProcess(Hook[2].BaseAddr)(hProcess, uExitCode );Hook[2].Hook;end;procedure InitHook; //安装 HookbeginHook[1] := TNtHookClass.Create('kernel32.dll', 'OpenProcess', @NewOpenProcess);hook[2] := TNtHookClass.Create('kernel32.dll', 'TerminateProcess', @NewTerminateProcess);end;procedure UninitHook; //删除 HookvarI: Integer;beginfor I := 0 to High(Hook) dobeginFreeAndNil(Hook[I]);end;end;procedure MemShared();beginMemFile:=OpenFileMapping(FILE_MAP_ALL_ACCESS,False, HOOK_MEM_FILENAME); //打开内存映射文件if MemFile = 0 then beginMemFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 4, HOOK_MEM_FILENAME);end;if MemFile <> 0 then//映射文件到变量startPid := MapViewOfFile(MemFile,FILE_MAP_ALL_ACCESS,0,0,0); end;//传递消息function HookProc(nCode, wParam, lParam: Integer): Integer; stdcall;beginResult := CallNextHookEx(hhk, nCode, wParam, lParam);end;//开始HOOKprocedure StartHook(pid: DWORD); stdcall;beginstartPid^ := pid;hhk := SetWindowsHookEx(WH_CALLWNDPROC, HookProc, hInstance, 0); end;//结束HOOKprocedure EndHook; stdcall;beginif hhk <> 0 thenUnhookWindowsHookEx(hhk);end;//环境处理procedure DllEntry(dwResaon: DWORD);begincase dwResaon ofDLL_PROCESS_A TTACH: InitHook; //DLL载入DLL_PROCESS_DETACH: UninitHook; //DLL删除end;end;exportsStartHook, EndHook;beginMemShared;{ 分配DLL程序到 DllProc 变量 }DllProc := @DllEntry;{ 调用DLL加载处理 }DllEntry(DLL_PROCESS_A TTACH);end.--------------------------- 单元unitHook.pasunit unitHook;interfaceusesWindows, Messages, Classes, SysUtils;type//NtHook类相关类型TNtJmpCode=packed record //8字节MovEax:Byte;Addr:DWORD;JmpCode:Word;dwReserved:Byte;end;TNtHookClass=class(TObject)privatehProcess:THandle;NewAddr:TNtJmpCode;OldAddr:array[0..7] of Byte;ReadOK:Boolean;publicBaseAddr:Pointer;constructor Create(DllName,FuncName:string;NewFunc:Pointer);destructor Destroy; override;procedure Hook;procedure UnHook;end;implementation//==================================================//NtHOOK 类开始//==================================================constructor TNtHookClass.Create(DllName: string; FuncName: string;NewFunc:Pointer);varDllModule:HMODULE;dwReserved:DWORD;begin//获取模块句柄DllModule:=GetModuleHandle(PChar(DllName));//如果得不到说明未被加载if DllModule=0 then DllModule:=LoadLibrary(PChar(DllName));//得到模块入口地址(基址)BaseAddr:=Pointer(GetProcAddress(DllModule,PChar(FuncName)));//获取当前进程句柄hProcess:=GetCurrentProcess;//指向新地址的指针NewAddr.MovEax:=$B8;NewAddr.Addr:=DWORD(NewFunc);NewAddr.JmpCode:=$E0FF;//保存原始地址ReadOK:=ReadProcessMemory(hProcess,BaseAddr,@OldAddr,8,dwReserved); //开始拦截Hook;end;//释放对象destructor TNtHookClass.Destroy;beginUnHook;CloseHandle(hProcess);inherited;end;//开始拦截procedure TNtHookClass.Hook;vardwReserved:DWORD;beginif (ReadOK=False) then Exit;//写入新的地址WriteProcessMemory(hProcess,BaseAddr,@NewAddr,8,dwReserved);end;//恢复拦截procedure TNtHookClass.UnHook;vardwReserved:DWORD;beginif (ReadOK=False) then Exit;//恢复地址WriteProcessMemory(hProcess,BaseAddr,@OldAddr,8,dwReserved); end;end.。