API HOOK关键技术解析
APIHOOK的实现原理
APIHOOK的实现原理API Hooking(API挂钩)是一种常见的软件技术,用于修改或者扩展应用程序的行为,它通过“操纵”应用程序的API调用过程来实现这一目标。
API Hooking通常用于各种目的,例如:监视应用程序的行为、修复漏洞、收集数据等。
本文将介绍API Hook的实现原理及其相关概念。
1. API Hook概述API Hooking通过劫持和修改应用程序对动态链接库(DLL)中导出函数的调用来实现目标功能。
在Windows操作系统中,每个可执行文件都会使用一些API函数,这些函数由系统提供并存储在动态链接库中。
当应用程序调用这些函数时,操作系统会在库文件中查找并执行相应的函数代码。
API Hooking就是在应用程序和DLL之间插入一个中间层,通过改变函数调用的目标,来控制和改变应用程序的行为。
API Hooking的实现原理可以归纳为以下几个步骤:(1)定位目标函数:首先,需要确定要Hook的目标函数。
可以通过静态分析程序源代码、反汇编可执行文件、监视应用程序行为等方法来获取目标函数的地址或名称。
(2)获取目标函数的原始地址:通过动态链接库(DLL)中的导入表,可以获取到目标函数的原始地址。
导入表中保存了DLL中导出函数地址的引用。
(3)Hook目标函数:Hook目标函数的方式有多种,这里介绍两种常见的方式。
a. 钩子函数(Hook Function):通过将Hook函数替换为目标函数的调用,可以劫持目标函数的执行。
Hook函数在执行之前、中间或者之后可以执行额外的逻辑操作,并返回结果给应用程序。
b. IAT Hooking(Import Address Table Hooking):IAT是动态链接库中的导入表,包含了动态链接库中导出函数的地址。
通过修改IAT中目标函数的地址,将其指向Hook函数,即可实现Hook效果。
(4)重定向函数调用:Hook目标函数后,需要将应用程序中对目标函数的调用重定向到Hook函数。
跨进程API Hook
跨进程API Hook(初稿)detrox什么是“跨进程API Hook”?众所周知Windows应用程序的各种系统功能是通过调用API函数来实现。
API Hook就是给系统的API附加上一段小程序,它能监视甚至控制应用程序对API函数的调用。
所谓跨进程也就是让自己的程序来控制别人程序的API调用了。
API Hook 理论通过对Win32 PE文件的分析(如果你还不熟悉PE文件格式,可以看看Iczelion的PE教程或者LUEVELSMEYER的<<The PE File Format>>)。
我们知道在PE文件中的IMPORT TABLE内存储着API函数的很多信息。
其中包括API的函数名,调用地址等等。
而操作系统在执行PE文件时会先将其映射到内存中。
在映射的同时还会把当前版本操作系统中API函数的入口地址写入IMPORT TABLE中一组与API调用相关的结构体内,用于该应用程序的API调用。
当应用程序调用API时,他会在自己内存映像里寻找API的入口地址,然后执行CALL指令。
如此一来,我们通过修改应用程序内存映像的IMPORT TABLE中API函数的入口地址,就可以达到重定向API 的目的。
将API地址改为我们自己函数的地址,这样我们的函数就可以完成对API的监视和控制了。
API Hook 的实现/* 1 */HANDLE hCurrent = GetModuleHandle(NULL);/* 2 */IMAGE_DOS_HEADER *pidh;/* 3 */IMAGE_NT_HEADERS *pinh;/* 4 */IMAGE_DATA_DIRECTORY *pSymbolTable;/* 5 */IMAGE_IMPORT_DESCRIPTOR *piid;/* 6 */pidh = (IMAGE_DOS_HEADER *)hCurrent;/* 7 */pinh = (IMAGE_NT_HEADERS *)((DWORD)hCurrent + pidh->e_lfanew); /* 8 */pSymbolTable = &pinh->OptionalHeader.DataDirectory[1];/* 9 */piid =(IMAGE_IMPORT_DESCRIPTOR *)((DWORD)hCurrent + pSymbolTable->VirtualAddress);/*10 */do {/*11 */ IMAGE_THUNK_DATA *pitd,*pitd2;/*12 */ pitd = (IMAGE_THUNK_DATA *)((DWORD)hCurrent +piid->OriginalFirstThunk);/*13 */ pitd2 = (IMAGE_THUNK_DATA *)((DWORD)hCurrent +piid->FirstThunk);/*14 */ do {/*15 */ IMAGE_IMPORT_BY_NAME *piibn;/*16 */ piibn = (IMAGE_IMPORT_BY_NAME *)((DWORD)hCurrent + *((DWORD *)pitd));/*17 */ PROC *ppfn = (PROC *)(pitd2->u1.Function);/*18 */ if (!strcmp("MessageBoxW",(char *)piibn->Name)) {/*19 */ oldMsg = (MsgBoxType)(ppfn);/*20 */ DWORD addr = (DWORD)MyMessage;/*21 */ DWORD written = 0;/* 改变内存读写状态 *//*22 */ DWORD oldAccess;/*23 */VirtualProtect(&pitd2->u1.Function,sizeof(DWORD),PAGE_WRITECOPY,&oldA ccess);/*24 */ APIAddress = (DWORD)&pitd2->u1.Function;/* 向内存映像写入数据 *//*25 */WriteProcessMemory(GetCurrentProcess(),&pitd2->u1.Function,&addr,sizeof(DWORD), &written);/*26 */ }/*27 */ pitd++;pitd2++;/*28 */ } while (pitd->u1.Function);/*29 */ piid++;/*30 */} while (piid->FirstThunk + piid->Characteristics+ piid->ForwarderChain + piid->Name + piid->TimeDateStamp);寻觅IMPORT TALBE在/*1*/中我们使用GetModuleHandle(NULL)来返回当前进程在内存中映像的基地址。
API_HOOK讲解1
第6章APIHOOKAPIHOOK始终是系统程序员关心的热门话题。
通过APIHOOK,可以对Win32API函数进行拦截,从而改变函数乃至程序的固有行为。
通过APIHOOK拦截可以解决十分棘手的难题。
本章主要介绍Win32API拦截、驱动程序服务函数的拦截、BrowserHelpObject实现、SPI接口的应用,并利用Detours库实现对DLL的绑定。
6.1 APIHOOK综述APIHOOK尽管能够提供非常强大的功能,但是遗憾的是,无论是DDK还是SDK都没有提供这方面的任何文档和例子。
使用APIHOOK前,用户首先应该弄清楚,究竟是拦截一个应用程序还是系统范围内的拦截。
系统的拦截往往需要实现对创建的新的进程进行监视。
对系统底层服务进行拦截,能够打破进程边界。
最简单的实现拦截的方法是实现一个代理的动态链接库。
这个动态链接库实现了目标拦截动态链接库的全部输出函数,但是它只是一个函数转发器,其函数功能还是通过间接地调用原来的目标动态链接库函数实现。
当程序或者系统调用目标动态链接库的时候,真正调用的是代理动态链接库。
代理动态链接库的输出函数会首先检查调用函数的入口参数,决定直接返回一个值,还是调用原来的函数。
可以把这个函数的返回结果作为返回值返回,也可以对调用结果进行二次处理。
由于这种方法需要对所有的函数进行处理,这个过程十分繁琐,而且并非所有的函数都提供了足够的文档,因此这种方法在某些情况下几乎是无法实现的。
这方面应用的例子有关于WinInet实现的程序,发表在1994年12月份的MSJ杂志上,网址是/MSJ/0997/hood0997.htm。
对API函数的拦截不外乎两种方式,要么在磁盘文件上实现,要么在内存中实现。
前者拦截在可执行程序加载以前,后者则是在程序加载之后。
两种方法基本上都是通过打补丁的方法实现的。
如果用户以前曾经研究过APIHOOK,也许听说过导入地址表补丁的概念。
它的很多优点使得这种WindowsAPIHOOK的方法成为最体面、最常见的方法之一。
hook技术原理
Hook技术是一种用于拦截API函数调用的技术,它通过修改系统API函数的内存地址,从而拦截系统函数的调用,实现对系统API函数的拦截和修改。
Hook技术的基本原理是将系统API函数的内存地址指向一个用户定义的函数,而不是指向实际的API函数。
当调用系统API函数时,系统将调用用户定义的函数,而不是原来的函数。
这样就可以实现对系统API函数的拦截和修改。
Hook技术的实现步骤如下:
1、首先,程序员需要查找和定位需要拦截的API函数的内存地址。
2、然后,程序员需要编写用户定义的函数,用来拦截和修改系统API函数的调用。
3、接着,程序员需要将系统API函数的内存地址指向用户定义的函数,从而实现API函数的拦截。
4、最后,程序员需要将系统API函数的原始内存地址保存起来,以便在不再需要拦截时,可以恢复原来的API函数调用行为。
Hook技术是一种强大的技术,可以用来实现各种功能,比如拦截软件的调用,拦截软件的输入输出,拦截系统函数的调用等。
Hook技术也可以用来实现防病毒,反垃圾邮件,防恶意程序,实现软件保护以及实现自定义控件等功能。
hook api
实现HOOK API两种方法
改引入表式 陷阱式
用改引入表式方法来实现,这种方法易 于实现,但要求你熟悉PE文件结构。主 要是定位到Kernel32.dll模块的 OpenProcess函数地址,并用 WriteProcessMemory函数改写函数地址。
进程的定义
通常被定义为一个正在运行的程序的实 例,是一个程序在其自身的地址空间中 的一次执行活动。 的一次执行活动。
Hook的应用模式 的应用模式
观察模式 最为常用,像Windows提供的SetWindowHook 就是典型地为这类应用准备的。而且这也是最 普遍的用法。 这个模式的特点是,在事情发生 的时候,发出一个通知信息。观察者只可以查 看过程中的信息,根据自己关心的内容处理自 己的业务,但是不可以更改原来的流程。 如全 局钩子中,经常使用的鼠标消息、键盘消息的 监视等应用。金山词霸屏幕取词的功能是一个 典型的应用
HOOKAPI的原则
被HOOK的API的原有功能不能受到任何 影响。就像医生救人,如果把病人身体里 的病毒杀死了,病人也死了,那么这个 “救人”就没有任何意义了。如果你 HOOK API之后,你的目的达到了,但 API的原有功能失效了,这样不是HOOK, 而是REPLACE,操作系统的正常功能就 会受到影响,甚至会崩溃。
HOOK API
Hook API是一种拦截应用程序API函 数调用的通用机制,通过建立API Hook 可以监视和改变应用程序的行为。 HookAPI 技术常用于屏幕取词、网络防 火墙、病毒木马等领域。
Hook就是钩子的意思,而API是指 Windows开放给程序员的编程接口,使 得在用户级别下可以对操作系统进行控 制,也就是一般的应用程序都需要调用 API来完成某些功能,Hook API就是在这 些应用程序调用真正的系统API前可以先 被截获,从而进行一些处理再调用真正 的API来完成功能。
API HOOK 简介
Hook这个东西有时令人又爱又怕,Hook是用来拦截系统某些讯息之用,例如说,我们想让系统不管在什麽地方只要按个Ctl-B便执行NotePad,或许您会使用Form的KeyPreview,设定为True,但在其他Process中按Ctl-B呢?那就没有用,这是就得设一个Keyboard Hook来拦截所有Key in的键;再如:MouseMove的Event只在该Form或Control上有效,如果希望在Form的外面也能得知MouseMove的讯息,那只好使用MouseHook来栏截Mouse的讯息。
再如:您想记录方才使用者的所有键盘动作或Mosue动作,以便录巨集,那就使用JournalRecordHook,如果想停止所有Mosue键盘的动作,而放(执行)巨集,那就使用JournalPlayBackHook;Hook呢,可以是整个系统为范围(RemoteHook),即其他Process的动作您也可以拦截,也可以是LocalHook,它的拦截范围只有Process本身。
Remote Hook的HookFunction要在.Dll之中,Local Hook则在.Bas中。
在VB如何设定Hook呢?使用SetWindowsHookEx()Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _ (ByVal idHook As Long, _ByVal lpfn As Long, _ByVal hmod As Long, _ByVal dwThreadId As Long) As LongidHook代表是何种Hook,有以下几种Public Const WH_CALLWNDPROC = 4Public Const WH_CALLWNDPROCRET = 12Public Const WH_CBT = 5Public Const WH_DEBUG = 9Public Const WH_FOREGROUNDIDLE = 11Public Const WH_GETMESSAGE = 3Public Const WH_HARDWARE = 8Public Const WH_JOURNALPLAYBACK = 1Public Const WH_JOURNALRECORD = 0Public Const WH_KEYBOARD = 2Public Const WH_MOUSE = 7Public Const WH_MSGFILTER = (-1)Public Const WH_SHELL = 10Public Const WH_SYSMSGFILTER = 6lpfn代表Hook Function所在的Address,这是一个CallBackFucnction,当挂上某个Hook时,我们便得定义一个Function来当作某个讯息产生时,来处理它的Function,这个HookFunction有一定的叁数格式Private Function HookFunc(ByVal nCode As Long, _ByVal wParam As Long, _ByVal lParam As Long ) As LongnCode 代表是什麽请况之下所产生的Hook,随Hook的不同而有不同组的可能值。
陷阱式APIHook的原理及其在截取串口数据中的应用
2024/9/29
8
NewCreateFile(文件名){ 还原CreateFile; Handle = CreateFile(文件名); 修改CreateFile; if(文件名==“COM2”) 保存Handle到共享内存变量ComHandle中
}
2024/9/29
9
NewWriteFile(文件句柄,数据){ if(文件句柄=ComHandle) 修改“数据”
GetMsgProc(){ }
2
目的进程载入 DLPSLIB.dll
(寄生程序)
同步修改ReadFile跳
转到NewReadFile
NewReadFile(){ }
2024/9/29
DLPSLIB.dll
目的进程载入dll时, dll就已经成为其一
部分了
SetDIPSHook{ SetWindowsHookEx(…)
2024/9/29
6
……
调用 Call ReadFile
1
……
4
自定义函数
NewReadFile(){ 还原ReadFile 调用ReadFile 修改ReadFile
ret
}
被劫持函数 ReadFile(){
……
2
ret
3
}
2024/9/29
……
调用 Call ReadFile
1
……
9
自定义函数 NewReadFile(){
1
……
9
自定义函数 NewReadFile(){
call ShadowReadFile(); 3
}
8
ShadowyReadFile(){
影子函数
扫盲之ApiHook细析
扫盲之ApiHook细析扫盲之Api Hook 细析2010-05-29 11:33转载自分享最终编辑 likefxlHook是什么?钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。
当消息到达后,在目标窗口处理函数之前处理它。
钩子机制允许应用程序截获处理window消息或特定事件。
钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。
每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。
这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。
Hook原理每个Hook都有一个关联的链表,由系统维护,链表指针指向被Hook子程调用的回调函数:LRESULT WINAPI HookCallBack(int nCode,WPARAM wParam,LPARAM lParam);nCode 事件代码wParam 消息的类型lParam 包含的消息当被Hook的类型关联的消息发生时,系统会把这个消息传递到链表指针指向的Hook子程,由子程内部对消息进行处理,。
钩子安装与卸载使用Windows提供的API SetWindowsHookEx来将Hook子程指针安装到Hook链表,安装的Hook子程始终在Hook链表头部。
HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId);idHook 安装的钩子类型lpfn 子程函数指针hMod 应用程序实例的句柄dwThreadId Hook关联的线程标识符当被Hook的消息类型发生时,系统会调用与这个Hook关联的链表头的Hook子程。
由子程序决定是否要把这个事件传递给下个子程。
源程序程序破解之 API HOOK技术
gCallCounter ++;
}
#endif
return ret;
}
2)使用刚才提到的方法进行DLL导入
string hexData1 = toHexString((const char *)pbData, strlen((const char *)pbData));
int ret = sub_4026B0(pbData);
string hexData2 = toHexString((const char *)pbData, strlen((const char *)pbData));
gHooks.Add(_T("KERNEL32.DLL"), "DeviceIoControl", my_DeviceIoControl);
static int gCallCounter = 0;
BOOL WINAPI my_DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize,
// 指定DLL的某个函数进行HOOK
HANDLE Add(LPCTSTR lpszModule, LPCSTR lpcFuncName, void *pNewAddr, DWORD dwData = 0);
// 给定一个函数地址进行HOOK
Windows中Hook API技术
Windows下Hook API技术 inline hook分类: WINDOWS什么叫Hook API?所谓Hook就是钩子的意思,而API是指 Windows开放给程序员的编程接口,使得在用户级别下可以对操作系统进行控制,也就是一般的应用程序都需要调用API来完成某些功能, Hook API的意思就是在这些应用程序调用真正的系统API前可以先被截获,从而进行一些处理再调用真正的API来完成功能。
在讲Hook API之前先来看一下如何Hook消息,例如Hook全局键盘消息,从而可以知道用户按了哪些键,这种Hook消息的功能可以由以下函数来完成,该函数将一个新的 Hook加入到原来的Hook链中,当某一消息到达后会依次经过它的Hook链再交给应用程序。
HHOOK SetWindowsHookEx(int idHook, //Hook类型,例如WH_KEYBOARD,WH_MOUSEHOOKPROC lpfn, //Hook处理过程函数的地址HINSTANCE hMod, //包含Hook处理过程函数的dll句柄(若在本进程可以为NULL)DWORD dwThreadId, //要Hook的线程ID,若为0,表示全局Hook所有);这里需要提一下的就是如果是Hook全局的而不是某个特定的进程则需要将Hook过程编写为一个DLL,以便让任何程序都可以加载它来获取Hook过程函数。
而对于Hook API微软并没有提供直接的接口函数,也许它并不想让我们这样做,不过有2种方法可以完成该功能。
第一种,修改可执行文件的IAT表(即输入表),因为在该表中记录了所有调用API的函数地址,则只需将这些地址改为自己函数的地址即可,但是这样有一个局限,因为有的程序会加壳,这样会隐藏真实的IAT表,从而使该方法失效。
第二种方法是直接跳转,改变API函数的头几个字节,使程序跳转到自己的函数,然后恢复API开头的几个字节,在调用AP完成功能后再改回来又能继续Hook了,但是这种方法也有一个问题就是同步的问题,当然这是可以克服的,并且该方法不受程序加壳的限制。
Windows下APIHook技术
Windows下APIHook技术1 前⾔在Micrisoft Windows中,每个进程都有⾃⼰的私有地址空间。
当我们⽤指针来引⽤内存的时候,指针的值表⽰的是进程⾃⼰的⾃制空间的⼀个内存地址。
进程不能创建⼀个指针来引⽤属于其他进程的内存。
独⽴的地址控件对开发⼈员和⽤户来说都是⾮常有利的。
对开发⼈员来说,系统更有可能捕获错误的内存读\写。
对⽤户⽽⾔,操作系统变得更加健壮。
当然这样的健壮性也是要付出代价的,因为它使我们很难编写能够与其他进程通信的应⽤程序或对其他进程进⾏操控的应⽤程序。
在《Windows 核⼼编程》第⼆⼗⼆章《DLL注⼊和API拦截》中讲解了多种机制,他们可以将⼀个DLL注⼊到另⼀个进程地址的空间中。
⼀旦DLL代码进⼊另⼀个地址空间,那么我们就可以在那个进程中随⼼所欲了。
本⽂主要介绍了如何实现替换Windows上的API函数,实现Windows API HOOK。
API HOOK的实现⽅法⼤概不下五六种。
本位主要介绍了其中的⼀种,即如何使⽤WIndows挂钩来注⼊DLL。
2 使⽤Windows挂钩来注⼊DLL2.1 简单windows消息HOOK2.1.1 SetWindowsHookEx这个是安装狗⼦的函数声明如下:HHOOK WINAPI SetWindowsHookEx(__in int idHook, \\钩⼦类型__in HOOKPROC lpfn, \\回调函数地址__in HINSTANCE hMod, \\实例句柄__in DWORD dwThreadId); \\线程ID,0表⽰所有让我们通过⼀个例⼦来学些下这个API。
进程A(⼀个游戏改建⼯具,需要接获键盘消息),安装了WH_KEYBOARD_LL挂钩,如下所⽰:HOOK hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstDll, 0); 第⼀个参数表⽰挂钩类型,是⼀个低级键盘钩⼦。
易语言HOOKAPI 技巧
(HookFuncAddr -
返回 (JmpCode)
2. Hook recv 函数等的技巧,这类函数的特点是,某个参数是具有缓冲区性质的,并在函数 调用完成后参数会直接传递数据,所以结合上面的代码,就可以这样了:
ret=Call(jmpcode,para1,para2.etc) 这时候,再对参数 para1 等进行处理,才可以获得数据
RtlMoveMemory_1 (hHook, 到字节集 (FuncAddress), 4) JmpCode = hHook + 4
RtlMoveMemory (JmpCode, FuncAddress, 5) RtlMoveMemory_1 (JmpCode + 5, { 233 } + 到字节 集 (到整数 (FuncAddress + 5 - JmpCode - 10)), 5)
易语言 HookAPI 技巧
易语言 Hook 的代码有很多,Hook 的跳转代码也很简单,不多说,主要注意的有:
1. 可以保存原 API 函数的 API 头到自己申请的地址,Hook 跳转的地址仍然是自己的子程序, 但如果保存了 API 头,就可以 call addr 实现不dress = 0 或 HookFuncAddr = 0) 返回 (0)
.如果真结束
hHook = VirtualAlloc (0, 14, #PAGE_EXECUTE_READWRITE) .如果真 (hHook = 0)
返回 (0) .如果真结束
位或
(#MEM_COMMIT, #MEM_RESERVE),
3. Anti-Hook 的躲避技巧,部分程序会有检测 API 头 5 字节,所以我们只需要在 Hookaddr 上面加上一段偏移(大于 5)即可躲避。更深入地,如果检测的是整个 API 头,我们就 需要深入 API 的调用过程,Hook 核心函数或其他流程来躲避。由于校验所有 API 头 hash 值需要大量的 CPU 占用及时间,所以一般也只会对重点函数进行检测。
API Hook基本原理和实现
API Hook基本原理和实现Hook是什么?Windows系统下的编程,消息message的传递是贯穿其始终的。
这个消息我们可以简单理解为一个有特定意义的整数,正如我们看过的老故事片中的“长江长江,我是黄河”一个含义。
windows中定义的消息给初学者的印象似乎是“不计其数”的,常见的一部分消息在winuser.h头文件中定义。
hook与消息有着非常密切的联系,它的中文含义是“钩子”,这样理解起来我们不难得出“hook是消息处理中的一个环节,用于监控消息在系统中的传递,并在这些消息到达最终的消息处理过程前,处理某些特定的消息”。
这也是hook分为不同种类的原因。
hook的这个本领,使它能够将自身的代码“融入”被hook住的程序的进程中,成为目标进程的一个部分。
我们也知道,在windows2000以后的系统中,普通用户程序的进程空间都是独立的,程序的运行彼此间都不受干扰。
这就使我们希望通过一个程序改变其他程序的某些行为的想法不能直接实现,但是hook的出现给我们开拓了解决此类问题的道路。
API Hook是什么?在windows系统下编程,应该会接触到api函数的使用,常用的api函数大概有2000个左右。
今天随着控件,stl等高效编程技术的出现,api的使用概率在普通的用户程序上就变得越来越小了。
当诸如控件这些现成的手段不能实现的功能时,我们还需要借助api。
最初有些人对某些api函数的功能不太满意,就产生了如何修改这些api,使之更好的服务于程序的想法,这样api hook就自然而然的出现了。
我们可以通过api hook,改变一个系统api 的原有功能。
基本的方法就是通过hook“接触”到需要修改的api函数入口点,改变它的地址指向新的自定义的函数。
api hook并不属于msdn上介绍的13类hook中的任何一种。
所以说,api hook并不是什么特别不同的hook,它也需要通过基本的hook提高自己的权限,跨越不同进程间访问的限制,达到修改api函数地址的目的。
Api hook
API拦截(API HOOK)技术及应用常用的API Hook(截取API,或函数钩子)有两种方式:陷阱式、改引入表式。
在Windows 9x、WindowsNT/2000这两个系统中的API Hook代码完全不同。
就Windows 9x而言,16位DLL与32位DLL的API Hook代码也完全不相同。
API HOOK入门API Hook是一项有趣而实用的Windows系统编程技术,应用领域十分广泛,屏幕取词、内码转换、屏幕翻译、中文平台、网络防火墙、串口红外通信或Internet通信的监视等,都涉及到了此项技术。
API Hook就是钩住API,钩就是绕弯的意思,即让API函数的调用先绕一个弯路,在它执行之前,先做一些“预处理”,这样我们就可以监视或定制某个Win32 API的调用,以实现一些特殊的功能。
至于具体可以实现些什么样的功能,就取决于程序设计者的想象力了。
在很多情况下,想监视或改变某个应用程序的一些特定的操作,但是该应用程序却没有提供相应的接口,而又几乎不可能得到其源代码。
因为大多数Windows应用程序的操作很大程度上依赖于API,所以可以采用API Hook的方式来试图监视和改变应用程序的行为。
常用的API Hook有两种方式:陷阱式和改引入表式。
API Hook的运行平台有三种:Windows 9x的16位DLL、Windows 9x的32位DLL和Windows NT/2000的32位DLL。
其关系如表7-1所示。
表7-1 API Hook的方式其中,×表示不能实现;Ο表示只对指定模块有效,对整个进程或整个操作系统无效;―表示在VC下可以实现,在C++Builder/Delphi下很难实现;√表示可以实现。
陷井式API HOOK原理Windows NT/2000陷阱式API Hook的工作原理如图1所示。
其工作过程如下:(1)加载陷阱式API Hook时,需要定位至被截函数处(图中是BF501234),写入一条跳转指令(Jmp XXXX,二进制代码为E9XXXX),表示所有程序调用被截函数时都自动跳转到自定义函数。
Hook(钩子技术)基本知识讲解,原理
Hook(钩⼦技术)基本知识讲解,原理⼀、什么是HOOK(钩⼦) APIWindows消息传递机制,当在应⽤程序进⾏相关操作,例如点击⿏标、按下键盘,操作窗⼝等,操作系统能够感知这⼀事件,接着把此消息放到系统消息队列,然后到应⽤程序的消息序列中,应⽤程序通过Getmessage函数取出消息,然后调⽤DispatchMessage函数将这条消息调度给操作系统,操作系统会调⽤在设计窗⼝类时指定的应⽤程序窗⼝对这⼀消息进⾏处理,处理过程如图所⽰:在《VC深⼊详解》⼀书将钩⼦过程⽐喻为警察为了抓逃犯⽽设置的检查站,基本原理也确实与此类似。
就是在应⽤程序将信息传递给操作系统时(图中③的),对消息进⾏捕获和过滤,从⽽阻⽌消息发送到指定的窗⼝过程,最终完成对某些消息的屏蔽功能。
HOOK(钩⼦,挂钩)是⼀种实现Windows平台下类似于中断的机制。
HOOK机制允许应⽤程序拦截并处理Windows消息或指定事件,当指定的消息发出后,HOOK程序就可以在消息到达⽬标窗⼝之前将其捕获,从⽽得到对消息的控制权,进⽽可以对该消息进⾏处理或修改,加⼊我们所需的功能。
钩⼦按使⽤范围分,可分为线程钩⼦和系统钩⼦,其中,系统钩⼦具有相当⼤的功能,⼏乎可以实现对所有Windows消息的拦截、处理和监控。
这项技术涉及到两个重要的API,⼀个是SetWindowsHookEx,安装钩⼦;另⼀个是UnHookWindowsHookEx,卸载钩⼦。
对于Windows系统,它是建⽴在事件驱动机制上的,说⽩了就是整个系统都是通过消息传递实现的。
hook(钩⼦)是⼀种特殊的消息处理机制,它可以监视系统或者进程中的各种事件消息,截获发往⽬标窗⼝的消息并进⾏处理。
所以说,我们可以在系统中⾃定义钩⼦,⽤来监视系统中特定事件的发⽣,完成特定功能,如屏幕取词,监视⽇志,截获键盘、⿏标输⼊等等。
程序员在讨论时也常说“可以先钩住再处理”,即执⾏某操作之前,优先处理⼀下,再决定后⾯的执⾏⾛向。
API函数_超强HOOK技术
API函数_超强HOOK技术其实 DNF QQ三国等SX HS 非法扩展名文件提示检测完全可以用API_HOOK技术来搞定的截获API是个很有用的东西,比如你想分析一下别人的程序是怎样工作的。
这里我介绍一下一种我自己试验通过的方法。
首先,我们必须设法把自己的代码放到目标程序的进程空间里去。
WindowsHook 可以帮我们实现这一点。
SetWindowsHookEx的声明如下:HHOOKSetWindowsHookEx(intidHook,hooktypeHOOKPROClpfn,hookprocedureHINSTANCEhMod,handletoapplicationinstanceDWORDdwThreadIdthreadidentifier);具体的参数含义可以翻阅msdn,没有msdn可谓寸步难行。
这里Hook本身的功能并不重要,我们使用它的目的仅仅只是为了能够让Windows把我们的代码植入别的进程里去。
hookType我们任选一种即可,只要保证是目标程序肯定会调用到就行,这里我用的是WH_CALLWNDPROC。
lpfn和hMod分别指向我们的钩子代码及其所在的dll,dwThreadId设为0,表示对所有系统内的线程都挂上这样一个hook,这样我们才能把代码放到别的进程里去。
之后,我们的代码就已经进入了系统内的所有进程空间了。
必须注意的是,我们只需要截获我们所关心的目标程序的调用,因此还必须区分一下进程号。
我们自己的钩子函数中,第一次运行将进行最重要的API重定向的工作。
也就是通过将所需要截获的API的开头几个字节改为一个跳转指令,使其跳转到我们的API 中来。
这是最关键的部分。
这里我想截三个调用,ws2_32.dll中的send和recv、user32.dll中的GetMessageA。
DWORDdwCurrentPID=0;HHOOKhOldHook=NULL;DWORDpSend=0;DWORDpRecv=0;GETMESSAGEpGetMessage=NULL;BYTEbtNewBytes[8]={0x0B8,0x0,0x0,0x40,0x0,0x0FF,0x0E0,0}; DWORDdwOldBytes[3][2];HANDLEhDebug=INVALID_HANDLE_value;LRESULTCALLBACKCallWndProc(intnCode,WPARAMwParam,LPARAMlParam){DWORDdwSize;DWORDdwPIDWatched;HMODULEhLib;if(dwCurrentPID==0){dwCurrentPID=GetCurrentProcessId();HWNDhwndMainHook;hwndMainHook=FindWindow(0,MainHook);dwPIDWatched=SendMessage(hwndMainHook,(WM_USER+100),0,0);hOldHook=(HHOOK)SendMessage(hwndMainHook,(WM_USER+101),0,0);if(dwCurrentPID==dwPIDWatched){hLib=LoadLibrary(ws2_32.dll);pSend=(DWORD)GetProcAddress(hLib,send);pRecv=(DWORD)GetProcAddress(hLib,recv);ReadProcessMemory(INVALID_HANDLE_value,(void)pSend,(void)dwOldBytes[0],sizeof(D WORD)2,&dwSize);(DWORD)(btNewBytes+1)=(DWORD)new_send;WriteProcessMemory(INVALID_HANDLE_value,(void)pSend,(void)btNewBytes,sizeof(DWO RD)2,&dwSize);ReadProcessMemory(INVALID_HANDLE_value,(void)pRecv,(void)dwOldBytes[1],sizeof(D WORD)2,&dwSize);(DWORD)(btNewBytes+1)=(DWORD)new_recv;WriteProcessMemory(INVALID_HANDLE_value,(void)pRecv,(void)btNewBytes,sizeof(DWO RD)2,&dwSize);hLib=LoadLibrary(user32.dll);pGetMessage=(GETMESSAGE)GetProcAddress(hLib,GetMessageA); ReadProcessMemory(INVALID_HANDLE_value,(void)pGetMessage,(void)dwOldBytes[2],si zeof(DWORD)2,&dwSize);(DWORD)(btNewBytes+1)=(DWORD)new_GetMessage;WriteProcessMemory(INVALID_HANDLE_value,(void)pGetMessage,(void)btNewBytes,size of(DWORD)2,&dwSize);hDebug=CreateFile(CTrace.log,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NOR MAL,0);}}if(hOldHook!=NULL)if(hOldHook!=NULL){returnCallNextHookEx(hOldHook,nCode,wParam,lParam);}return0;}上面的钩子函数,只有第一次运行时有用,就是把三个函数的首8字节修改一下(实际上只需要7个)。
Windows_Hook_易核心编程(3)_API_Hook_续_拦截API
上一期,我们讲了用HOOK技术实现远程线程插入,相信大家还记忆犹新.这一期我们来谈谈 API HOOKAPI Hook技术应用广泛,常用于屏幕取词,网络防火墙,病毒木马,加壳软件,串口红外通讯,游戏外挂,internet通信等领域API HOOK的中文意思就是钩住API,对API进行预处理,先执行我们的函数,例如我们用API Hook技术挂接ExitWindowsEx API函数,使关机失效,挂接ZwOpenProcess函数,隐藏进程等等......总的来说,常用的挂钩API方法有以下两种: <一>改写IAT导入表法我们知道,Windows下的可执行文档的文件格式是一种叫PE(“portable executable”,可移植的可执行文件)的文件格式,这种文件格式是由微软设计的,接下来这张图描述了PE文件的结构:+-------------------------------+ - offset 0| MS DOS标志("MZ") 和 DOS块 |+-------------------------------+| PE 标志 ("PE") |+-------------------------------+| .text | - 模块代码| 程序代码 || |+-------------------------------+| .data | - 已初始化的(全局静态)数据| 已初始化的数据 || |+-------------------------------+| .idata | - 导入函数的信息和数据| 导入表 || |+-------------------------------+| .edata | - 导出函数的信息和数据| 导出表 || |+-------------------------------+| 调试符号 |+-------------------------------+这里对我们比较重要的是.idata部分的导入地址表(IAT)。
8种hook技术_hook方式
8种hook技术_hook方式在软件开发中,常常需要对特定的功能或流程进行定制化。
而在定制化过程中,hook技术是一个重要的利器。
本文将介绍8种常见的hook方式。
1. 函数Hook:函数Hook是指通过修改函数的入口地址,截获函数的执行过程以实现自定义逻辑。
通常使用的方法有替换函数指针、注入代码等。
2. 系统调用Hook:系统调用是操作系统提供的接口,用于访问底层资源。
通过hook系统调用,可以在应用程序执行系统调用时,对其进行自定义处理,如修改传入参数、替换返回值等。
3. 消息Hook:消息是GUI应用程序中用于传递用户输入、系统事件等的基本单元。
通过hook消息,可以拦截和处理应用程序接收到的消息,并进行相应的操作。
4. API Hook:API是应用程序提供的接口,用于实现特定功能。
通过hook API,可以在调用API的过程中,修改其行为或增加额外的功能。
5. 线程Hook:线程是程序执行的基本单位,通过hook线程,可以在线程创建、销毁、执行过程中注入自定义代码,实现对线程行为的监控和控制。
6. 类Hook:类是面向对象编程中的基本概念,通过hook类,可以修改类的行为或增加新的功能。
常见的类hook方式包括继承、代理、装饰器等。
7. 注册表Hook:注册表是Windows操作系统中用于存储系统配置信息的数据库。
通过hook注册表,可以拦截对注册表的读写操作,实现对系统配置的自定义修改。
8. 文件系统Hook:文件系统是操作系统中用于管理文件和目录的模块。
通过hook文件系统,可以拦截对文件和目录的操作,实现对文件系统的自定义控制和保护。
综上所述,以上是8种常见的hook技术方式。
在软件开发中,合理运用这些hook技术,可以实现对应用程序的灵活定制和功能增强,提升开发效率和系统性能。
当然,在使用hook技术时,务必注意合法合规,避免不必要的安全风险和潜在问题。
希望本文能对读者对hook 技术有所了解和应用。
API钩子揭秘(上)
API钩子揭秘(上)
Ivo;Ivanov;赵雪峰
【期刊名称】《程序员》
【年(卷),期】2002(000)007
【摘要】很多人经常问到:如何像金山词霸那样实现屏幕取词?这项技术最关键的地方就是对系统文本输出函数进行拦截,也就是所谓钩子(Hook)技术:在没有源程序可使用的情况下,如何操作系统改变或者其他软件的功能?本文全面、系统地分析了各种不同技术的实现,具有很高的实用和指导价值。
【总页数】3页(P)
【作者】Ivo;Ivanov;赵雪峰
【作者单位】
【正文语种】中文
【中图分类】TP311.52
【相关文献】
1.永明诗病说猜想(上)——揭秘平头、上尾、蜂腰、鹤膝 [J], 钟如雄
2.Win95系统API函数大揭秘 [J], 何发武
3.编写Win 32 API钩子 [J], 范武
4.API钩子揭秘(下) [J], IvoIvanov; 赵雪峰
5.在核战争边缘上徘徊——1990年印巴核危机揭秘(上) [J], 杜幼康
因版权原因,仅展示原文概要,查看原文内容请购买。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1 I k A H o 系统一般框架 P o
一个 A I o 主要山两个模块组成:钩子服务器( o k P H k o Ho Sr r e e 模块,一般为 E E v) X 的形式;钩子驱动器(ok vr H o Di ) re 模块,一般为D L L 的形式。钩子服务器主要负责向目 标进程 注人钩子驱动器,使得钩子驱动器运行在目 标进程的地址空 间,而钩子驱动器则负责实际的A I P拦截处理工作,实现我 们期望的功能。上 述关于A I k P H o 的两个部分, o 分别涉及两 项关键技术的实现: L D L注人技术和A I P 拦截技术。
21利用注册表注入 D L . L
当准备拦截的目 标进程连接 f e3. l U r2 l s d ,也即使用了
个生命周期内的 A I P 调用情况进行监控,用这种方法会遗翻
某些 A I P 的调用 。
2 . 3远程线程技术
远程线程技术指的是通过Ceee o Trd r t m t h a在另一个 aR e e
远程进程的内存空间
ieun d = i Poes m r(R m tPoes o e Wre rcsMe oy e oe cs, 被保护的 D L文件被篡改( R trC t h r L 数字签名技术) ,它就会自动从 pz i iR m t(V I )s i iN m , ,U L; s b l e o , OD pz b l a e b L ) L Fe eP L Fe cN dcce 恢复这个文件。 lahl l 卜 虽然说有方法可以绕过D L L 保护( 例
பைடு நூலகம்
s 要是 程, 以 要申 足 的 限POES AE HED 制— 内核级的拦截和用户级的拦截。内核级的钩子 i 所 需 请 够 权 ( CS CET_ RA , R R T ’ 然后, od i a W 这个线程来启动我们的 D L 建立L aLb r ry L , 任何细节,不在本文的探讨范围之内。而用厂级的钩子则通 L 中实现整个A I P的拦截工作, 。 般有以 下 LaL r W函数是在kr l .I odia br y e e 2 l n 3 d 中定义的, 用来加载D L 常是在普通的D L L
/ dia W的入u 计算LaL r o br y 地址
P HR AD S AR _ OUT NE f S at d = _ T T R T E I p n trAd r
(T R A _ A T R T N ) P H E D S R _ OU I E T
如先更改dcce 录,的备份再修改 D L lah 目 卜 l L 文件、或者利用 Ko n L s nw D L 键值更改D L的默认启动路径等) L ,但是可以顶
wokld)木马D L s o .l c d l。 L 遇到不认识的调用, 使用函数转发器
码并处理。 前对于 日 特洛伊D L L 技术, 微软已有防范 Wi K n 2 的s t 3 口 ye 2 录下设i a e 录, sm Y l c 口 这个口 dc h l 录中存放着 大量
的D L L 文件( 也包括 ・ 峡重要的ee x文件) 。 操作系统发现 , 城
数( e no sokx 在St dwH oE 的参数中指定) Wi 能够对此消息进行适
享, 必须把它存储在一个共享的数据仄域。 C + 在V + 中我们可 以采用预编译指令#r m dt s 在D L # a a e L 文件中创建一个新 pg a g a 的段, 并在D F E 文件中把该段的属性设置为” a d, s r " 这样就 he
\pIt L 键值中定义钩f A p iD s n L 驱动器。 该键值标识的D L L将 在符合条件的应用程序启动时自 动加载。这是Wi o s n w 操作 保护) d 系统内建的机制。 这种注人方式存在的缺点是: 仅适用于N / T he o P cs O eP csP C S C A ET R A oe = pnr e ( O E S E T _ H E Rm t r s e o sR R 2 K操作系统;如果需要激活或停止钩子的注人,只有重新启 D/ I / 允许远程创建线程 P O E S M P R TO I R C S一 - E A IN O / / 允许远
见,未来微软必将更加小心地保护币要的D L L 文件。
G trc des e drs G t dl ad (E T" e e 2) e oA P ( Mou H n l T X ( r l ) e e K n 3" , 0od i a W" L aLb r ) ry ;
3 改写执行代码 . 2
文作,它 只存一 参数: L 文件 对路径名pzi i 儿种方法。 个 D L 的绝 s b l L Fe
Nm ( ae 也就是D L L 的全路径文件名) 由于D L 。 L 是在远程进程 内调用的, 所以首先还需要将这个文件名复制到远程地址空 间:否则远程线程读不到这个参数) ( / L 计算 D 路径名需要的内存空间 L
件,替换原来的 w o k 2dI sc 3 .I将原先的 D L文件贡命名为 ( L
/ ullc、 使用Vra l E 函数在远程进程的内存地址空间分 l Ao t
配D L L 文件名缓冲区
NUL , , M_ MMI , GE R AD Lc ME C b O TP A _ E WR T ) IE ;
i c=1 sl W(s b l a e *i o( Ir n pz i iN m ) s ef H R ; n b ( te t + L Fe ) z WC A )
3 . 1代理D L特洛伊木马) L(
特洛伊D 的工作原理是使用木马D L L L L 替换常用的D L L
文件, 通过函数转发器将正 常的调用转发给原D L 截获并 L, 处理特定的消息。 譬如, 我们知道WID WS o e . N O 的Sc tx k l的 函数存放在wok2 1i 我们另写 一 s k2 l I s 3.1 c d B, t 个wo 3.l 文 c d 木I
网萝 旦全 技木与应用 2 6 1 苦 0. 01
万方数据
由于 后面需要写入远程进程的内存地址空间并建立 远程线
V O E A I N, WRT ) M_ R TO P V M_ IE 。
在A I k o 应用的系统级别方面, PH o 有两类A I P拦截的机 通过一个内核模式的驭动程序来实现,能捕捉到系统活动的
的( : 属J 内核模块) ,所以这个人口地址同样适用于远程进程。
最后, 我们通过建立远程线程时的地址p S r dr f tt d 实 n aA (
际上就是LaLb r od ia W的入口地址) ry 和传递的参数pzi i s bl L Fe 到原先的A I P 函数的地址,然后把该函数开始的几个字 省 用 R m t我们复制到远程进程内存空间的木马D L e o( e L 的全路径文 i 指令代替,从而使得对该 A I mp P 函数的调用能够转向我们 件名) 在远程进程内启动钩子驱动器 D L: L 自定义的函数调用。 / 1 启动远程线程LaL ry 通过远程线程调用用户 odia W, br 3 改写P . 3 E文件的输人地址表 的D L L 文件 P 文件的结构如图2 E 所示。 开始是 ・ O 程序, 段D S 当你 h e o T r dCe e m t h a( e o Po s/ h a= r t e o T r d R m t r es 被 Rm t e e aR e e h e c , / 的程序在不支持Wi o s n w 的环境中运行时,它会显示警告语 d
动Wi o s 不能用此方法向没有使用Ue 2 l n w; d s 3.l r d 的应用程序
注入 D L L ,例如控制台应用程序等;钩 子 驱动器D L将注人 L 程V M操作 P O E SV WRT , 允许远程V _ _ IE/ R CS M M写
F L Ed R moe oes ; w e t rcsl) A S, P d
A I k P H o 关键技术解析 o
刘克胜 王忠寿
解放军电子 〔 程学院网络 〔 程系信息安全教研室 安徽 203 307
摘要:本文分析了A I k P H o 系统的实现结构和系统涉及的 D L注人和A I o L P 拦截两项关键技术的多种实现途径,并结合 应用给出了编程实现的方法。 关键词:A I K;关键技术;解析 P H O O
有许多拦截的方法是基 于可执行代码的改写,第 ‘ 种方
说 面计算 明一卜 ,卜 的其实是本进程内LaL r W的 o ia d br y
人口 地址, 批由于kr ll e ed 模块在所有进程内的地址都是相同 n .l
法是改变在 C L 指令中使用的函数地址。它的从本思路是 AL 检索出日 标进程需要拦截的 A I A L P 的C L 指令,然后把原先 的地址改成为我们在钩 子 驱动器中提供的函数地址。第二种 方法就是常用的 i X X的方法。 l mp X : 要的实现步骤是先找
pzi i e o =P R Vra l E ( e o P cs Rm t ( T ) ullcx Rm t r es f w r交给wokld ;遇到特殊的请求( s bl L Fe e WS i Ao h t eo , o a r d sco .l dl 事先约定的) 就解
/ t r e M m r函数将D L 使用Wr P c s e o i os e y L 的路径名复制到
0 引言
A I k是 项实川的WID WS 一 PH o o N O 系统编程技术,应
用领域十分广泛。A 1 k P H o 通过对应用程序内存映像A I o P调 用的重定向,改变应用程序流程,从而实现对 A I P 函数调用 的监视和控制。
2 . 2建众 系统范围的Wi o s n w 钩子 d
建立了一个共享数据段。