您现在的位置:首页 >> API >> API >> 内容

Delphi写的一个函数的Hook类

时间:2011/9/3 14:53:36 点击:

  核心提示:unit HookFuncLib;interfaceuses Windows,SysUtils,Classes;const CHookJump_LEN = 5; //要修改的函数的跳转5字节,一个Jm...

unit HookFuncLib;

interface
uses Windows,SysUtils,Classes;

const
  CHookJump_LEN = 5; //要修改的函数的跳转5字节,一个Jmp指令,一个函数地址
type
  TFuncHookList = class;
  TFuncHook = class
  private
    OldProtection: DWORD;//内存区域原读写权限
    FOldFunc: Pointer;
    OldCode: array[0..4] of Byte;//要修改的原函数5字节
    NewCode: array[0..4] of Byte;
    function GetHasInstalled: Boolean;//要替换成的5字节
  public
    constructor Create(OldFunc: Pointer);
    destructor Destroy;override;
    property HasHooked: Boolean read GetHasInstalled;
    function HookFunc(NewFunc: Pointer): Boolean;
    procedure UnHookFunc;
    procedure SwapOld;
    procedure SwapNew;
  end;

  TFuncHookList = class
  private
    HookList: TStringList;
    function Getitem(index: Integer): TFuncHook;
    function GetFuncCount: Integer;
  public
    constructor Create;
    destructor Destroy;override;
    function AddHookFunc(HookName: string;OldFunc: Pointer;NewFunc: Pointer): Boolean;
    function FindHookedFunc(Func: Pointer): Integer;
    procedure UnHookFunc(HookName: string);overload;
    procedure UnHookFunc(Func: Pointer);overload;
    procedure SwapToOldFunc(HookName: string);overload;
    procedure SwapToOldFunc(Func: Pointer);overload;
    procedure SwapToNewFunc(HookName: string);overload;
    procedure SwapToNewFunc(Func: Pointer);overload;
    procedure SwapToOldFuncs;
    procedure SwapToNewFuncs;
    procedure UnHookFuncs;
    property item[index: Integer]: TFuncHook read Getitem;
    property FuncCount: Integer read GetFuncCount;
  end;
implementation

{ TFuncHook }

constructor TFuncHook.Create(OldFunc: Pointer);
begin
  OldProtection := 0;
  FOldFunc := OldFunc;
  NewCode[0] := 0;
end;

destructor TFuncHook.Destroy;
begin
  if HasHooked then
    UnHookFunc;
  inherited;
end;

function TFuncHook.GetHasInstalled: Boolean;
begin
   Result := NewCode[0] <> 0;
end;

function TFuncHook.HookFunc(NewFunc: Pointer): Boolean;
var
  OffsetAddr: DWORD; //偏移地址
begin
   Result := False;
   if (NewFunc <> nil) and (not HasHooked) then
   begin
     if VirtualProtect(FOldFunc,8,PAGE_EXECUTE_READWRITE,@OldProtection) then //解内存保护成功
     begin
       NewCode[0] := $e9;//Jmp指令机器码
       OffsetAddr := Integer(NewFunc) - Integer(FOldFunc) - SizeOf(NewCode);
       CopyMemory(@NewCode[1],@OffsetAddr,SizeOf(OffsetAddr));//将偏移地址写入NewCode的Jmp指令后
       CopyMemory(@OldCode[0],FOldFunc,SizeOf(OldCode));//保存原函数5字节
       CopyMemory(FOldFunc,@NewCode[0],SizeOf(NewCode));//替换5字节
       Result := True;
     end;
   end;
end;

procedure TFuncHook.SwapNew;
begin
  if HasHooked then
     CopyMemory(FOldFunc,@NewCode[0],SizeOf(NewCode));//恢复到新函数执行
end;

procedure TFuncHook.SwapOld;
begin
  if FOldFunc <> nil then
    CopyMemory(FOldFunc,@OldCode[0],SizeOf(OldCode));//恢复到原函数
end;

procedure TFuncHook.UnHookFunc;
var
  temp: DWORD;
begin
  if (FOldFunc <> nil) and HasHooked then
  begin
    try
      CopyMemory(FOldFunc,@OldCode[0],SizeOf(OldCode));//恢复原函数
      VirtualProtect(FOldFunc,8,OldProtection,@temp);//恢复原读写保护
      NewCode[0] := 0;
    except
     
    end;
  end;
end;
{ TFuncHookList }

function TFuncHookList.AddHookFunc(HookName: string;OldFunc, NewFunc: Pointer): Boolean;
var
  FuncHook: TFuncHook;
  index: integer;
begin
  if HookList.IndexOf(HookName) = -1 then
  begin
    index := FindHookedFunc(OldFunc);
    if index <> -1 then
    begin
      FuncHook := TFuncHook(HookList.Objects[index]);
      Result := FuncHook.HookFunc(NewFunc);
      HookList[index] := HookName;
    end
    else
    begin
      FuncHook := TFuncHook.Create(OldFunc);
      Result := FuncHook.HookFunc(NewFunc);
      HookList.AddObject(HookName,FuncHook);
    end;
  end else
    raise Exception.Create('HookName '+HookName+' 已经存在!');
end;

constructor TFuncHookList.Create;
begin
  HookList := TStringList.Create;
end;

destructor TFuncHookList.Destroy;
begin
  UnHookFuncs;
  HookList.Free;
  inherited;
end;

function TFuncHookList.FindHookedFunc(Func: Pointer): Integer;
var
  i: Integer;
label 1;
begin
  Result := -1;
  for i := 0 to HookList.Count - 1 do
  begin
    if TFuncHook(HookList.Objects[i]).FOldFunc = Func then
    begin
      Result := i;
      goto 1;
    end;
  end;
  1:
end;

procedure TFuncHookList.UnHookFunc(HookName: string);
var
  index: Integer;
begin
  index := HookList.IndexOf(HookName);
  if index <> -1 then
  begin
    TFuncHook(HookList.Objects[index]).Free;
    //HookList.Delete(index);
  end;
end;

procedure TFuncHookList.UnHookFunc(Func: Pointer);
var
  index: Integer;
begin
  index := FindHookedFunc(Func);
  if index <> -1 then
  begin
    TFuncHook(HookList.Objects[index]).Free;
    HookList.Delete(index);
  end;
end;

procedure TFuncHookList.SwapToOldFuncs;
var
  i: Integer;
begin
  for i := 0 to HookList.Count - 1 do
    TFuncHook(HookList.Objects[i]).SwapOld;
end;

procedure TFuncHookList.SwapToNewFuncs;
var
  i: integer;
begin
  for i := 0 to HookList.Count - 1 do
    TFuncHook(HookList.Objects[i]).SwapNew;
end;

procedure TFuncHookList.UnHookFuncs;
begin
  while HookList.Count > 0 do
  begin
    TFuncHook(HookList.Objects[HookList.Count - 1]).Free;
    HookList.Delete(HookList.Count - 1);
  end;
end;

procedure TFuncHookList.SwapToOldFunc(HookName: string);
var
  index: Integer;
begin
  index := HookList.IndexOf(HookName);
  if index <> -1 then
    TFuncHook(HookList.Objects[index]).SwapOld;
end;

procedure TFuncHookList.SwapToOldFunc(Func: Pointer);
var
  index: Integer;
begin
  index := FindHookedFunc(Func);
  if index <> -1 then
    TFuncHook(HookList.Objects[index]).SwapOld
end;

procedure TFuncHookList.SwapToNewFunc(HookName: string);
var
  index: Integer;
begin
  index := HookList.IndexOf(HookName);
  if index <> -1 then
    TFuncHook(HookList.Objects[index]).SwapNew;
end;

procedure TFuncHookList.SwapToNewFunc(Func: Pointer);
var
  index: Integer;
begin
  index := FindHookedFunc(Func);
  if index <> -1 then
    TFuncHook(HookList.Objects[index]).SwapNew;
end;

function TFuncHookList.Getitem(index: Integer): TFuncHook;
begin
   if (index < 0) or (index > HookList.Count - 1) then
     raise Exception.Create('超过边界');
   Result := TFuncHook(HookList.Objects[index]);
end;

function TFuncHookList.GetFuncCount: Integer;
begin
  Result := HookList.Count;
end;

end.

作者:不得闲 来源:原创
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
本类推荐
  • 没有
本类固顶
  • 没有
  • 盒子文章(www.2ccc.com) © 2024 版权所有 All Rights Reserved.
  • 沪ICP备05001939号