Windows下Hook API技术

Windows平台基于API Hook技术的WinInet网络库HttpDNS实现方案 一、项目背景 学而思网校直播课堂在线安装程序,是一个独立的应用程序,提供学生端的安装功能,为了减少安装包体积,避免引入第三方网络库,使用的是操作系统的WinInet网络库。为了更好的优化网络,提高网络连接的成功率,避免Local DNS造成的域名劫持等问题,采用HttpDNS方式实现域名解析。 二、为什么使用HttpDNS 相比于传统的DNS,HttpDNS主要有以下优势: 1. 域名防劫持: 使用Http(Https)协议进行域名解析,域名解析请求直接发送至HttpDNS服务器,绕... 阅读详情

  Org:http://hi.baidu.com/gudu13lang/blog/item/62e2cb549625fe58d0090649.html

    

  什么叫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_MOUSE
  HOOKPROC 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了,但是这种方法也有一个问题就是同步的问题,当然这是可以克服的,并且该方法不受程序加壳的限制。
  下面将以一个Hook指定程序send函数的例子来详细描述如何Hook API,以达到监视程序发送的每个封包的目的。采用的是第二种方法,编写为一个dll。首先是一些全局声明,
 
//本dll的handle
HANDLE g_hInstance = NULL;
//修改API入口为 mov eax, 00400000;jmp eax是程序能跳转到自己的函数
BYTE g_btNewBytes[8] = { 0xB8, 0x0, 0x0, 0x40, 0x0, 0xFF, 0xE0, 0x0 };
//保存原API入口的8个字节
DWORD g_dwOldBytes[2][2] = { 0x0, 0x0, 0x0, 0x0 };
//钩子句柄
HHOOK g_hOldHook = NULL;
//API中send函数的地址
DWORD g_pSend = 0;
//事务,解决同步问题
HANDLE g_hSendEvent = NULL;
//自己的send函数地址,参数必须与API的send函数地址相同
int _stdcall hook_send( SOCKET s, const char *buf, int len, int flags );
//要Hook的进程和主线程ID号
DWORD g_dwProcessID = 0;
DWORD g_dwThreadID = 0;
 
  从声明可以看出,我们会把API函数的首8个字节改为 mov eax, 00400000;jmp eax ,使程序能够跳转,只需获取我们自己的函数地址填充掉00400000即可实现跳转。而g_dwOldBytes是用来保存API开头原始的8个字节,在真正执行API函数是需要写回。还有一点,在声明新的函数时,该例中为hook_send,除了保正参数与API的一致外,还需要声明为__stdcall类型,表示函数在退出前自己来清理堆栈,因为这里是直接跳转到新函数处,所以必须自己清理堆栈。下面看主函数,
 
BOOL APIENTRY DllMain( HANDLE hModule, 
  DWORD ul_reason_for_call, 
  LPVOID lpReserved
  )
{
  if(ul_reason_for_call == DLL_PROCESS_ATTACH)
  {
  //获取本dll句柄
  g_hInstance = hModule;
   
  //创建事务
  g_hSendEvent = CreateEvent( NULL, FALSE, TRUE, NULL );
   
  //重写API开头的8字节
  HMODULE hWsock = LoadLibrary( "wsock32.dll" );
  g_pSend = ( DWORD )GetProcAddress( hWsock, "send" );
 
  //保存原始字节
  ReadProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pSend, 
  ( void * )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );
  //将00400000改写为我们函数的地址
  *( DWORD* )( g_btNewBytes + 1 ) = ( DWORD )hook_send;
  WriteProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pSend, 
  ( void * )g_btNewBytes, sizeof( DWORD )*2, NULL ); 
  }
  return TRUE;
}
 
  以上是dll的main函数,在被指定的程序加载的时候会自动运行dll的main函数来完成初始化,这里就是改写API的首地址来完成跳转。当然本程序是对于指定程序进行Hook,如果要进行全局Hook,可以在main函数中用GetModuleFileName函数来获取exe文件完整路径,判断当前进程是否是想要Hook的进程。写函数中使用INVALID_HANDLE_VALUE,表示写本进程。
 
int _stdcall hook_send( SOCKET s, const char *buf, int len, int flags )
{
  int nRet;
  WaitForSingleObject( g_hSendEvent, INFINITE );
  
  //恢复API头8个字节
  WriteProcessMemory( INVALID_HANDLE_VALUE, ( void* )g_pSend, 
  ( void* )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );
 
  /*
  这里可以添加想要进行的处理过程
  */
 
  //真正执行API函数
  nRet = send( s, buf, len, flags );
 
  //写入跳转语句,继续Hook
  WriteProcessMemory( INVALID_HANDLE_VALUE, ( void* )g_pSend, 
  ( void* )g_btNewBytes, sizeof( DWORD )*2, NULL );
 
  SetEvent( g_hSendEvent );
 
  return nRet;
}
 
HOOK_API BOOL StartHook(HWND hWnd)
{
  //通过传入的窗口句柄获取线程句柄
  g_dwThreadID = GetWindowThreadProcessId( hWnd, &g_dwProcessID );
 
  //WH_CALLWNDPROC类型的Hook
  g_hOldHook = SetWindowsHookEx( WH_CALLWNDPROC, HookProc,  
  ( HINSTANCE ) g_hInstance, g_dwThreadID );

  if( g_hOldHook == NULL )
  return FALSE;

  return TRUE;
}
 
static LRESULT WINAPI HookProc( int nCode, WPARAM wParam, LPARAM lParam ) 
{

 return CallNextHookEx( g_hOldHook, nCode, wParam, lParam ); 
}
 
HOOK_API void StopHook(void)
{
  if(g_hOldHook != NULL)
  {
  WaitForSingleObject( g_hSendEvent, INFINITE );

  HANDLE hProcess = NULL;
  hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, g_dwProcessID);

  DWORD dwOldProc;
  DWORD dwNewProc;
 
  //改变页面属性为读写
  VirtualProtectEx( hProcess, ( void* )g_pSend, 8, PAGE_READWRITE, &dwOldProc );
 
  //恢复API的首8个字节
  WriteProcessMemory( hProcess, ( void* )g_pSend, 
  ( void* )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );
 
  //恢复页面文件的属性
  VirtualProtectEx( hProcess, ( void* )g_pSend, 8, dwOldProc, &dwNewProc );
  
  CloseHandle(g_hSendEvent);
  
  UnhookWindowsHookEx( g_hOldHook );
  }
}
 
  可以看出,我们创建的Hook类型是WH_CALLWNDPROC类型,该类型的Hook在进程与系统一通信时就会被加载到进程空间,从而调用dll的main函数完成真正的Hook,而在SetWindowsHookEx函数中指定的HookProc函数将不作任何处理,只是调用CallNextHookEx将消息交给Hook链中下一个环节处理,因为这里SetWindowsHookEx的唯一作用就是让进程加载我们的dll。
  以上就是一个最简单的Hook API的例子,该种技术可以完成许多功能。例如网游外挂制作过程中截取发送的与收到的封包即可使用该方法,或者也可以在Hook到API后加入木马功能,反向连接指定的主机或者监听某一端口,还有许多加壳也是用该原理来隐藏IAT表,填入自己的函数地址。

Rust实战:通过DLL注入与IAT Hook技术拦截Windows API调用 本文详细介绍了如何使用Rust语言实现Windows平台下的DLL注入与IAT Hook技术,以拦截并修改目标进程对特定API(如MessageBoxW)的调用。通过实战代码解析,阐述了Rust在系统编程中的内存安全优势、DLL入口点编写、IAT遍历与地址替换原理,以及远程线程注入的具体步骤,为开发者提供了一套安全、高效的API拦截解决方案。 阅读详情

相关推荐

Windows进程隐藏技术:基于API Hook的用户态实现与原理剖析

Windows系统编程中,API Hook(应用程序编程接口挂钩)是一种重要的技术手段,它允许开发者拦截和修改函数调用,从而改变程序行为或扩展系统功能。其核心原理是通过修改目标函数入口处的指令,将执行流重定向到自定义的钩子函数,在完成特定处理后再返回原函数或直接返回修改结果。这项技术在软件安全、系统监控、调试工具等领域具有重要价值,例如可用于开发行为分析工具、性能监控软件或沙箱环境。通过挂钩关键的系统API,开发者能够深入理解Windows内核与用户态的交互机制,掌握进程管理、内存操作等底层知识。本文以进

weixin_33794672的博客 354

History API(vue-router模拟前置知识)

History API 模拟vue-router的history模式的实践时,需要用到 History API 的知识。 history window.history对象是一个只读属性。 提供了操作浏览器会话历史(浏览器地址栏中访问的页面,以及当前页面中通过框架加载的页面)的接口。 history.go history.back history.forward history.pushState history.replaceState 提供了会话历史的信息 history.length 会话历史

皮蛋很白的博客 1397

深入解析Windows与Linux下的Hook技术:从API劫持到LD_PRELOAD实战

本文深入解析了Windows与Linux平台下的Hook技术原理与实战应用。在Windows中,通过API劫持与DLL注入实现函数调用拦截;在Linux下,则利用LD_PRELOAD环境变量优雅地劫持动态库函数。文章对比了两种技术的实现层级、复杂度与应用场景,为软件调试、行为监控与系统扩展提供了实用指南。

weixin_29275257的博客 419

深入解读Windows API挂接与Hook技术实践

以上实例和分析展示了API Hook技术在游戏和软件开发中的广泛应用和显著效果,同时也强调了在使用时需谨慎对待,确保技术的合法合规应用,并关注其带来的潜在风险。随着技术的不断进步,我们期待API Hook技术能够在更多领域带来创新和便利。

weixin_42405592的博客 1281

WindowsAPI Hook 技术

1 前言 在Micrisoft Windows中, 每个进程都有自己的私有地址空间。当我们用指针来引用内存的时候,指针的值表示的是进程自己的自制空间的一个内存地址。进程不能创建一个指针来引用属于其他进程的内存。 独立的地址控件对开发人员和用户来说都是非常有利的。对开发人员来说,系统更有可能捕获错误的内存读\写。对用户而言, 操作系统变得更加健...

weixin_30298497的博客 443

WindowsHook API 技术(HOOK SEND)

WindowsHookAPI技术 什么叫HookAPI?所谓Hook就是钩子的意思,而API是指Windows开放给程序员的编程接口,使得在用户级别下可以对操作系统进行控制,也就是...

weixin_33749242的博客 683

WindowsHook API技术小结 (转)

WindowsHook API技术小结 (转) 发布时间:2015-4-1 10:48:05编辑:www.fx114.net 分享查询网我要评论 本篇文章主要介绍了"WindowsHook API技术小结 (转)",主要涉及到WindowsHook API技术小结 (转)方面的内容,对于WindowsHook API技术小结 (转)感兴趣的同学可以参考一下。

xingzheouc的专栏 641

WindowsHook API技术 inline hook

  什么叫Hook API?所谓Hook就是钩子的意思,而API是指 Windows开放给程序员的编程接口,使得在用户级别下可以对操作系统进行控制,也就是一般的应用程序都需要调用API来完成某些功能, Hook API的意思就是在这些应用程序调用真正的系统API前可以先被截获,从而进行一些处理再调用真正的API来完成功能。在讲Hook API之 前先来看一下如何Hook消息,例如Hook全局键盘消

zhuerhua的专栏 1240

Hook技术第一讲,之Hook Windows API

一丶什么是Hook,以及Hook能干啥 首先这一个小标题主要介绍神马是Hook,如果知道的,则不用看了. 这里我偷袭啊懒,贴出Hook的意思https://blog.csdn.net/qq_34573534/article/details/103702378 Hook,英文单词中成为钩子,铁钩的意思,在我们编程中就是挂钩的意思。 我们要Hook Api,则是要把这个API进行挂钩,让其...

qq_34573534的博客 935

WindowsHook API技术(hook send)

什么叫Hook API?所谓Hook就是钩子的意思,而API是指Windows开放给程序员的编程接口,使得在用户级别下可以对操作系统进行控制,也就是一般的应用程序都需要调用API来完成某些功能,Hook API的意思就是在这些应用程序调用真正的系统API前可以先被截获,从而进行一些处理再调用真正的API来完成功能。在讲Hook API之前先来看一下如何Hook消息,例如Hook全局键盘消息,从而可

zbc_vc的专栏 3608

有关Windows平台下Hook一些系统API技术方案的考虑

生病并调养近半年了,也好久没有写博文了,真是有些抱歉,总有心有余力不足的感觉。最近,遇到一种使用情形,需要覆盖Windows系统API的默认行为,而且可能不光涉及到Win32 x86,x64,可能还要涉及到wince平台。本文只是一个简要的技术介绍,有兴趣的朋友可以一步步摸索下去。首先是Win32 x86/x64下边,比如,我要覆盖'MessageBoxA'的调用(e.g.只是举例,实际可能更复杂

iihero@CSDN 3267

逆向实用干货分享,Hook技术第一讲,之Hook Windows API

             逆向实用干货分享,Hook技术第一讲,之Hook Windows API 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) 一丶什么是Hook,以及Hook能干啥 首先这一个小标题主要介绍神马是Hook,如果知道的,则不用看了. 这里我偷袭啊懒,贴出Hook的意思https://ba...

weixin_30247781的博客 278
上一篇: 详谈HOOK API的技术
下一篇: 什么是“跨进程 API Hook”?
killcpp
博客等级 码龄20年 13粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值