⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unitwjshook.bak

📁 临视串口的传输
💻 BAK
字号:
unit UnitWJSHook;

interface

uses classes,Windows,messages;


type
  PPointer = ^Pointer;
  TImportCode = packed record
    JumpInstruction: Word; // should be $25FF  即 FF 25
    AddressOfPointerToFunction: PPointer;
  end;
  PImportCode = ^TImportCode;

  PImage_Import_Entry = ^Image_Import_Entry;
  Image_Import_Entry = record
    Characteristics: DWORD;
    TimeDateStamp: DWORD;
    MajorVersion: Word;
    MinorVersion: Word;
    Name: DWORD;
    LookupTable: DWORD;
  end;

  HookStruct = record
     OldFunction,NewFunction:Pointer;
  end;
  function FinalFunctionAddress(Code: Pointer): Pointer;
  procedure HookAPIFunction(hook:HookStruct);
  procedure UnHookAPIFunction(hook:HookStruct);

implementation

function FinalFunctionAddress(Code: Pointer): Pointer;
//取函数的实际地址
//如果函数的第一个指令是Jmp指令,则取出它的跳转地址(实际地址)
Var
  func: PImportCode;
begin
  Result:=Code;
  if Code=nil then exit;
  try
    func:=code;
    if (func.JumpInstruction=$25FF) then begin
      //指令二进制码FF 25  汇编指令jmp [...]
      Result:=func.AddressOfPointerToFunction^;
    end;
  except
    Result:=nil;
  end;
end;

function PatchAddressInModule(BeenDone:Tlist;hModule: THandle; OldFunc,NewFunc: Pointer):integer;
Var
   Dos: PImageDosHeader;
   NT: PImageNTHeaders;
   ImportDesc: PImage_Import_Entry;
   rva: DWORD;
   Func: PPointer;
   DLL: String;
   f: Pointer;
   written: DWORD;
begin
  Result:=0;
  if hModule=0 then exit;
  Dos:=Pointer(hModule);
  // 如果这个模块已经处理过,就退出。BeenDone包含已处理的模块。
  if BeenDone.IndexOf(Dos)>=0 then exit;
  BeenDone.Add(Dos); //把模块名加入BeenDone

  OldFunc:=FinalFunctionAddress(OldFunc);  //取函数的实际地址
  //如果对这个模块没有读的权限,则退出。
  if IsBadReadPtr(Dos,SizeOf(TImageDosHeader)) then exit;
  //如果这个模块不是以'MZ'开头,表明不是EXE、DLL,则退出。
  if Dos.e_magic<>IMAGE_DOS_SIGNATURE then exit; //IMAGE_DOS_SIGNATURE='MZ'

  //windows的PE文件(EXE、DLL)分为DOS、Windows两个部分。
  //._lfanew是PE文件中Windows部分的起始地址。
  NT :=Pointer(Integer(Dos) + dos._lfanew);
  //if IsBadReadPtr(NT,SizeOf(TImageNtHeaders)) then exit;


  //找出这个模块调用了其它DLL的哪些函数
  RVA:=NT^.OptionalHeader.   //模块windows部分的第三小部分OptionalHeader
     DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].  //中的函数引用表
         VirtualAddress; //的入口地址
  if RVA=0 then exit; //如果没有调用,则退出。

  ImportDesc := pointer(DWORD(Dos)+RVA); //求函数引用表的绝对地址,RVA只是相对地址
  While (ImportDesc^.Name<>0) do //历遍所有被引用的DLL模块
  begin
    DLL:=PChar(DWORD(Dos)+ImportDesc^.Name); //被当前模块引用的DLL模块名字
    //嵌套调用本函数,历遍DLL相互交差引用函数的网状结构
    //把这个被引用的DLL当作当前模块,重复以上过程
    PatchAddressInModule(BeenDone,GetModuleHandle(PChar(DLL)),OldFunc,NewFunc);

    //找出被引用的DLL模块的每一个功能函数
    Func:=Pointer(DWORD(DOS)+ImportDesc.LookupTable);
    While Func^<>nil do //历遍被引用的DLL模块的所有功能函数
    begin
      f:=FinalFunctionAddress(Func^); //取实际地址
      if f=OldFunc then //如果函数实际地址就是所要找的地址
         WriteProcessMemory(GetCurrentProcess,Func,@NewFunc,4,written); //把新函数地址覆盖它
      If Written>0 then Inc(Result);
      Inc(Func); //下一个功能函数
    end;
    Inc(ImportDesc); //下一个DLL模块
  end;
end;

procedure HookAPIFunction(hook:HookStruct);
Var
 BeenDone: TList;
begin
  if (hook.NewFunction=nil)or(hook.NewFunction=nil)then exit;
  BeenDone:=TList.Create; //用于存放所有模块的名字
  try
    PatchAddressInModule(BeenDone,GetModuleHandle(nil),hook.OldFunction,hook.NewFunction);
  finally
    BeenDone.Free;
  end;
end;

procedure UnHookAPIFunction(hook:HookStruct);
Var
 BeenDone: TList;
begin
  if (hook.NewFunction=nil)or(hook.NewFunction=nil)then exit;
  BeenDone:=TList.Create; //用于存放所有模块的名字
  try
    PatchAddressInModule(BeenDone,GetModuleHandle(nil),hook.NewFunction,hook.OldFunction);
  finally
    BeenDone.Free;
  end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -