利用Hook API函数OpenProcess与TerminateProcess来防止任务管理器结束进程

      思路:其实比较简单,还是利用DLL,首写跟据API函数OpenProcess与TerminateProcess的结构自已编写两个与这两个API一样的函数,再利用GetProcAddress获取系统的那两个API函数入口地址,最后用WriteProcessMemory将你写的函数的地址替换掉原来系统的函数地址。这样所有调用这两系统API都将先执行你的函数。
如果只Hook其中一个函数比如只hook OpenProcess的话那么任务管理器将不能获取到你的进程信息那么会出错。如果只hook TerminateProcess那样也不行,因为一个进程的句柄在本进程与别的进程中是不一样的,所以如果你不知道自已进程在别人进程中的句柄那么是没办法hook TerminateProcess的。
本例中首先利用OpenProcess获取自已在别的进程中的句柄,然后hook TerminateProcess进程监控,如果发现有程序调用TerminateProcess并且所结束的对象正是自已,那么就给出提示窗口。
------------------------------------------------调用部分

unit Unit1;

interface

uses

  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;  //保存本进程在远程进程中的句柄

//拦截 OpenProcess

function 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;     //安装 Hook

begin

  Hook[1] := TNtHookClass.Create('kernel32.dll', 'OpenProcess', @NewOpenProcess);

  hook[2] := TNtHookClass.Create('kernel32.dll', 'TerminateProcess', @NewTerminateProcess);

end;

procedure UninitHook;     //删除 Hook

var

  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;

//开始HOOK

procedure StartHook(pid: DWORD); stdcall;

begin

  startPid^ := pid;

  hhk := SetWindowsHookEx(WH_CALLWNDPROC, HookProc, hInstance, 0);

end;

//结束HOOK

procedure 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;

interface

uses

  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.

你可能感兴趣的:(process)