关于全局API Hook的一个问题,请大家帮忙。

                            
以下是我的代码,并不算很长,应该也是写得很清楚的了。代码后面有文字说明   
   
  以下是DLL的代码  
  library   dll;  
   
  uses  
      SysUtils,  
      Windows,  
      Classes,  
      Dialogs,  
      APIHook   in   'APIHook.pas';  
   
  var  
      Hook:HHOOK;  
   
  function   GetMsgProc(nCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;  
  begin  
      Result   :=   0;  
  end;  
   
  procedure   SetHook;  
  begin  
      Hook   :=   SetWindowsHookEx(WH_GETMESSAGE,@GetMsgProc,hInstance,0);  
  end;  
   
  procedure   RemoveHook;  
  begin  
      UnHookWindowsHookEx(Hook);  
  end;  
   
  exports  
      SetHook,   RemoveHook;  
   
  {$R   *.res}  
   
  begin  
      APIHook_Up;  
  end.  
   
   
   
   
  以下是APIHook单元的代码  
  unit   APIHook;  
   
  interface  
   
  uses  
      Windows,   Messages,   Classes,   SysUtils,   Dialogs;  
   
  type  
        PImage_Import_Entry   =   ^Image_Import_Entry;  
        Image_Import_Entry   =   record  
              Characteristics:   DWORD;  
              TimeDateStamp:   DWORD;  
              MajorVersion:   Word;  
              MinorVersion:   Word;  
              Name:   DWORD;  
              LookupTable:   DWORD;  
        end;  
   
        TImportCode   =   packed   record  
              JumpInstruction:   Word;  
              AddressOfPointerToFunction:   ^Pointer;  
        end;  
        PImportCode   =   ^TImportCode;  
   
        //TSetFocus   =   function(hWnd:   HWND):   HWND;   stdcall;  
   
        TDeleteFileW   =   function(lpFileName:   PWideChar):   BOOL;   stdcall;  
        TDeleteFileA   =   function(lpFileName:   PAnsiChar):   BOOL;   stdcall;  
        TDeleteFile   =   function(lpFileName:   PChar):   BOOL;   stdcall;  
   
        function   LocateFunctionAddress(Code:   Pointer):   Pointer;stdcall;  
        function   RepointFunction(OldFunc,   NewFunc:   Pointer):   Integer;stdcall;  
        procedure   APIHook_Up;stdcall;  
        procedure   APIHook_Off;stdcall;  
   
  var  
      OldDeleteFileW:TDeleteFileW;  
      OldDeleteFileA:TDeleteFileA;  
      OldDeleteFile:TDeleteFile;  
      FuncDeleteFileW:   PImportCode;  
      FuncDeleteFileA:   PImportCode;  
      FuncDeleteFile:   PImportCode;  
  implementation  
  ////////////////////////////////////////////////////////////////////////  
   
  function   MyDeleteFileW(lpFileName:   PWideChar):   BOOL;   stdcall;  
  begin  
      MessageBox(0,'qqq','qqq',mb_ok);  
      Result:=   true;  
  end;  
   
  function   MyDeleteFileA(lpFileName:   PAnsiChar):   BOOL;   stdcall;  
  begin  
      MessageBox(0,'qqq','qqq',mb_ok);  
      Result:=   true;  
  end;  
   
  function   MyDeleteFile(lpFileName:   PChar):   BOOL;   stdcall;  
  begin  
      MessageBox(0,'qqq','qqq',mb_ok);  
      Result:=   true;  
  end;  
   
  ////////////////////////////////////////////////////////////////////////  
   
  function   LocateFunctionAddress(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   RepointFunction(OldFunc,   NewFunc:   Pointer):   Integer;  
  var  
        IsDone:   TList;  
        function   RepointAddrInModule(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   :=   LocateFunctionAddress(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);  
                    RepointAddrInModule(GetModuleHandle(PChar(DLL)),   OldFunc,   NewFunc);  
                    Func   :=   Pointer(Integer(DOS)   +   ImportDesc.LookupTable);  
                    while   Func^   <>   nil   do  
                    begin  
                          f   :=   LocateFunctionAddress(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   :=   RepointAddrInModule(GetModuleHandle(nil),   OldFunc,   NewFunc);  
        finally  
              IsDone.Free;  
        end;  
  end;  
   
  Procedure   PermuteFunction(OldFunc:Pointer;   NewFunc:Pointer);  
  var  
      written:   DWORD;  
  begin  
      WriteProcessMemory(GetCurrentProcess,OldFunc,@NewFunc,4,written);  
  end;  
   
   
  procedure   APIHook_Up;  
  begin  
   
      if   @OldDeleteFileW   =   nil   then  
          @OldDeleteFileW   :=   LocateFunctionAddress(@DeleteFileW);  
   
      if   @OldDeleteFileA   =   nil   then  
          @OldDeleteFileA   :=   LocateFunctionAddress(@DeleteFileA);  
   
      if   @OldDeleteFile   =   nil   then  
          @OldDeleteFile   :=   LocateFunctionAddress(@DeleteFile);  
   
      PermuteFunction(funcDeleteFileW.AddressOfPointerToFunction,   @MyDeleteFileW);  
      PermuteFunction(funcDeleteFileA.AddressOfPointerToFunction,   @MyDeleteFileA);  
      PermuteFunction(funcDeleteFile.AddressOfPointerToFunction,   @MyDeleteFile);  
   
  end;  
   
  procedure   APIHook_Off;  
  begin  
      If   @OldDeleteFileW   <>   nil   then  
      begin  
              PermuteFunction(funcDeleteFileW.AddressOfPointerToFunction,   @OldDeleteFileW);  
      end;  
   
      If   @OldDeleteFileA   <>   nil   then  
      begin  
              PermuteFunction(funcDeleteFileA.AddressOfPointerToFunction,   @OldDeleteFileA);  
      end;  
   
      If   @OldDeleteFile   <>   nil   then  
      begin  
              PermuteFunction(funcDeleteFile.AddressOfPointerToFunction,   @OldDeleteFile);  
      end;  
   
  end;  
   
  initialization  
   
          FuncDeleteFile   :=   @DeleteFile;  
          FuncDeleteFileA   :=   @DeleteFileA;  
          FuncDeleteFileW   :=   @DeleteFileW;  
   
  finalization  
   
      APIHook_Off;  
   
  end.  
   
   
  本来我用新函数替换旧函数的时候调用的是RepointFunction函数  
  不知道为什么总是提示内存读取错误的信息。后来我用PermuteFunction做转换,发现对全局进程不管用。  
  我是这么操作的:  
  首先把APIHook这个单元放到我自己的一个程序中,然后再我自己的程序中调用DeleteFile函数来删除一个文件,结果是成功的。但是这并不是全局钩子,现在我要做全局钩子的话,把上面的代码放入DLL中。启动钩子后,我直接在桌面上删除一个文件,居然一点反映都没有,这到底是怎么回事啊,请问各位大哥我的代码到底哪里出了问题。或者哪里还没有考虑到的东西。  
   
  如果有可能的话,给一个DeleteFile的全局钩子的详细代码的话更好,小弟不胜感激。  
 

查看回复