How to Use EasyHook in Delphi?

Jun 20, 2014 at 11:10 AM
I translate easyhook.h to pascal Language.

the next is my example from UnmanagedHook.
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,UEasyHook;

type

  TMessageBeep =function (uType: UINT): BOOL; stdcall;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
  public
  end;

  function MyMessageBeep(uType: UINT): BOOL; stdcall;

var
  Form1: TForm1;
  RealMessageBeep:TMessageBeep;

implementation

uses UEasyHookLib;

{$R *.dfm}

function MyMessageBeep(uType: UINT): BOOL;
begin
  OutputDebugString(PChar('ddddddd'));
  Result :=True;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  EasyHookLib :TEasyHookLib;
  DLLHandle :THandle;
  Hook :TTraceHookHandle;
  ACLEntries :array[0..0] of ULONG;
  a:Integer;
begin
  DLLHandle :=LoadLibrary('user32.dll');
  if DLLHandle<>0 then
  begin
    @RealMessageBeep :=GetProcAddress(DLLHandle,'MessageBeep');
  end;

  EasyHookLib :=TEasyHookLib.Create;
  //There Have Some problem
  EasyHookLib.LhInstallHook(@RealMessageBeep,@MyMessageBeep,nil,@Hook);
  EasyHookLib.LhSetExclusiveACL(@ACLEntries[0], 1, @Hook);
end;

Jun 22, 2014 at 10:11 AM
My Delphi is a little rusty these days, but I don't see anything obviously wrong. What error is happening?
Jun 30, 2014 at 8:23 AM
some Exception Happend in here。
EasyHookLib.LhInstallHook(@RealMessageBeep,@MyMessageBeep,nil,@Hook);
Other Unit is the Next。
unit UEasyHook;

interface

uses
  Windows;




const

  MAX_HOOK_COUNT = 128;
  MAX_ACE_COUNT = 128;
  MAX_THREAD_COUNT = 128;
  MAX_PASSTHRU_SIZE = 1024 * 64;

  EASYHOOK_INJECT_DEFAULT = $00000000;
  EASYHOOK_INJECT_STEALTH = $10000000;  // (experimental)
  EASYHOOK_INJECT_NET_DEFIBRILLATOR = $20000000; // USE THIS ONLY IN UNMANAGED CODE AND ONLY WITH CreateAndInject() FOR MANAGED PROCESSES!!

//typedef struct _LOCAL_HOOK_INFO_* PLOCAL_HOOK_INFO;
//
//typedef struct _HOOK_TRACE_INFO_
//{
//    PLOCAL_HOOK_INFO        Link;
//}HOOK_TRACE_INFO, *TRACED_HOOK_HANDLE;

type
  NTSTATUS = Integer;
  ULONG = Cardinal;
  PULONG = ^ULONG;
  ULONGLONG = Int64;
  PUnicodeString = ^TUnicodeString;
  TUnicodeString = packed record
    Length: Word;
    MaximumLength: Word;
    Buffer: PWideChar;
  end;
  HMODULE = Pointer;

  TNotificationRequest = record
    MaxCount: Cardinal;
    Count: Cardinal;
    Entries: array of Cardinal;
  end;
  PNotificationRequest = ^TNotificationRequest;

  THookAcl = record
    Count: Cardinal;
    IsExclusive: Bool;
    Entries: array[0..MAX_ACE_COUNT - 1] of Cardinal;
  end;
  PHookAcl = ^THookAcl;

    //Injection support API.
  TRemoteEntryInfo = record
    HostPID: Cardinal;
    UserData: PChar;
    UserDataSize: Cardinal;
  end;
  PRemoteEntryInfo = ^TRemoteEntryInfo;


  PLocalHookInfo = ^TLocalHookInfo;
  TLocalHookInfo = record
    Next: PLocalHookInfo;
    NativeSize: ULONG;
    TargetProc: PChar;
    TargetBackup: ULONGLONG;
    TargetBackup_x64: ULONGLONG;
    HookCopy: ULONGLONG;
    EntrySize: ULONG;
    Trampoline: PChar;
    HLSIndex: ULONG;
    HLSIdent: ULONG;
    Callback: Pointer;
    LocalACL: THookAcl;
    Signature: ULONG;
    Tracking: Pointer;

    RandomValue: Pointer;               // fixed
    HookIntro: Pointer;                 // fixed
    OldProc: Pointer;                   // fixed
    HookProc: Pointer;                  // fixed
    HookOutro: Pointer;                 // fixed
    IsExecutedPtr: Pointer;             // fixed
  end;

  TTraceHookHandle = record
    Link: PLocalHookInfo;
  end;
  PTraceHookHandle = ^TTraceHookHandle;

  PModuleInfomation = ^TModuleInfomation;
  TModuleInfomation = record
    Next: PModuleInfomation;
    BaseAddress: PChar;
    ImageSize: Cardinal;
    Path: array[0..255] of Char;
    ModuleName: PChar;
  end;

  TRtlGetLastError = function(): NTSTATUS;
  TRtlGetLastErrorString = function(): PWideChar;
  TRtlGetLastErrorStringCopy = function(): PWideChar;
  TLhInstallHook = function(InEntryPoint: Pointer; InHookProc: Pointer; InCallback: Pointer; OutHandle: PTraceHookHandle): NTSTATUS;

  TLhUninstallAllHooks = function(): NTSTATUS;
  TLhUninstallHook = function(InHandle: PTraceHookHandle): NTSTATUS;
  TLhWaitForPendingRemovals = function(): NTSTATUS;

  TLhSetInclusiveACL = function(InThreadIdList: PULONG; InThreadCount: ULONG; InHandle: PTraceHookHandle): NTSTATUS;
  TLhSetExclusiveACL = function(InThreadIdList: PULONG; InThreadCount: ULONG; InHandle: PTraceHookHandle): NTSTATUS;
  TLhSetGlobalInclusiveACL = function(InThreadIdList: PULONG; InThreadCount: ULONG): NTSTATUS;
  TLhSetGlobalExclusiveACL = function(InThreadIdList: PULONG; InThreadCount: ULONG): NTSTATUS;
  TLhIsThreadIntercepted = function(InHook: PTraceHookHandle; InThreadID: ULONG; OutResult: PBOOL): NTSTATUS;

  TLhBarrierGetCallback = function(OutValue: Pointer): NTSTATUS;
  TLhBarrierGetReturnAddress = function(OutValue: Pointer): NTSTATUS;
  TLhBarrierGetAddressOfReturnAddress = function(OutValue: Pointer): NTSTATUS;
  TLhBarrierBeginStackTrace = function(OutBackup: Pointer): NTSTATUS;
  TLhBarrierEndStackTrace = function(InBackup: Pointer): NTSTATUS;

  TLhUpdateModuleInformation = function(): NTSTATUS;
  TLhBarrierPointerToModule = function(InPointer: Pointer; OutModule: PModuleInfomation): NTSTATUS;
  TLhEnumModules = function(OutModuleArray: HMODULE; InMaxModuleCount: ULONG; OutModuleCount: PULONG): NTSTATUS;
  TLhBarrierGetCallingModule = function(OutModule: PModuleInfomation): NTSTATUS;
  TLhBarrierCallStackTrace = function(OutMethodArray: Pointer; InMaxMethodCount: ULONG; OutMethodCount: PULONG): NTSTATUS;

  TDbgIsAvailable = function(): BOOL;
  TDbgIsEnabled = function(): BOOL;
  TDbgAttachDebugger = function(): NTSTATUS;
  TDbgDetachDebugger = function(): NTSTATUS;

  TDbgGetThreadIdByHandle = function(InThreadHandle: THandle; OutThreadId: PULONG): NTSTATUS;
  TDbgGetProcessIdByHandle = function(InProcessHandle: THandle; OutProcessId: PULONG): NTSTATUS;
  TDbgHandleToObjectName = function(InNamedHandle: THandle; OutNameBuffer: PUnicodeString; InBufferSize: ULONG; OutRequiredSize: PULONG): NTSTATUS;

  TRemoteEntryPoint = procedure(InRemoteInfo: PRemoteEntryInfo); stdcall;
  TRhCreateStealthRemoteThread = function(InTargetPID: ULONG; InRemoteRoutine: Pointer; InRemoteParam: Pointer; OutRemoteThread: PHandle): NTSTATUS;
  TRhInjectLibrary = function(InTargetPID: ULONG; InWakeUpTID: ULONG; InInjectionOptions: ULONG; InLibraryPath_x86: PWideChar; InLibraryPath_x64: PWideChar; InPassThruBuffer: Pointer; InPassThruSize: ULONG): NTSTATUS;
  TRhCreateAndInject = function(InEXEPath: PWideChar; InCommandLine: PWideChar; InProcessCreationFlags: ULONG; InInjectionOptions: ULONG; InLibraryPath_x86: PWideChar; InLibraryPath_x64: PWideChar; InPassThruBuffer: Pointer; InPassThruSize: ULONG; OutProcessId: PULONG): NTSTATUS;
  TRhIsX64System = function(): BOOL;
  TRhIsX64Process = function(InProcessId: ULONG; OutResult: PBOOL): NTSTATUS;
  TRhIsAdministrator = function(): BOOL;
  TRhWakeUpProcess = function(): NTSTATUS;
  TRhInstallSupportDriver = function(): NTSTATUS;
  TRhInstallDriver = function(InDriverPath: PWideChar; InDriverName: PWideChar): NTSTATUS;

implementation

end.

 
unit UEasyHookLib;

interface


uses
  Windows,
  UEasyHook;


type
   TEasyHookLib =class(TObject)
   private
     IsLoad:Boolean;
     _LhInstallHook :TLhInstallHook;
     _LhSetExclusiveACL :TLhSetExclusiveACL;
     procedure InitAPI;
   protected
   public
     function LhInstallHook(InEntryPoint: Pointer; InHookProc: Pointer; InCallback: Pointer; OutHandle: PTraceHookHandle): NTSTATUS;Stdcall;
     function LhSetExclusiveACL (InThreadIdList: PULONG; InThreadCount: ULONG; InHandle: PTraceHookHandle): NTSTATUS; Stdcall;
     constructor Create;
     destructor Destroy;override;
   end;


implementation

{ TEasyHookLib }

constructor TEasyHookLib.Create;
begin
  InitAPI;
end;

destructor TEasyHookLib.Destroy;
begin

  inherited;
end;

procedure TEasyHookLib.InitAPI;
var
  DLLHandle :THandle;
  a:Integer;
begin
  IsLoad :=False;

  a:=SizeOf(TLocalHookInfo);

  DLLHandle :=LoadLibrary('EasyHook32.dll');
  if DLLHandle<>0 then
  begin
    @_LhInstallHook :=GetProcAddress(DLLHandle,'_LhInstallHook@16');
    @_LhSetExclusiveACL :=GetProcAddress(DLLHandle,'_LhSetExclusiveACL@12');
    if @_LhInstallHook<>nil then
    begin
        IsLoad :=True;
    end;
  end;
end;

function TEasyHookLib.LhInstallHook(InEntryPoint, InHookProc,
  InCallback: Pointer; OutHandle: PTraceHookHandle): NTSTATUS;
begin
  Result :=1;
  if IsLoad then
  begin
    Result := _LhInstallHook(InEntryPoint,InHookProc,InCallback,OutHandle);
  end;
end;

function TEasyHookLib.LhSetExclusiveACL(InThreadIdList: PULONG;
  InThreadCount: ULONG; InHandle: PTraceHookHandle): NTSTATUS;
begin
   Result :=1;
  if IsLoad then
  begin
    Result := _LhSetExclusiveACL(InThreadIdList,InThreadCount,InHandle);
  end;
end;

end.