前几日得到一Hook API的例程,关于Hook TextOutA,DrawTextW等函数的。
但只能对自已的程序起作用而不能对所有系统程序有作用,不知何故?
请大家指点。

解决方案 »

  1.   

    具体代码如下:
    unit HookAPI;interfaceuses
       Windows, Classes;
    function LocateFunctionAddress(Code: Pointer): Pointer;
    function RepointFunction(OldFunc, NewFunc: Pointer): Integer;type //定义一个入口结构
       PImage_Import_Entry = ^Image_Import_Entry;
       Image_Import_Entry = record
          Characteristics: DWORD;
          TimeDateStamp: DWORD;
          MajorVersion: Word;
          MinorVersion: Word;
          Name: DWORD;
          LookupTable: DWORD;
       end;type //定义一个跳转的结构
       TImportCode = packed record
          JumpInstruction: Word; //定义跳转指令jmp
          AddressOfPointerToFunction: ^Pointer; //定义要跳转到的函数
       end;
       PImportCode = ^TImportCode;
    implementationfunction 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;end.
      

  2.   

    没细看,但你的API HOOK是改写的本身进程的IDT表(也就是改了调用API的入口地址)不是API的真实地址,当然只对本身有效.
      

  3.   

    做个钩子DLL,在主函数中写下上面的代码即可,其它进程会主动加载这个DLL,也就达到了你的目的
      

  4.   

    我记得当时有一份“兄弟变速器”提供了C的源码的,哪位大虾能改成Delphi版本的?谢了!
      

  5.   

    我给你一份变速器源码,delphi的,用了ring0,留下email
      

  6.   

    [email protected]
    谢了
    我会给分的.