博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HOOK API Lib 0.1 For Delphi
阅读量:4149 次
发布时间:2019-05-25

本文共 17192 字,大约阅读时间需要 57 分钟。

 周未一个朋友要求用Delphi做了一个东西,用到了API HOOK,于是写了个简单的

SetOnBefore把函数安装到API之前,可在真正的api执行之前先执行我们的函数
SetOnAfter把函数安装到API之后,可在真正的api执行之后再执行我们的函数
代码写得比较急,还有很多地方可以优化,功能上也有些地方可以于改进一下,如:
替换api,能改变api的返回值等。。。以后有时间玩的时候再升级,没时间就算了。。。
如果你有兴趣转成VC的代码请共享一份给我:)
具体代码如下,其中GetOpCodeSize可参考我早期的“”

 

 

DelphiCode:
{Name: API Hook Lib  Version: 0.1  Author: coded by xIkUg/RCT/CCG  HomePage: http://www.wintoolspro.com, http://debugman.wintoolspro.com  CreateDate: 2006-12-03}unit uHookLib;interfaceuses  Windows, SysUtils;type  PBytes = ^Byte;  TMaskTable = array [0..517] of LongWord;var  MaskTable: TMaskTable = (    $00004000, $00004000, $00004000, $00004000,    $00008000, $00008000, $00000000, $00000000,    $00004000, $00004000, $00004000, $00004000,    $00008000, $00008000, $00000000, $00000000,    $00004000, $00004000, $00004000, $00004000,    $00008000, $00008000, $00000000, $00000000,    $00004000, $00004000, $00004000, $00004000,    $00008000, $00008000, $00000000, $00000000,    $00004000, $00004000, $00004000, $00004000,    $00008000, $00008000, $00000008, $00000000,    $00004000, $00004000, $00004000, $00004000,    $00008000, $00008000, $00000008, $00000000,    $00004000, $00004000, $00004000, $00004000,    $00008000, $00008000, $00000008, $00000000,    $00004000, $00004000, $00004000, $00004000,    $00008000, $00008000, $00000008, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00004000, $00004000,    $00000008, $00000008, $00001008, $00000018,    $00002000, $00006000, $00000100, $00004100,    $00000000, $00000000, $00000000, $00000000,    $00000100, $00000100, $00000100, $00000100,    $00000100, $00000100, $00000100, $00000100,    $00000100, $00000100, $00000100, $00000100,    $00000100, $00000100, $00000100, $00000100,    $00004100, $00006000, $00004100, $00004100,    $00004000, $00004000, $00004000, $00004000,    $00004000, $00004000, $00004000, $00004000,    $00004000, $00004000, $00004000, $00004000,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00002002, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000020, $00000020, $00000020, $00000020,    $00000000, $00000000, $00000000, $00000000,    $00000100, $00002000, $00000000, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000100, $00000100, $00000100, $00000100,    $00000100, $00000100, $00000100, $00000100,    $00002000, $00002000, $00002000, $00002000,    $00002000, $00002000, $00002000, $00002000,    $00004100, $00004100, $00000200, $00000000,    $00004000, $00004000, $00004100, $00006000,    $00000300, $00000000, $00000200, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00004000, $00004000, $00004000, $00004000,    $00000100, $00000100, $00000000, $00000000,    $00004000, $00004000, $00004000, $00004000,    $00004000, $00004000, $00004000, $00004000,    $00000100, $00000100, $00000100, $00000100,    $00000100, $00000100, $00000100, $00000100,    $00002000, $00002000, $00002002, $00000100,    $00000000, $00000000, $00000000, $00000000,    $00000008, $00000000, $00000008, $00000008,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00004000, $00004000,    $00004000, $00004000, $00004000, $00004000,    $FFFFFFFF, $FFFFFFFF, $00000000, $FFFFFFFF,    $00000000, $00000000, $00000000, $00000000,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $00002000, $00002000, $00002000, $00002000,    $00002000, $00002000, $00002000, $00002000,    $00002000, $00002000, $00002000, $00002000,    $00002000, $00002000, $00002000, $00002000,    $00004000, $00004000, $00004000, $00004000,    $00004000, $00004000, $00004000, $00004000,    $00004000, $00004000, $00004000, $00004000,    $00004000, $00004000, $00004000, $00004000,    $00000000, $00000000, $00000000, $00004000,    $00004100, $00004000, $FFFFFFFF, $FFFFFFFF,    $00000000, $00000000, $00000000, $00004000,    $00004100, $00004000, $FFFFFFFF, $00004000,    $00004000, $00004000, $00004000, $00004000,    $00004000, $00004000, $00004000, $00004000,    $FFFFFFFF, $FFFFFFFF, $00004100, $00004000,    $00004000, $00004000, $00004000, $00004000,    $00004000, $00004000, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $00000000, $00000000, $00000000, $00000000,    $00000000, $00000000, $00000000, $00000000,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $00000000, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,    $FFFFFFFF, $FFFFFFFF  );function SetOnBefore(const DllName: string; const ApiName: string;  HookProc: Pointer): Boolean;function SetOnAfter(const DllName: string; const ApiName: string;  HookProc: Pointer): Boolean;  function GetOpCodeSize(Start: Pointer; Tlb: TMaskTable): integer; stdcall;implementationvar  JMPGate: array [0..4] of byte = (    $E9, $00, $00, $00, $00       // JMP XXXXXXXX  );  // HookProc offset is 36  // HookApi offset is  82  BeforeStub: array [0..93] of byte = (    $58,                            // 0 pop     eax    $EB, $08,                       // 1 jmp     short 0040100B    $00, $00, $00, $00,             // 3 dd      00000000    $00, $00, $00, $00,             // 7 dd      00000000    $E8, $00, $00, $00, $00,        // 11 call    00401010    $59,                            // 16 pop     ecx    $81, $E9, $10, $10, $40, $00,   // 17 sub     ecx, 00401010    $89, $A1, $03, $10, $40, $00,   // 23 mov     [ecx+401003], esp    $89, $81, $07, $10, $40, $00,   // 29 mov     [ecx+401007], eax    $E8, $36, $01, $00, $00,        // 35 call    HookProc    $8B, $44, $24, $FC,             // 40 mov     eax, [esp - 4]    $E8, $00, $00, $00, $00,        // 44 call    0040102D    $59,                            // 49 pop     ecx    $89, $44, $24, $FC,             // 50 mov [esp - 4], eax    $81, $E9, $31, $10, $40, $00,   // 54 sub     ecx, 0040102D    $8B, $A1, $03, $10, $40, $00,   // 60 mov     esp, [ecx+401003]    $8B, $81, $07, $10, $40, $00,   // 66 mov     eax, [ecx+401007]    $50,                            // 72 push    eax    $90, $90, $90, $90,             // 73    $90, $90, $90, $90,    $90, $90, $90, $90,    $90, $90, $90, $90,       $E9, $18, $01, $00, $00         // 89 jmp     HookedApi  );  AfterStub: array [0..129] of Byte = (    $58,                            // 00   pop     eax    $EB, $0C,                       // 01   jmp     short 0040100F    $00, $00, $00, $00,             // 03   dd      00000000    $00, $00, $00, $00,             // 07   add     [eax], al    $00, $00, $00, $00,             // 0B   add     [eax], al    $E8, $00, $00, $00, $00,        // 0F   call    00401014    $59,                            // 14   pop     ecx    $81, $E9, $14, $10, $40, $00,   // 15   sub     ecx, 00401014    $89, $A1, $03, $10, $40, $00,   // 1B   mov     [ecx+401003], esp    $89, $81, $07, $10, $40, $00,   // 21   mov     [ecx+401007], eax    $8D, $89, $43, $10, $40, $00,   // 27   lea     ecx, [ecx+401043]    $51,                            // 2D   push    ecx    $90,                            // 2E   nop    $90,                            // 2F   nop    $90,                            // 30   nop    $90,                            // 31   nop    $90,                            // 32   nop    $90,                            // 33   nop    $90,                            // 34   nop    $90,                            // 35   nop    $90,                            // 36   nop    $90,                            // 37   nop    $90,                            // 38   nop    $90,                            // 39   nop    $90,                            // 3A   nop    $90,                            // 3B   nop    $90,                            // 3C   nop    $90,                            // 3D   nop    $E9, $57, $01, $00, $00,        // 3E   jmp     0040119A    $8B, $5C, $24, $FC,             // 43   mov     ebx, [esp-4]    $E8, $00, $00, $00, $00,        // 47   call    0040104C    $59,                            // 4C   pop     ecx    $89, $5C, $24, $FC,             // 4D   mov     [esp-4], ebx    $81, $E9, $4C, $10, $40, $00,   // 51   sub     ecx, 0040104C    $89, $81, $0B, $10, $40, $00,   // 57   mov     [ecx+40100B], eax    $8B, $A1, $03, $10, $40, $00,   // 5D   mov     esp, [ecx+401003]    $E8, $32, $01, $00, $00,        // 63   call    0040119A    $E8, $00, $00, $00, $00,        // 68   call    0040106D    $59,                            // 6D   pop     ecx    $81, $E9, $6D, $10, $40, $00,   // 6E   sub     ecx, 0040106D    $8B, $81, $07, $10, $40, $00,   // 74   mov     eax, [ecx+401007]    $50,                            // 7A   push    eax    $8B, $81, $0B, $10, $40, $00,   // 7B   mov     eax, [ecx+40100B]    $C3                             // 81   retn  );function GetOpCodeSize(Start: Pointer; Tlb: TMaskTable): integer;var  pOPCode: PBytes;  t, c: LongWord;  dh, dl, al: byte;begin  result := -1;  t := 0;  pOPCode := Start;  repeat    t := t and $F7;    c := pOPCode^;    pOpCode := Pointer((DWORD(pOpCode) + 1));    t := t or Tlb[c];  until ((t and $000000FF) and 8) = 0;  if (c = $0F6) or (c = $0F7) then  begin    t := t or $00004000;    if (pOpCode^ and $38) = 0 then      t := t or $00008000;  end  else if (c = $0CD) then  begin    t := t or $00000100;    if pOpCode^ = $20 then      t := t or $00000400;  end  else if (c = $0F) then  begin    al := pOpCode^;    pOpCode := Pointer((DWORD(pOpCode) + 1));    t := t or Tlb[al + $100];    if t = $FFFFFFFF then      Exit;  end;  if (((t and $0000FF00) shr 8) and $80) <> 0 then  begin    dh := (t and $0000FF00) shr 8;    dh := dh xor $20;    if (c and 1) = 0 then      dh := dh xor $21;    t := t and $FFFF00FF;    t := t or (dh shl 8);  end;  if (((t and $0000FF00) shr 8) and $40) <> 0 then  begin    al := pOpCode^;    pOpCode := Pointer((DWORD(pOpCode) + 1));    c := al;    c := c or (al shl 8);    c := c and $C007;    if (c and $0000FF00) <> $C000 then    begin      if ((t and $000000FF) and $10) = 0 then      begin        if (c and $000000FF) = 4 then        begin          al := pOpCode^;          pOpCode := Pointer((DWORD(pOpCode) + 1));          al := al and 7;          c := c and $0000FF00;          c := c or al;        end;        if (c and $0000FF00) <> $4000 then        begin          if (c and $0000FF00) = $8000 then          begin            t := t or 4;          end          else if c = 5 then            t := t or 4;        end        else        begin          t := t or 1;        end;      end      else      begin        if (c <> 6) then        begin          if (c and $0000FF00) = $4000 then            t := t or 1          else if (c and $0000FF00) = $8000 then            t := t or 2;        end        else          t := t or 2;      end;    end;  end;    if (((t and $000000FF)) and $20) <> 0 then  begin    dl := (t and $000000FF);    dl := dl xor 2;    t := t and $FFFFFF00;    t := t or dl;    if (dl and $10) = 0 then    begin      dl := dl xor 6;      t := t and $FFFFFF00;      t := t or dl;    end;  end;  if (((t and $0000FF00) shr 8) and $20) <> 0 then  begin    dh := (t and $0000FF00) shr 8;    dh := dh xor 2;    t := t and $FFFF00FF;    t := t or (dh shl 8);    if (dh and $10) = 0 then    begin      dh := dh xor 6;      t := t and $FFFFFF00;      t := t or dh;    end;  end;  result := DWORD(pOPCode) - DWORD(Start);  t := t and $707;  result := result + (t and $000000FF);         //1条指令不可能大过255个字节  result := result + ((t and $0000FF00) shr 8);end;function HookCode(const DllName: string; const ApiName: string;  HookProc: Pointer): Boolean;beginend;function SetOnBefore(const DllName: string; const ApiName: string;  HookProc: Pointer): Boolean;var  ApiEntry: Pointer;  DllHandle: THandle;  ReplaceCodeSize: Integer;  OpCode: array [0..15] of byte;  StubPtr: Pointer;  Addr: LongWord;  RetSize: LongWord;  begin  Result := False;  DllHandle := GetModuleHandle(PChar(DllName));  if DllHandle = 0 then  begin    DllHandle := LoadLibrary(PChar(DllName));    if DllHandle = 0 then Exit;  end;  ApiEntry := GetProcAddress(DllHandle, PChar(ApiName));  if ApiEntry = nil then Exit;  ReplaceCodeSize := GetOpCodeSize(ApiEntry, MaskTable);  while ReplaceCodeSize < 5 do  begin    ReplaceCodeSize := ReplaceCodeSize +      GetOpCodeSize(Pointer(LongWord(ApiEntry) + ReplaceCodeSize), MaskTable);  end;  if ReplaceCodeSize > 16 then Exit;  if VirtualProtect(ApiEntry, ReplaceCodeSize, PAGE_READWRITE, nil) then    Exit;  CopyMemory(@OpCode, ApiEntry, ReplaceCodeSize);  StubPtr := VirtualAlloc(nil, SizeOf(BeforeStub), MEM_COMMIT, PAGE_EXECUTE_READWRITE);  if StubPtr = nil then Exit;  CopyMemory(StubPtr, @BeforeStub, SizeOf(BeforeStub));  // 求HookProc的地址    Addr := LongWord(HookProc) - LongWord(StubPtr) - 35 - 5;  // 写入HookProc的地址  PDWORD(LongWord(StubPtr) + 36)^ := Addr;  // 求HookedApi的地址    Addr := LongWord(ApiEntry) + ReplaceCodeSize - LongWord(StubPtr) - 89 - 5;  // 写入HookedApi的地址  PDWORD(LongWord(StubPtr) + 90)^ := Addr;  // 写入被Hook掉的OpCode  CopyMemory(Pointer(LongWord(StubPtr) + 73), @OpCode, ReplaceCodeSize);  // 改写Api入口地址  Addr := LongWord(StubPtr) - LongWord(ApiEntry) - 5;  PDWORD(LongWord(@JMPGate) + 1)^ := Addr;  WriteProcessMemory(GetCurrentProcess, ApiEntry, @JMPGate, SizeOf(JMPGate), RetSize);//  CopyMemory(ApiEntry, @JMPGate, SizeOf(JMPGate));  Result := True;end;function SetOnAfter(const DllName: string; const ApiName: string;  HookProc: Pointer): Boolean;var  ApiEntry: Pointer;  DllHandle: THandle;  ReplaceCodeSize: Integer;  OpCode: array [0..15] of byte;  StubPtr: Pointer;  Addr: LongWord;  RetSize: LongWord;  begin  Result := False;  DllHandle := GetModuleHandle(PChar(DllName));  if DllHandle = 0 then  begin    DllHandle := LoadLibrary(PChar(DllName));    if DllHandle = 0 then Exit;  end;  ApiEntry := GetProcAddress(DllHandle, PChar(ApiName));  if ApiEntry = nil then Exit;  ReplaceCodeSize := GetOpCodeSize(ApiEntry, MaskTable);  while ReplaceCodeSize < 5 do  begin    ReplaceCodeSize := ReplaceCodeSize +      GetOpCodeSize(Pointer(LongWord(ApiEntry) + ReplaceCodeSize), MaskTable);  end;  if ReplaceCodeSize > 16 then Exit;  if VirtualProtect(ApiEntry, ReplaceCodeSize, PAGE_READWRITE, nil) then    Exit;  CopyMemory(@OpCode, ApiEntry, ReplaceCodeSize);  StubPtr := VirtualAlloc(nil, SizeOf(AfterStub), MEM_COMMIT, PAGE_EXECUTE_READWRITE);  if StubPtr = nil then Exit;  CopyMemory(StubPtr, @AfterStub, SizeOf(AfterStub));  // 求HookProc的地址    Addr := LongWord(HookProc) - LongWord(StubPtr) - $63 - 5;  // 写入HookProc的地址  PDWORD(LongWord(StubPtr) + $64)^ := Addr;  // 求HookedApi的地址    Addr := LongWord(ApiEntry) + ReplaceCodeSize - LongWord(StubPtr) - $3E - 5;  // 写入HookedApi的地址  PDWORD(LongWord(StubPtr) + $3F)^ := Addr;  // 写入被Hook掉的OpCode  CopyMemory(Pointer(LongWord(StubPtr) + $2E), @OpCode, ReplaceCodeSize);  // 改写Api入口地址  Addr := LongWord(StubPtr) - LongWord(ApiEntry) - 5;  PDWORD(LongWord(@JMPGate) + 1)^ := Addr;  WriteProcessMemory(GetCurrentProcess, ApiEntry, @JMPGate, SizeOf(JMPGate), RetSize);//  CopyMemory(ApiEntry, @JMPGate, SizeOf(JMPGate));  Result := True;end;end.

转载地址:http://gesti.baihongyu.com/

你可能感兴趣的文章
【web素材】02-10款大气的购物商城网站模板
查看>>
49个在工作中常用且容易遗忘的CSS样式清单整理
查看>>
20种在学习编程的同时也可以在线赚钱的方法
查看>>
隐藏搜索框:CSS 动画正反向序列
查看>>
127个超级实用的JavaScript 代码片段,你千万要收藏好(上)
查看>>
【视频教程】Javascript ES6 教程27—ES6 构建一个Promise
查看>>
【5分钟代码练习】01—导航栏鼠标悬停效果的实现
查看>>
127个超级实用的JavaScript 代码片段,你千万要收藏好(中)
查看>>
127个超级实用的JavaScript 代码片段,你千万要收藏好(下)
查看>>
【web素材】03-24款后台管理系统网站模板
查看>>
Flex 布局教程:语法篇
查看>>
年薪50万+的90后程序员都经历了什么?
查看>>
2019年哪些外快收入可达到2万以上?
查看>>
【JavaScript 教程】标准库—Date 对象
查看>>
前阿里手淘前端负责人@winter:前端人如何保持竞争力?
查看>>
【JavaScript 教程】面向对象编程——实例对象与 new 命令
查看>>
我在网易做了6年前端,想给求职者4条建议
查看>>
SQL1015N The database is in an inconsistent state. SQLSTATE=55025
查看>>
RQP-DEF-0177
查看>>
MySQL字段类型的选择与MySQL的查询效率
查看>>