首页
社区
课程
招聘
[分享]利用Hook API函数OpenProcess与TerminateProcess来防止任务管理器结束进程 Delphi代码
发表于: 2009-12-16 16:50 24215

[分享]利用Hook API函数OpenProcess与TerminateProcess来防止任务管理器结束进程 Delphi代码

2009-12-16 16:50
24215
第一次发文章,写得不好不要丢砖头啊,嘻嘻!!  高手就别看了~~

思路:其实比较简单,还是利用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.

[课程]FART 脱壳王!加量不加价!FART作者讲授!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (23)
雪    币: 188
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
没办法,上传不了文件啊。。
2009-12-16 16:55
0
雪    币: 188
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
刚没看到,原来可以上传文件的,哈哈
2009-12-16 17:04
0
雪    币: 442
活跃值: (107)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
4
Delphi???不错的
2009-12-16 17:32
0
雪    币: 272
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不错的东西
2009-12-16 18:08
0
雪    币: 189
活跃值: (4810)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
不错!!!

支持一下!!! 不过,实际上好像无多大用处。(SSDT 勾也没用)

当然, 单看写的代码(我也用 DELPHI),你比我高几倍,我只会说, 不会写。

PostMessage, SendMessage 关闭, NTDuplicateObject, NT****
2009-12-16 18:45
0
雪    币: 156
活跃值: (97)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
为什么附件还要钱啊!?
2010-2-17 14:01
0
雪    币: 205
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
不错,虽然是很老的代码。
2010-2-17 20:51
0
雪    币: 65
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
不会DELPHI......
为什么没有VC的?
2010-2-17 21:36
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
不太稳定,explorer.exe和任务管理器经常挂掉。
2010-2-19 11:48
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
如果我PostQuitMessage或者PostThreadMessage呢?

2010-2-26 00:20
0
雪    币: 219
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
感谢分享
我看了一下,有点奇怪之处,在hookdll.dpr 中,定义数组如下
Hook: array[0..2] of TNtHookClass;
也就是说定义了 0~2 的下标数组,但在程序中好像没见到使用下标为0的元素,不知道是另有用意,还是。。
谢谢
2010-5-17 09:29
0
雪    币: 123
活跃值: (27)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
13
没用,任意一款驱动级工具就杀掉了,最简单的PspTerminateProcess
2010-5-18 13:14
0
雪    币: 2015
活跃值: (902)
能力值: ( LV12,RANK:1000 )
在线值:
发帖
回帖
粉丝
14
程序还是很稳定的,只是楼主删除了源码中关键的地方。
2010-5-20 22:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
aaaaaaaa
2010-9-1 16:42
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
16
之前弄过VC版的。。。
2010-9-1 17:11
0
雪    币: 282
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
很好,任务管理器没法关闭。
2010-9-3 16:08
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
不错,谢谢分享
2010-10-22 14:54
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
在WINDOWS的任务管理器中的“进程”页面中,点结束进程确实可以。
但是如果是进的“应用程序”页面中,就可以结束了,不知道在应用程序中结束是调用的哪个API结束的。
2011-2-18 15:56
0
雪    币: 152
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
小雨伞报毒,无法实际应用!不过实现技术到可以借鉴一下!
2012-1-12 09:38
0
雪    币: 22
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
任务管理器经常挂掉。
2012-1-30 17:38
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
22
垃圾啊,直接按照微软WDK中的说明,调用NTDLL中的NT系列函数中的NtOpenProcess与NtTerminateProcess来结束进程,这样直接绕过你的HOOK
2012-1-30 21:47
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
23
对了,NT系列函数的下层函数就是驱动里面的函数了,就不关你的HOOK什么事情了
2012-1-31 20:46
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
24
你不如直接写SSDT HOOK,这样的话,任何RING3进程的调用都绕不开你的HOOK了
2012-1-31 20:49
0
游客
登录 | 注册 方可回帖
返回
//