Hook API相关技术以及例子,Hook API的原理其实是通过核心函数强制修改原API的头部指针

Hook API的原理其实是通过核心函数强制修改原API的头部指针,使其无条件跳转到自定义函数指针来实现的,如果学过汇编原理,其实就是jmp xxx

library HookComPort;

uses
  Windows,
  SysUtils,
  Classes;

type
  TCreateFile = function(lpFileName: PAnsiChar; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall;
  TWriteFile = function(hFile: THandle; const Buffer; nNumberOfBytesToWrite: DWORD; var lpNumberOfBytesWritten: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;
  TReadFile = function(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD; var lpNumberOfBytesRead: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;
  TMessageBox = function(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;

  TImportCode = packed record
    JumpInstruction: Word;
    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;

  TCallBack = packed record
    FileName: array [0..255] of char;
    FileHandle: THandle;
    MainHandle: THandle;
    CreaetFile_Msg: Cardinal;
    ReadFile_Msg: Cardinal;
    WriteFile_Msg: Cardinal;
  end;

var
  hMappingFile: THandle = INVALID_HANDLE_VALUE;
  pCallBack: ^TCallBack;
  HookHandle: THandle = INVALID_HANDLE_VALUE;
  OldCreateFile: TCreateFile = nil;
  OldWriteFile: TWriteFile = nil;
  OldReadFile: TReadFile = nil;
  OldMessageBox: TMessageBox = nil;

{$R *.res}

function FinalFunctionAddress(Code: Pointer): Pointer;
var
  func: PImportCode;
begin
  Result := Code;
  if Code = nil then exit;
  try
    func:=code;
    if (func.JumpInstruction = $25FF) then Result := func.AddressOfPointerToFunction^;
  except
    Result := nil;
  end;
end;

function PatchAddress(OldFunc, NewFunc: Pointer): Integer;
var
  BeenDone: TList;
  function PatchAddressInModule(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;
    Dos := Pointer(hModule);
    if BeenDone.IndexOf(Dos) >= 0 then exit;
    BeenDone.Add(Dos);
    OldFunc := FinalFunctionAddress(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);
      PatchAddressInModule(GetModuleHandle(PChar(DLL)), OldFunc, NewFunc);
      Func := Pointer(Integer(DOS) + ImportDesc.LookupTable);
      while Func^ <> nil do
      begin
        f := FinalFunctionAddress(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
  BeenDone := TList.Create;
  try
    Result := PatchAddressInModule(GetModuleHandle(nil), OldFunc, NewFunc);
  finally
    BeenDone.Free;
  end;
end;

function GetMsgProc(code: integer; removal: integer; msg: Pointer): Integer; stdcall;
begin
  Result := 0;
end;

procedure StartHook; stdcall;
begin
  HookHandle := SetWindowsHookEx(WH_MAXHOOK, @GetMsgProc, LoadLibrary('HookComPort.Dll'), 0);
end;

procedure StopHook; stdcall;
begin
  UnhookWindowsHookEx(HookHandle);
end;

function MyMessageBox(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
begin
  Result := OldMessageBox(hWnd, lpText, PChar(String(lpCaption) + ':)'), uType);
end;

function MyCreateFile(lpFileName: PAnsiChar; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; stdcall;
begin
  Result := OldCreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
  if StriComp(lpFileName, pCallBack.FileName) = 0 then
  begin
    pCallBack.FileHandle := Result;
    PostMessage(pCallBack.MainHandle, pCallBack.CreaetFile_Msg, Result, Result);
  end;
end;

function MyWriteFile(hFile: THandle; const Buffer; nNumberOfBytesToWrite: DWORD; var lpNumberOfBytesWritten: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;
var
  Data: array of char;
begin
  Result := OldWriteFile(hFile, Buffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
  if hFile = pCallBack.FileHandle then
  begin
    SetLength(Data, nNumberOfBytesToWrite);
    CopyMemory(Data, @Buffer, nNumberOfBytesToWrite);
    PostMessage(pCallBack.MainHandle, pCallBack.WriteFile_Msg, GlobalAddAtom(PChar(Data)), nNumberOfBytesToWrite + 1);
  end;
end;

function MyReadFile(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD; var lpNumberOfBytesRead: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;
var
  Data: array of char;
begin
  Result := OldReadFile(hFile, Buffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
  if hFile = pCallBack.FileHandle then
  begin
    SetLength(Data, nNumberOfBytesToRead);
    CopyMemory(Data, @Buffer, nNumberOfBytesToRead);
    PostMessage(pCallBack.MainHandle, pCallBack.ReadFile_Msg, GlobalAddAtom(PChar(Data)), nNumberOfBytesToRead + 1);
  end;
end;

procedure HookComPortOn;
begin
  if hMappingFile = INVALID_HANDLE_VALUE then
  begin
    hMappingFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TCallBack), 'HookComPort');
    pCallBack := MapViewOfFile(hMappingFile, FILE_MAP_WRITE or FILE_MAP_READ, 0, 0, 0);
  end;

  if @OldMessageBox = nil then
  begin
    @OldMessageBox := FinalFunctionAddress(@MessageBoxA);
    PatchAddress(@OldMessageBox, @MyMessageBox);
  end;

  if @OldCreateFile = nil then
  begin
    @OldCreateFile := FinalFunctionAddress(@CreateFileA);
    PatchAddress(@OldCreateFile, @MyCreateFile);
  end;

  if @OldWriteFile = nil then
  begin
    @OldWriteFile := FinalFunctionAddress(@WriteFile);
    PatchAddress(@OldWriteFile, @MyWriteFile);
   end;

  if @OldReadFile = nil then
  begin
    @OldReadFile := FinalFunctionAddress(@ReadFile);
    PatchAddress(@OldReadFile, @MyReadFile);
  end;

end;

procedure HookComPortOff;
begin
  if hMappingFile <> INVALID_HANDLE_VALUE then
  begin
    UnMapViewOfFile(pCallBack);
    CloseHandle(hMappingFile);
  end;

  if @OldMessageBox <> nil then PatchAddress(@MyMessageBox, @OldMessageBox);
  if @OldCreateFile <> nil then PatchAddress(@MyCreateFile, @OldCreateFile);
  if @OldWriteFile <> nil then PatchAddress(@MyWriteFile, @OldWriteFile);
  if @OldReadFile <> nil then PatchAddress(@MyReadFile, @OldReadFile);
end;

procedure DLLEntryPoint(dwReason: DWord);
begin
  case dwReason of
    DLL_PROCESS_ATTACH: HookComPortOn;
    DLL_PROCESS_DETACH: HookComPortOff;
  end;
end;

exports
  StartHook,
  StopHook;

begin
  DllProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值