本文整理自网络,侵删。
思路:其实比较简单,还是利用DLL,首写跟据API函数OpenProcess与TerminateProcess的结构自已编写两个与这两个API一样的函数,再利用GetProcAddress获取系统的那两个API函数入口地址,最后用WriteProcessMemory将你写的函数的地址替换掉原来系统的函数地址。这样所有调用这两系统API都将先执行你的函数。如果只Hook其中一个函数比如只hook OpenProcess的话那么任务管理器将不能获取到你的进程信息那么会出错。如果只hook TerminateProcess那样也不行,因为一个进程的句柄在本进程与别的进程中是不一样的,所以如果你不知道自已进程在别人进程中的句柄那么是没办法hook TerminateProcess的。本例中首先利用OpenProcess获取自已在别的进程中的句柄,然后hook TerminateProcess进程监控,如果发现有程序调用TerminateProcess并且所结束的对象正是自已,那么就给出提示窗口。------------------------------------------------调用部分unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1; procedure StartHook(pid: DWORD); stdcall; external 'hookdll.dll'; procedure EndHook; stdcall; external 'hookdll.dll';implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);begin StartHook(GetCurrentProcessId);end;procedure TForm1.Button2Click(Sender: TObject);begin EndHook;end;end.-----------------------------------------------------------------------------------------DLL文件,全部实现都在这里--------------------- Hookdll.dpr
library Hookdll;uses SysUtils, Classes, Windows,Dialogs, unitHook in 'unitHook.pas';const HOOK_MEM_FILENAME = 'tmp.hkt';var hhk: HHOOK; Hook: array[0..2] of TNtHookClass; //内存映射 MemFile: THandle; startPid: PDWORD; //保存PID fhProcess: THandle; //保存本进程在远程进程中的句柄//拦截 OpenProcessfunction NewOpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;type TNewOpenProcess = function (dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;begin if startPid^ = dwProcessId then begin Hook[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;type TNewTerminateProcess = function (hProcess: THandle;uExitCode: UINT): BOOL; Stdcall;begin if fhProcess = hProcess then begin showmessage('不准关闭我!'); result := true; exit; end; Hook[2].UnHook; Result := TNewTerminateProcess(Hook[2].BaseAddr)(hProcess, uExitCode ); Hook[2].Hook;end;procedure InitHook; //安装 Hookbegin Hook[1] := TNtHookClass.Create('kernel32.dll', 'OpenProcess', @NewOpenProcess); hook[2] := TNtHookClass.Create('kernel32.dll', 'TerminateProcess', @NewTerminateProcess);end;procedure UninitHook; //删除 Hookvar I: Integer;begin for I := 0 to High(Hook) do begin FreeAndNil(Hook[I]); end;end;procedure MemShared();begin MemFile:=OpenFileMapping(FILE_MAP_ALL_ACCESS,False, HOOK_MEM_FILENAME); //打开内存映射文件 if MemFile = 0 then begin MemFile := 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;begin Result := CallNextHookEx(hhk, nCode, wParam, lParam);end;//开始HOOKprocedure StartHook(pid: DWORD); stdcall;begin startPid^ := pid; hhk := SetWindowsHookEx(WH_CALLWNDPROC, HookProc, hInstance, 0);end;//结束HOOKprocedure EndHook; stdcall;begin if hhk <> 0 then UnhookWindowsHookEx(hhk);end;//环境处理procedure DllEntry(dwResaon: DWORD);begin case dwResaon of DLL_PROCESS_ATTACH: InitHook; //DLL载入 DLL_PROCESS_DETACH: UninitHook; //DLL删除 end;end;exports StartHook, EndHook;begin MemShared; { 分配DLL程序到 DllProc 变量 } DllProc := @DllEntry; { 调用DLL加载处理 } DllEntry(DLL_PROCESS_ATTACH);end.--------------------------- 单元unitHook.pas
unit unitHook;interfaceuses Windows, Messages, Classes, SysUtils;type //NtHook类相关类型 TNtJmpCode=packed record //8字节 MovEax:Byte; Addr:DWORD; JmpCode:Word; dwReserved:Byte; end; TNtHookClass=class(TObject) private hProcess:THandle; NewAddr:TNtJmpCode; OldAddr:array[0..7] of Byte; ReadOK:Boolean; public BaseAddr: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);var DllModule: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;begin UnHook; CloseHandle(hProcess); inherited;end;//开始拦截procedure TNtHookClass.Hook;var dwReserved:DWORD;begin if (ReadOK=False) then Exit; //写入新的地址 WriteProcessMemory(hProcess,BaseAddr,@NewAddr,8,dwReserved);end;//恢复拦截procedure TNtHookClass.UnHook;var dwReserved:DWORD;begin if (ReadOK=False) then Exit; //恢复地址 WriteProcessMemory(hProcess,BaseAddr,@OldAddr,8,dwReserved);end;end.
相关阅读 >>
Delphi createthread的线程传参数(小熊论坛的)
更多相关阅读请进入《Delphi》频道 >>