问题描述:怎么hook windows的系统API?咨询范围:实现方法描述,实现代码。
给分标准:
          回贴内容清晰明确,深入浅出者回赠高分。
          回贴全面深入,不掺水分的,可以考虑标准分值(100分)相送。
          回贴能够对理解问题有较大帮助者另有50分相赠。
          贴面上的分数不是给分上限,按以上标准给分,达到标准的有一个给一个。
          欢迎对这问题有兴趣的朋友一起来UP,共同提高。
          欢迎大家对问题提出自已的见解和想法(不给分)。
          谢绝回贴捞分者。

解决方案 »

  1.   

    看看这些标准,我看我还是不说的好,省得挨骂。
    这样的资料多的是,只要把C的换成Delphi就行了。如果直接用C,换都不要换了。
      

  2.   

    修改引入表函数的API HOOK如何能HOOK到加壳的程序?
      

  3.   

    ^-^ eg 多的很,自己找吗~搜索一会就OK了
      

  4.   

    1、自定义一个记录
    ------------------------------------------------TImportCode = packed record
      JumpInstruction           :  Word;    //  应该是$25FF,JUMP指令
      AddressOfPointerToFunction:  PPointer;//  真正的开始地址
    end;
    PImportCode = ^TImportCode;------------------------------------------------2、用下面的函数返回函数的真正地址
    ------------------------------------------------
    function TrueFunctionAddress(func: Pointer): Pointer;
    var
      Code: PImportCode;
    begin
      Result:= func;
      if func = nil then exit;
      try
        Code := func;
        if (Code.JumpInstruction = $25FF) then begin
          Result := Code.AddressOfPointerToFunction^;
        end;
      except
        Result := nil;
      end;
    end;------------------------------------------------3、替换函数:
    Procedure PermuteFunction(OldFunc:PPOinter; NewFunc:Pointer);
    var
      written: DWORD;
    begin
      WriteProcessMemory(GetCurrentProcess, OldFunc, @NewFunc, 4, written);
    end;------------------------------------------------4、第一个程序
    ------------------------------------------------
    unit mess;interface
    uses
      Windows, Messages, SysUtils, Classes, APIHook;procedure API_Hookup;
    procedure Un_API_Hook;var
      FuncMessageboxA, FuncMessageboxW: PImportCode;implementationtype
      TMessageA = function(hwn: hwnd; lptext: pchar; lpcapion: pchar; utype: cardinal): integer; stdcall;
      TMessageW = function(hwn: hwnd; lptext: pwidechar; lpcapion: pwidechar; utype: cardinal): integer; stdcall;var
      OldMessageBoxA: TMessageA;
      OldMessageBoxW: TMessageW;
    function MyBoxA(hwn:hwnd;lptext:pchar;lpcapion:pchar;utype:cardinal): integer; stdcall;
    begin
      result := OldMessageBoxA(hwn, 'Succes Hook A !', lpcapion, utype);
    end;function MyBoxw(hwn:hwnd;lptext:pwidechar;lpcapion:pwidechar;utype:cardinal): integer; stdcall;
    begin
      result := OldMessageBoxW(hwn, '成功挂上W!', lpcapion, utype);
    end;procedure API_Hookup;
    begin
      if @OldMessageBoxA = nil then
        @OldMessageBoxA := TrueFunctionAddress(@messageboxA);
      if @OldMessageBoxW = nil then
        @OldMessageBoxW := TrueFunctionAddress(@messageboxW);  PermuteFunction(FuncMessageboxA.AddressOfPointerToFunction, @MyBoxA);
      PermuteFunction(FuncMessageboxW.AddressOfPointerToFunction, @MyBoxW);
    end;procedure Un_API_hook;
    begin
      If @OldMessageBoxA <> nil then begin
        PermuteFunction(FuncMessageboxA.AddressOfPointerToFunction, @OldMessageboxA);
        PermuteFunction(FuncMessageboxW.AddressOfPointerToFunction, @OldMessageboxW);
      end;
    end;initialization
       FuncMessageboxA := @MessageboxA;
       FuncMessageboxW := @MessageboxW;
    end.------------------------------------------------5、在主窗体上添加三个按钮,添加Onclick代码,如下:
    ------------------------------------------------
    procedure TForm1.Button1Click( Sender : TObject);
    begin
      API_HookUp;
    end;procedure TForm1.Button3Click( Sender : TObject);
    begin
      Un_API_Hook;
    end;procedure TForm1.Button2Click( Sender : TObject);
    begin
      MessageBoxA(Form1.Handle,'NO HOOK UP A','MessageBoxA',MB_OK);
      MessageBoxW(Form1.Handle,'NO HOOK UP W','MessageBoxW',MB_OK);
    end;------------------------------------------------6、如果现在新建一个Application TestTry,在Form上添加一个按钮,
    其Onclick事件如下:
    ------------------------------------------------
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      MessageBoxA(Form1.Handle,'NO HOOK UP A','MessageBoxA',MB_OK);
      MessageBoxW(Form1.Handle,'NO HOOK UP W','MessageBoxW',MB_OK);
      MessageBox (Form1.Handle,'NO HOOK UP BOX','MessageBox',MB_OK);
    end;___________________________________________________________
    7、第二个程序
    ___________________________________________________________uses
      Windows,
      SysUtils,
      Classes,
      APIHook in 'APIHook.pas',
      mess in 'mess.pas';{$R *.RES}function GetMsgProc(code: integer; removal: integer; msg: Pointer): Integer; stdcall;
    begin
      Result := 0;
    end;Var HookHandle: THandle;procedure StartHook; stdcall;
    begin
      HookHandle := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, HInstance, 0);
    end;procedure StopHook; stdcall;
    begin
       UnhookWindowsHookEx( HookHandle );
    end;exports StartHook, StopHook;begin
      API_Hookup; //加载时挂上
    end.-----------------------------------------------------------
    为了卸载时能解除钩子,在Unit MESS单元最后加上一句:
    -----------------------------------------------------------
    finalization
      Un_API_hook;-----------------------------------------------------------当然,别忘了对MESS做相应修改。编译好后别忘了存盘。新建Application TRY2程序,主Form的单元名称不妨叫TRYUnit2,在Form1上添加三个Button,并声明:
    -----------------------------------------------------------
    procedure StartHook; stdcall; external 'TRYDLL.DLL';
    procedure StopHook;  stdcall; external 'TRYDLL.DLL';-----------------------------------------------------------
    三个Button的OnClick代码如下:
    -----------------------------------------------------------
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      StartHook;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      MessageBoxA(Form1.Handle,'NO HOOK UP A','MessageBoxA',MB_OK);
      MessageBoxW(Form1.Handle,'NO HOOK UP W','MessageBoxW',MB_OK);
      MessageBox (Form1.Handle,'NO HOOK UP BOX','MessageBox',MB_OK);
    end;procedure TForm1.Button3Click(Sender: TObject);
    begin
      StopHook;
    end;-----------------------------------------------------------
      

  5.   

    (* ------------------------------------------- *)
    (* PermuteFunction功能  :用 NewFunc替代 OldFunc    *)
    (*                      Windows Me + Delphi 5.0     *)
    (* ------------------------------------------ *)
    unit APIHook;
    interface
    uses
      Windows,  Classes ;
    type
      PImage_Import_Entry = ^Image_Import_Entry;
      Image_Import_Entry = record
        Characteristics    : DWORD;
        TimeDateStamp      : DWORD;
        MajorVersion       : Word;
        MinorVersion       : Word;
        Name               : DWORD;
        LookupTable        : DWORD;
    end;Function TrueFunctionAddress(Code: Pointer): Pointer;
    Function PermuteFunction(OldFunc, NewFunc: Pointer): Integer;
    implementation
    type
      TImportCode = packed record
        JumpInstruction: Word;
        AddressOfPointerToFunction: ^Pointer;
      end;
      PImportCode = ^TImportCode;
    function TrueFunctionAddress(Code: Pointer): Pointer;
    var func: PImportCode;
    begin
      Result := Code;
      if Code = nil then exit;
      try
        func := code;
        if (func.JumpInstruction=$25FF) then begin
          Result := func.AddressOfPointerToFunction^;
        end;
      except
        Result := nil;
      end;
    end;Function PermuteFunction(OldFunc, NewFunc: Pointer): Integer;
    var IsDone: TList;
    Function PermuteAddrInModule(hModule: THandle; OldFunc, NewFunc: Pointer): Integer;
    var
      Dos          : PImageDosHeader;
      NT           : PImageNTHeaders;
      ImportDesc   : PImage_Import_Entry;
      RVA          : DWORD;
      Func         : ^Pointer;
      DLL          : String;
      f            : Pointer;
      written      : DWORD;
    begin
      Result := 0;
      Dos := Pointer(hModule);
      if IsDone.IndexOf(Dos) >= 0 then exit;
      IsDone.Add(Dos);
      OldFunc := TrueFunctionAddress(OldFunc);
      if IsBadReadPtr(Dos,SizeOf(TImageDosHeader)) then exit;
      if Dos.e_magic <> IMAGE_DOS_SIGNATURE then exit;
      NT := Pointer(Integer(Dos) + dos._lfanew);
      RVA := NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;  if RVA = 0 then exit;
      ImportDesc := pointer(integer(Dos)+RVA);
      While(ImportDesc^.Name<>0) do
      begin
        DLL := PChar(Integer(Dos) + ImportDesc^.Name);
        PermuteAddrInModule(GetModuleHandle(PChar(DLL)),OldFunc,NewFunc);
        Func := Pointer(Integer(DOS) + ImportDesc.LookupTable);
        While Func^ <> nil do
        begin
          f := TrueFunctionAddress(Func^);
          if f = OldFunc then
          begin
            WriteProcessMemory(GetCurrentProcess,Func,@NewFunc,4,written);
            If Written > 0 then Inc(Result);
          end;
          Inc(Func);
        end;
        Inc(ImportDesc);
      end;
    end;begin
      IsDone := TList.Create;
      try
        Result := PermuteAddrInModule(GetModuleHandle(nil),OldFunc,NewFunc);
      finally
        IsDone.Free;
      end;
    end;
    end.
      

  6.   

    想了解更详细的你就看《Windows 核心编程》和《Delphi5 开发人员指南》
    大家都是互相关心并解决问题的/无论说的对不对都是对你的关心/下次不要写的那么苛刻/
    上面的程序我记不得是怎么得到了/发出来大家学习/在这里谢谢著者/
      

  7.   

    不能HOOK到加壳程序吧...
    也不能HOOK到用LoadLibrary动态调用的API函数...
      

  8.   

    我在CSDN上说了多次了
    去FAQ区看了LoadLibrary都可以有办法解决的!
      

  9.   

    http://www.csdn.net/develop/read_article.asp?id=22765http://expert.csdn.net/Expert/FAQ/FAQ_Index.asp?id=174838http://search.csdn.net/expert/topic/53/5304/2003/3/1/1479439.xml
      

  10.   

    楼上的,你是哪条道上混的??去FAQ看,亏你说得出口,那上面几乎全部都是垃圾!!