線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1199
推到 Plurk!
推到 Facebook!

拦截API的元件,以栈的方式管理

 
mustapha.wang
資深會員


發表:89
回覆:409
積分:274
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-12-17 11:07:57 IP:218.1.xxx.xxx 未訂閱
看到别人拦截API的帖子,大概是最简单的,没用asm http://www.xfocus.net/articles/200205/392.html 但其中有些笔误,而且使用不方便,因此我把它整理后包装成一个元件THookStorage,让大家一行代码就能拦截,而且对同一个API可以多次拦截,附件里包含一个两次拦截MessageBoxA的例子。
unit HookAPI;
interface
uses
  Classes,Windows;
type
  PHookRec=^THookRec;
  THookRec=record
    PAddr:PPointer;
    AddrList:TList; //hooked address list
  end;      THookStorage=class
  private
    FList:TList;
  protected
    function FindHookRec(API:Pointer):PHookRec;
    function FindNewFunc(AHR:THookRec;NewFunc:Pointer):integer;
  public
    constructor Create;virtual;
    destructor Destroy;override;
    procedure Hook(API,NewFunc:Pointer);
    procedure UnHook(API,NewFunc:Pointer);
  end;
var
  HookStorage:THookStorage;
implementation
type
  PImportCode=^TImportCode;
  TImportCode=packed record
    Jump:Word; //$25FF,JUMP
    PAddr:PPointer; //address of func address
  end;    { THookStorage }    constructor THookStorage.Create;
begin
  FList:=TList.Create;
end;    destructor THookStorage.Destroy;
var
  i:integer;
  Func:Pointer;
  PHR:PHookRec;
  Written:Cardinal;
begin
  for i:=0 to FList.Count-1 do
  begin
    PHR:=PHookRec(FList[i]);
    Func:=PHR^.AddrList[0]; //origin address
    WriteProcessMemory(GetCurrentProcess,PHR^.PAddr,@Func,4,Written);
    PHR^.AddrList.Free;
    Dispose(PHR);
  end;
  FList.Free;
  inherited;
end;    function THookStorage.FindHookRec(API: Pointer): PHookRec;
var
  i:integer;
  PIC:PImportCode;
begin
  Result:=nil;
  PIC:=API;
  if PIC.Jump=$25FF then
  begin
    for i:=0 to FList.Count-1 do
    begin
      if PHookRec(FList[i]).PAddr=PIC.PAddr then
      begin
        Result:=PHookRec(FList[i]);
        break;
      end;
    end;
  end;
end;    function THookStorage.FindNewFunc(AHR: THookRec;NewFunc:Pointer): integer;
var
  i:integer;
begin
  Result:=-1;
  for i:=0 to AHR.AddrList.Count-1 do
  begin
    if AHR.AddrList[i]=NewFunc then
    begin
      Result:=i;
      break;
    end;
  end;
end;    procedure THookStorage.Hook(API,NewFunc: Pointer);
var
  PIC:PImportCode;
  Written:Cardinal;
  PHR:PHookRec;
  Index:integer;
begin
  PIC:=API;
  if PIC^.Jump=$25FF then
  begin
    PHR:=FindHookRec(API);
    if PHR=nil then
    begin
      New(PHR);
      PHR^.PAddr:=PIC.PAddr;
      PHR^.AddrList:=TList.Create;
      PHR^.AddrList.Add(PHR^.PAddr^); //origin address
      FList.Add(PHR);
    end;
    Index:=FindNewFunc(PHR^,NewFunc);
    if Index<0 then
    begin
      WriteProcessMemory(GetCurrentProcess,PIC^.PAddr,@NewFunc,4,Written);
      PHR^.AddrList.Add(NewFunc);  //new address
    end;
  end;
end;    procedure THookStorage.UnHook(API,NewFunc: Pointer);
var
  Index:integer;
  PHR:PHookRec;
  Written:Cardinal;
  Func:Pointer;
begin
  PHR:=FindHookRec(API);
  if PHR=nil then exit;
  Index:=FindNewFunc(PHR^,NewFunc);
  if Index>=0 then PHR^.AddrList.Delete(Index);
  Func:=PHR^.AddrList[PHR^.AddrList.Count-1]; //last address
  WriteProcessMemory(GetCurrentProcess,PHR^.PAddr,@Func,4,Written);
  if PHR^.AddrList.Count=1 then  //no hook
  begin
    FList.Remove(PHR);
    PHR^.AddrList.Free;
    Dispose(PHR);
  end;
end;    initialization
  HookStorage:=THookStorage.Create;
finalization
  HookStorage.Free;
end.
如果有错误,望大家不吝斧正。 久病成良医--多试 千人之诺诺,不如一士之谔谔--兼听
------
江上何人初见月,江月何年初照人
附加檔案:42255_HookAPI.rar
mustapha.wang
資深會員


發表:89
回覆:409
積分:274
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-12-18 16:24:35 IP:218.1.xxx.xxx 未訂閱
只适合那种用external引入的API,它们的头两个Byte才是jmp($25FF)     久病成良医--多试 千人之诺诺,不如一士之谔谔--兼听
------
江上何人初见月,江月何年初照人
系統時間:2024-07-04 4:31:48
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!