书上说,在WIN98下以JMP方法(改前5个字节)来拦截某些API函数!但会影响到其他进程
。这样有时会出错!我想问一下,是不是所有的被拦截函数都会影响到其他的进程!我的理解是拦截系统的API函数才会影响到别的进程!比如,屏幕取词的TEXTOUT函数等,因为这样的系统函数会加载到0x80000000以上的地址空间!所以每个进程都是可见的!而如果我要拦截的是某些不是系统DLL函数如:WSOCK32。DLL里的SENDTO函数,是不是该函数不会影响到其他的进程!我试着拦截SENDTO函数了!也没有发现WIN98下出错啊!

解决方案 »

  1.   

    ……是这样的,jmp要修改的是dll的函数地址,如果成功修改那么系统中所有程序调用此
    函数都会跳入你设定的地址。这是一个比较全面的解决方法,但问题是在你修改的时候
    不能保证别的程序不会调用此函数,如果线程切换,而你并没有结束修改动作,恰好有
    程序调用了这个函数,结果当然可想而知了。
      

  2.   

    那我要是让某一程序调用我的函数呢!而不是全部程序,先在DLL运行时判断一下是不是我要运行的程序,如果是就替换,不是的话就什么也不做!这样的话,就不会影响到别的进程了吧!
      

  3.   

    恐怕不行。SENDTO就是在WSOCK32.dll中实现的,而jmp修改的是sendto的前5个字节,也就是说修改了WSOCK32.dll。那么任何调用此函数的程序得到的都是修改后的结果。也就是说,这是一种系统级的解决方案。有两个问题:一个是jmp的硬编码使得移植性不好,另一个是在你修改sendto的时候刚好有别的程序调用这个函数。
    不过这种情况也很极端,jeffery的《windows核心编程》中提到了jmp的方法,也说了它的问题。但是他没给出解决这种问题的办法。
    但是现在很多程序都是用jmp来hookapi的,而且运行的也很好。不知道用了什么办法,难道仅仅是线程同步?
      

  4.   

    amd没问题,Alpha的就不行了。
      

  5.   

    KAO..还是没有反应..怎么回事?
    为什么是前5个字节??
    它的结构是什么样子??
    我很想知道啊..
      

  6.   

    type
      TCode5 = packed record
        jcode: shortint;
      Address: DWORD;
      end;
    .........
    jmp.jcode := ShortInt($E9); //jmp 机器码
    jmp.Address := DWORD(@SecondTest) - DWORD(@FirstTest) - 5; 
    //目的地址-原地址
    //地址偏移-结构大小 
    用 WriteProcessMemory 写到目标函数的地址处。
      

  7.   

    jmp.Address := DWORD(@SecondTest) - DWORD(@FirstTest) - 5; 
    //目的地址-原地址
    //地址偏移-结构大小 
    是什么意思?没看明白,哪位给解释一下??????
      

  8.   

    相关Unit
    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.
      

  9.   

    应该不是吧,挂钩程序可以指定要挂接哪个线称(过程)吧,只是在内存中替换了被调用的dll副本的函数入口地址,应该不会对全局产生影响。
      

  10.   


    library MyAPIDLL;{ Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }uses
       HookAPI, Windows;type
       TTextOutA = function(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
       TTextOutW = function(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
       TTextOut = function(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall;
       TDrawTextA = function(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
       TDrawTextW = function(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
       TDrawText = function(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
    var
       OldTextOutA: TTextOutA;
       OldTextOutW: TTextOutW;
       OldTextOut: TTextOut;
       OldDrawTextA: TDrawTextA;
       OldDrawTextW: TDrawTextW;
       OldDrawText: TDrawText;function MyTextOutA(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
    begin
       OldTextOutA(DC, X, Y, 'ABC', length('ABC'));
    end;function MyTextOutW(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
    begin
       OldTextOutW(DC, X, Y, 'ABC', length('ABC'));
    end;function MyTextOut(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall;
    begin
       OldTextOut(DC, X, Y, 'ABC', length('ABC'));
    end;function MyDrawTextA(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
    begin
       OldDrawTextA(hDC, 'ABC', length('ABC'), lpRect, uFormat);
    end;function MyDrawTextW(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
    begin
       OldDrawTextW(hDC, 'ABC', length('ABC'), lpRect, uFormat);
    end;function MyDrawText(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
    begin
       OldDrawText(hDC, 'ABC', length('ABC'), lpRect, uFormat);
    end;procedure API_Hookup; stdcall;
    begin
    //&micro;÷&Oacute;&Atilde;&Ecirc;±&Icirc;&Ograve;&Atilde;&Ccedil;&Ograve;&ordf;°&Ntilde;&Ocirc;&shy;&Agrave;&acute;&micro;&Auml;&ordm;&macr;&Ecirc;&yacute;&micro;&Oslash;&Ouml;·±&pound;&acute;&aelig;&Iuml;&Acirc;&Agrave;&acute;&pound;&ordm;
       if @OldTextOutA = nil then
          @OldTextOutA := LocateFunctionAddress(@TextOutA);
       if @OldTextOutW = nil then
          @OldTextOutW := LocateFunctionAddress(@TextOutW);
       if @OldTextOut = nil then
          @OldTextOut := LocateFunctionAddress(@TextOut);
       if @OldDrawTextA = nil then
          @OldDrawTextA := LocateFunctionAddress(@DrawTextA);
       if @OldDrawTextW = nil then
          @OldDrawTextW := LocateFunctionAddress(@DrawTextW);
       if @OldDrawText = nil then
          @OldDrawText := LocateFunctionAddress(@DrawText);
    //&Egrave;&raquo;&ordm;ó&ordm;&Uuml;&Euml;&sup3;&AElig;&auml;×&Ocirc;&Egrave;&raquo;&micro;&Auml;&Oacute;&Atilde;×&Ocirc;&frac14;&ordm;&micro;&Auml;&ordm;&macr;&Ecirc;&yacute;&Igrave;&aelig;&raquo;&raquo;&micro;&ocirc;&Ocirc;&shy;&Agrave;&acute;&micro;&Auml;&ordm;&macr;&Ecirc;&yacute;
       RepointFunction(@OldTextOutA, @MyTextOutA);
       RepointFunction(@OldTextOutW, @MyTextOutW);
       RepointFunction(@OldTextOut, @MyTextOut);
       RepointFunction(@OldDrawTextA, @MyDrawTextA);
       RepointFunction(@OldDrawTextW, @MyDrawTextW);
       RepointFunction(@OldDrawText, @MyDrawText);
    end;procedure API_HookDown; stdcall;
    begin
       if @OldTextOutA <> nil then
          begin
            RepointFunction(@MyTextOutA, @OldTextOutA);
            @OldTextOutA := nil;
          end;
       if @OldTextOutW <> nil then
          begin
            RepointFunction(@MyTextOutW, @OldTextOutW);
            @OldTextOutW := nil;
          end;
       if @OldTextOut <> nil then
          begin
            RepointFunction(@MyTextOut, @OldTextOut);
            @OldTextOut := nil;
          end;
       if @OldDrawTextA <> nil then
          begin
            RepointFunction(@MyDrawTextA, @OldDrawTextA);
            @OldDrawTextA := nil;
          end;
       if @OldDrawTextW <> nil then
          begin
            RepointFunction(@MyDrawTextW, @OldDrawTextW);
            @OldDrawTextW := nil;
          end;
       if @OldDrawText <> nil then
          begin
            RepointFunction(@MyDrawText, @OldDrawText);
            @OldDrawText := nil;
          end;
    end;Exports
      API_Hookup, API_HookDown;
    end.
      

  11.   

    对于2000/XP有没有问题的,98就不Ok了只对当前的Exe有效unit Demo;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, ExtCtrls, Menus;type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Label1: TLabel;
        Panel1: TPanel;
        GroupBox1: TGroupBox;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    procedure API_Hookup; stdcall; external 'MYAPIDLL.dll';
    procedure API_HookDown;  stdcall; external 'MYAPIDLL.dll';
    var
      Form1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
    var
      i:integer;
    begin
      API_Hookup;
      Self.Repaint;
      for i:=0 to self.ControlCount-1 do
      begin
         self.Controls[i].Refresh;
      end;
    end;procedure TForm1.Button2Click(Sender: TObject);
    var
      i:integer;
    begin
      API_HookDown;
      Self.Repaint;
      for i:=0 to self.ControlCount-1 do
      begin
         self.Controls[i].Refresh;
      end;  
    end;end.