zoukankan      html  css  js  c++  java
  • 利用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.
  • 相关阅读:
    MAC 设置环境变量
    查询端口使用情况
    如何查看Oracle数据库字符集 尚未研究
    Python的MD5加密
    数据库解锁用户
    Oracle创建用户,赋予权限
    plsql
    福州周边游玩
    django笔记--1
    Linux速成
  • 原文地址:https://www.cnblogs.com/delphi7456/p/1865729.html
Copyright © 2011-2022 走看看