delphi apihook

原创 2004年07月30日 12:38:00
关于API HOOK,我相信大家比我知道的多,大家应该记得在DOS中编程,经常都要用截取中断向量的技术,这样我们可以设置新的中断服务程序,因此当一个新的程序调用这个中断向量的时候,它就会先调用我们自己设置的中断程序,然后调用原来的中断程序,这样我们就能够非凡的控制权,许多的病毒程序都是这样的。在WINDOWS中,也可以采用类似的技术,当系统调用某个API函数时,就会先进入我们设置的函数,其工作原理和DOS的中断差不多,这种技术也有很多的名称,像"陷阱技术","重入技术"。可我认为API HOOK好一些吧!这些技术再很多的软件中也有应用的,像"金山词霸"就是的了。呵呵~~~不是故意拿金山公司的产品说的啊!这个软件就运用了这个技术,像当你把鼠标指向一个单词,这时就会弹出一个窗口翻译单词了。这也就是用了钩子的原理。说了这么多废话,说正题了,要使自己的代码正确运行,函数必须和要改写的API函数有相同形式的参数。我在程序中,拦截了MessageBoxA和MessageBoxW这两个函数。如:
fuction MyBoxA(hwn:hwnd;Iptext:pcter;Ipcapion:pchar;utype:cardinal):interger;stdcall;
fuction MyBoxW(hwn:hwnd;Iptext:pchter;Ipcapiom:pchar;utype:cardinal):interger;stdcall;
这里我使用了stdcall关键字,这个我上面已经说了,函数的形参的进出栈顺序要和拦截的函数一样,在WIN32中并不允许直接修改内存中的代码,但可以调用一个函数来运用:WriteProcessMemory。当然有的人问这个不能改写,可我用着很好!也许用它会有些bug,可我不知道,知道的人请给我来信。
在PE文件中,当你呼叫另一模块中的函数列如:USER32.DLL中的GetMessage),编译出来的CALL指令并不会吧控制权直接传给DLL里的函数,而是传给了JMP DWORD PTR [XXXXXXXXX]指令,[XXXXXXXXXX]里有该函数的真正地址(进入点),要得到API函数,可以这样写:Address:=@MessageBoxA。像上面说的那样,这里只得到了一个跳转的指令,后面的MessageBoxA才是代码开始的地方。下面的程序我自己定义了一个结构(使用了packed关键字)
TlmportCode =packed record
    Jumplnstruction: Word; //是$25FF,JUMP指令
AddressOfPointer ToFunction: PPointer;//真正开始的地址
end;
PlmportCode = ^TlportCode;
这里,Ppointer =^pointer ;用下面函数返回函数的真正地址:
function TrueFunctionAddress(func: Pointer): Pointer;
var
  Code: PlmportCode;
Begin
  Result:= func;
  if func = nil then exit;
  try
   Code := func;
   if (Code.jumplnstruction = $25FF) then begin
     Result := Code.AddressOfPointer ToFunction^;
   end;
   except
     Result :=nil;
  end;
end;
这样,只要用自己的函数的地址代替它就可以了。替换函数:
Procedure PermuteFunction(OldFunc:Ppointer; NewFunc:Poiner);
var
  written: DWORD;
begin
  WriteProcessMemory(GetCurrentProcess,OldFunc,@NewFunc,4,written);
end;
新建一个API HOOK,把上面的保存就可以了。
新建一个Application Try1,主FORM的单元名称就用TRYUNIT1。把上面的HOOK加进来,再新建一个UNIT MESS,添加下面的代码:
unit mess

interface
uses
   Windows,Message,SysUtils,Classes,APIHook;

procedure API_Hookup;
procedure Un_API_Hook;

var
   FuncMessageboxA,FuncMessagew;PlmportCode;

implementation

type
   TmessageA = function(hwn: hwnd; Iptext: pchar; Ipcapion:pchar; utype: cardinal): interger;stdcall;
   TmessageW = function(hwn: hwnd; Iptext: pchar; Ipcapion:pchar; utype: cardinal): interger;stdcall;

var
   OldMessageBoxA: TmessageA;
   OldMessageBoxW: TmessageW;


functionj MyBoxA (hwn: hwnd; Iptext: pchar; Ipcapion:pchar; utype: cardinal): interger;stdcall;
begin
result :=OldMessageBoxA(hwn,'Succes Hook A!', Ipcapion,utype);
end;

functionj MyBoxW (hwn: hwnd; Iptext: pchar; Ipcapion:pchar; utype: cardinal): interger;stdcall;
result :=OldMessageBoxW(hwn,'成功挂上W!'Ipcapion,utype);
end;

procedure API_Hookup;
begin
   if @OldMessageBoxA = nil then
@OleMessageBoxA = TrueFunctionAddress(@messageboxA);
   if @OldMessageBoxW = nil then
@OleMessageBoxW = TrueFunctionAddress(@messageboxW);

PermuteFunction(FuncMessageboxA,AddressOfPointerToFunction,@MyBoxA);
PermuteFunction(FuncMessageboxW,AddressOfPointerToFunction,@MyBoxW);
end;

procedure Un_API_Hook;
begin
  if @OldMessageBoxA <> nil then begin
         PermuteFunction(FuncMessageboxA,AddressOfPointer ToFunction,@OldMessageboxA);
         PermuteFunction(FuncMessageboxW,AddressOfPointer ToFunction,@OldMessageboxW);
  end;
end;

initialization
   FundMessageboxA := @MeesageboxA;
   FundMessageboxW := @MeesageboxW;
end;
在主窗体中添加三按钮,添加Onclick事件的代码,如下:
procedure TForm1.Button1Click( Sender: TObject);
begin
   API_Hook;
end;

procedure TForm1.Button3Click( Sender: TObject);
   Un_API_Hook;
end;

procedure TForm1.Button2Click( Sender: TObject);
begin
  MessageBoxA(Form1.Handle,'NO HOOK UP A','MessageBoxA',MB_OK);
  MessageBoxW(Form1.Handle,'NO HOOK UP W','MessageBoxW',MB_OK);
  MessageBox (Form1.Handle,'NO HOOK UP BOX','MessageBox',MB_OK);
end;
先运行TRY1,再运行TestTry。看看结果,APIHook仅仅再TRY1中挂上了,并没有在所以的系统进程中挂上,这个时想想鼠标钩子的时候做法,用SetWindowsHookEx挂上鼠标钩子,当其它的进程发出鼠标消息的时候,我们的程序就会拦截到并做出响应,还可以用UpHooklWindowsHookEx解除鼠标钩子,这样,我们就知道了,应该为我们的函数挂上钩子,当然你要知道鼠标钩子有各种的消息响应其它进程。有两种方法,一种是模仿SetWindowsHookEx,编制自己的MySetWindowsHookEx。还有一种也是WINDOWS所提供的另一个函数:GetMsgProc。这个函数在DELPHI帮助里说的很清楚得了。我们的目的也就是在动态链接库中挂上WH_GETMESSAGE消息钩子。当其它进程发出这个函数的时候,就会加载我们的动态链接库,如果我们的DLL加载时自动运行API_Hook,就可以让其它进程挂上我们的API Hook了。
第二个程序我会在下次写出来。

又是一个APIHOOK

又是一个APIHOOK 借用了海风月影的HookApi 0.5的一些思路;又是一个APIHOOK,没什么特别的!能顺利完成任务,没有什么多余的!代码里用到了libdasm,去下载一个吧!Ho...
  • linuxheik
  • linuxheik
  • 2015年10月19日 21:42
  • 242

HOOK API入门之Hook自己程序的MessageBoxW

说到HOOK,我看了很多的资料和教程,无奈就是学不会HOOK,不懂是我的理解能力差,还是你们说的 不够明白,直到我看了以下这篇文章,终于学会了HOOK: http://blog.sina.com.cn...
  • friendan
  • friendan
  • 2013年10月01日 20:12
  • 33800

Delphi 的消息机制

=============================================================================== ⊙ 一个 GUI Applicatio...
  • zang141588761
  • zang141588761
  • 2016年09月05日 15:36
  • 1279

Delphi 集合 使用资料收集

集合的使用      (一)       delphi中的集合是对数学中集合的概念的简单实现。要求是集合中的元素必须同类型,且必须是序数类型,且集合中可能的元素个数不能大于255。     定义: t...
  • ainixiaozhuzi
  • ainixiaozhuzi
  • 2013年10月20日 10:12
  • 1111

Delphi xe7并行编程快速入门

现在多数设备、计算机都有多个CPU单元,即使是手机也是多核的。但要在开发中使用多核的优势,却需要一些技巧,花费时间编写额外的代码。好了,现在可以使用Delphi做并行编程了。在Delphi、C++ B...
  • henreash
  • henreash
  • 2014年11月20日 16:19
  • 6858

Delphi中Chrome Chromium、Cef3学习笔记(一)

官方下载地址:https://cefbuilds.com/ CEF简介:     嵌入式Chromium框架(简称CEF) 是一个由Marshall Greenblatt在20...
  • xtfnpgy
  • xtfnpgy
  • 2015年06月25日 13:25
  • 4892

Delphi 的绘图功能

//TPen 的主要属性有四: Color、Width、Style、Mode              {Color: 颜色}              {Width: 宽度; 默认是 1; ...
  • gzxiaorou
  • gzxiaorou
  • 2015年03月22日 15:34
  • 482

Delphi url 编码及转码及特殊字符串替换--百度和腾讯用的就是这个

先介绍一下,Delphi中处理Google的URL编码解码,其中就会明白URL编码转换的方法的 从delphi的角度看Google(谷歌)URL编码解码方式 在网上搜索了一下,似乎没有什么关于goo...
  • Syndicator
  • Syndicator
  • 2014年01月03日 11:59
  • 1953

Delphi 文件处理(4)

9.3.1 文件类型 1.文件类型概念 Delphi使用文件类型来读写存储在外部存储介质上的文件。一个文件变量能够与任意种类的外部设备建立通信,包括磁盘、打印机、键盘、绘图仪、调制解调器等。 ...
  • lailai186
  • lailai186
  • 2013年04月10日 10:01
  • 4848

Delphi实现通用的定时自动关机程序

一、问题的提出:运行某任务的计算机,尤其是服务器,如果能实现在无人职守的情况下,到达指定时间时自动关机,那么将极大地减轻系统管理员的负担,也会给我们的日常工作带来很大方便。    笔者用Delp...
  • my98800
  • my98800
  • 2016年08月29日 09:12
  • 1011
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:delphi apihook
举报原因:
原因补充:

(最多只允许输入30个字)