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.
  • 相关阅读:
    Parameter Binding in ASP.NET Web API
    Which HTTP methods match up to which CRUD methods?
    ErrorHandling in asp.net web api
    HttpStatusCode
    Autofac Getting Started(默认的构造函数注入)
    Autofac Controlling Scope and Lifetime
    luvit 被忽视的lua 高性能框架(仿nodejs)
    undefined与null的区别
    VsCode中使用Emmet神器快速编写HTML代码
    字符串匹配---KMP算法
  • 原文地址:https://www.cnblogs.com/delphi7456/p/1865729.html
Copyright © 2011-2022 走看看