当前位置: 代码迷 >> 综合 >> 封装delphi Hook Api
  详细解决方案

封装delphi Hook Api

热度:65   发布时间:2024-01-06 16:50:31.0

直接看代码

unit uApiHook;

interface

uses
  SysUtils, Windows, TlHelp32;

type
  PJmpCode = ^TJmpCode;
  TJmpCode = packed record
    JmpCode: BYTE;
    Address: Pointer;
    MovEAX: Array [0..2] of BYTE;
  end;

type
  TApiHookInfo = class
  private
    FCS:TRTLCriticalSection;
    FJmpCode: PJmpCode;
    FOldProc: PJmpCode;
    FLoadLib: Boolean;
    FDllHandle: THandle;
    FHookFun: Pointer;
    m_hProc: DWORD;
    FOldPoint: Cardinal;
    FbHook: Boolean;
    procedure SetPageWrite;
    procedure SetPageReadOnly;
  public
    FAddr: Pointer;
    constructor Create;
    destructor Destroy; override;
    function init(ADllName, AFunName: string; ANewFunPointer: Pointer):Boolean;
    procedure Lock;
    procedure UnLock;
    procedure Hook;
    procedure UnHook;
  end;

implementation

{ TApiHookInfo }

procedure TApiHookInfo.SetPageWrite;
begin
  if Win32PlatForm = VER_PLATFORM_WIN32_NT  then //判断是不是NT.
    VirtualProtect(FAddr, $F, PAGE_EXECUTE_READWRITE, FOldPoint);
end;

procedure TApiHookInfo.SetPageReadOnly;
begin
  if Win32PlatForm = VER_PLATFORM_WIN32_NT  then //判断是不是NT.
    VirtualProtect(FAddr, $F, FOldPoint, FOldPoint);
end;

constructor TApiHookInfo.Create;
begin
  InitializeCriticalSection(FCS);
  New(FJmpCode);
  New(FOldProc);
  FLoadLib := False;
  FDllHandle := 0;
  FHookFun := nil;
  FbHook := False;
end;

destructor TApiHookInfo.Destroy;
begin
  if FbHook then
    UnHook;
  if FLoadLib then
    FreeLibrary(FDllHandle);
  Dispose(FJmpCode);
  Dispose(FOldProc);
  DeleteCriticalSection(FCS);
  inherited;
end;

procedure TApiHookInfo.Hook;
var
  dwSize: Cardinal;
begin
  SetPageWrite;
  WriteProcessMemory(m_hProc, FAddr, FJmpCode, 8, dwSize);
  FbHook := True;
  SetPageReadOnly;
end;

function TApiHookInfo.init(ADllName, AFunName: string;
  ANewFunPointer: Pointer):Boolean;
var
  dwSize: DWORD;
begin
        FDllHandle := GetModuleHandle(PChar(ADllName));
        if FDllHandle = 0 then
  begin
    FDllHandle := LoadLibrary(PChar(ADllName));
    if FDllHandle = 0 then
    begin
                        Result := False;
      Exit;
    end
    else
            FLoadLib := True;
  end;
  //函数地址
        FAddr := GetProcAddress(FDllHandle, PChar(AFunName));
        if (FAddr = nil) then
  begin
    Result := False;
    Exit;
  end;
  //当前进程
        m_hProc := GetCurrentProcess();

        if (m_hProc = 0) then
  begin
    Result := False;
    Exit;
  end;
  //读当前进程中函数地址
  SetPageWrite;
  FJmpCode^.JmpCode := $B8;
  FJmpCode^.MovEAX[0] := $FF;
  FJmpCode^.MovEAX[1] := $E0;
  FJmpCode^.MovEAX[2] := 0;
  ReadProcessMemory(m_hProc, FAddr, FOldProc, 8, dwSize);
  FJmpCode^.Address := ANewFunPointer;
  WriteProcessMemory(m_hProc, FAddr, FJmpCode, 8, dwSize);
  SetPageReadOnly;
  Result := True;
end;

procedure TApiHookInfo.Lock;
begin
  EnterCriticalSection(FCS);
end;

procedure TApiHookInfo.UnHook;
var
  dwSize: DWORD;
begin
  SetPageWrite;
  WriteProcessMemory(m_hProc, FAddr, FOldProc, 8, dwSize);
  FbHook := False;
  SetPageReadOnly;
end;

procedure TApiHookInfo.UnLock;
begin
  LeaveCriticalSection(FCS);
end;

end.


使用方法:
var
  g_OpenProcess: TApiHookInfo;

function MyOpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;
begin
  g_OpenProcess.Lock;
  try
    g_OpenProcess.UnHook;
    try
      //你自己的一些代码
      Result := OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
      //你自己的一些代码
    finally
      g_OpenProcess.Hook;
    end;
  finally
    g_OpenProcess.UnLock;
  end;
end;

procedure HookApi;
begin
  g_OpenProcess.init('kernel32.dll', 'OpenProcess', @MyOpenProcess);
end;

procedure UnHookAPI;
begin
  g_OpenProcess.Free;
end;
 
  相关解决方案