阿杰 发表于 2010-7-11 09:27:12

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

利用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 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.UnHook;
Result := TNewOpenProcess(Hook.BaseAddr)(dwDesiredAccess, bInheritHandle, dwProcessId);
fhProcess:=Result;
Hook.Hook;
exit;
end;
Hook.UnHook;
Result := TNewOpenProcess(Hook.BaseAddr)(dwDesiredAccess, bInheritHandle, dwProcessId);
Hook.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.UnHook;
Result := TNewTerminateProcess(Hook.BaseAddr)(hProcess, uExitCode );
Hook.Hook;
end;

procedure InitHook; //安装 Hook
begin
Hook := TNtHookClass.Create('kernel32.dll', 'OpenProcess', @NewOpenProcess);
hook := TNtHookClass.Create('kernel32.dll', 'TerminateProcess', @NewTerminateProcess);
end;

procedure UninitHook; //删除 Hook
var
I: Integer;
begin
for I := 0 to High(Hook) do
begin
FreeAndNil(Hook);
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 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.

马大哈 发表于 2010-7-12 01:14:02

看着DELPHI就头晕...........

Tesla.Angela 发表于 2010-7-12 11:37:50


此帖子为转载与网路,只是给汇编的朋友分享一下。由于本人不懂汇编 无法将此汇编转为易语言 所以请汇编高手把此方法转为易的!

这个涉及函数指针,估计易语言做不了。

gam2046 发表于 2010-7-17 14:50:00

据说不是E语言支持指针?

servite 发表于 2010-12-20 22:57:44

这个玩意儿会让你听到 “咣咣的ERROR提示音” 发病期不确定...根据你系统运行程序的不明真相遗留 时而发病时而安然无事... 这种倒退N年玩玩还是很不错的 ,如今的话 下两层做保护吧...

gam2046 发表于 2011-7-18 20:56:36

gam2046 发表于 2010-7-17 14:50 static/image/common/back.gif
据说不是E语言支持指针?

过了一年 我又回来了、
当然我这么怂、现在看看依旧这么怂、

upring 发表于 2015-4-1 14:46:06

delphi的语法试试最容易读懂的语法之一
页: [1]
查看完整版本: 利用Hook API函数OpenProcess与TerminateProcess来防止任务管理器结束进程