java hook技术_API Hook基本原理和实现 - - JavaEye技术网站

news/2024/5/10 17:39:18/文章来源:https://blog.csdn.net/weixin_29699579/article/details/114111987

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函数地址的修改,是不需要用到api hook技术就可以实现的。

api hook和pe格式的关系

api hook技术的难点,并不在于hook技术,初学者借助于资料“照葫芦画瓢”能够很容易就掌握hook的基本使用技术。但是如何修改api函数的入口地址?这就需要学习pe可执行文件(.exe,.dll等)如何被系统映射到进程空间中,这就需要学习pe格式的基本知识。windows已经提供了很多数据结构struct帮助我们访问pe格式,借助它们,我们就不要自己计算格式的具体字节位置这些繁琐的细节。但是从api hook的实现来看,pe格式的访问部分仍然是整个编程实现中最复杂的一部分,对于经常crack的朋友不在此列。

假设我们已经了解了pe格式,那么我们在哪里修改api的函数入口点比较合适呢?这个就是输入符号表imported symbols table(间接)指向的输入符号地址。

下面对于pe格式的介绍这一部分,对于没有接触过pe格式学习的朋友应该是看不太明白的,但我已经把精华部分提取出来了,学习了pe格式后再看这些就很容易了。

pe格式的基本组成

+-------------------+

| DOS-stub     |  --DOS-头

+-------------------+

| file-header   |  --文件头

+-------------------+

| optional header |  --可选头

|- - - - - - - - - -|

|          |

| data directories |  --(可选头尾的)数据目录

|          |

+-------------------+

|          |

| section headers |  --节头

|          |

+-------------------+

|          |

| section 1    |  --节1

|          |

+-------------------+

|          |

| section 2    |  --节2

|     &// 本文转自 C++Builder 研究 - http://www.ccrun.com/article.asp?i=1036&d=cf6de2

nbsp;     |

+-------------------+

|          |

| ...        |

|          |

+-------------------+

|          |

| section n    |  --节n

|          |

+-------------------+

在上图中,我们需要从“可选头”尾的“数据目录”数组中的第二个元素——输入符号表的位置,它是一个IMAGE_DATA_DIRECTORY结构,从它中的VirtualAddress地址,“顺藤摸瓜”找到api函数的入口地点。

下图的简单说明如下:

OriginalFirstThunk 指向IMAGE_THUNK_DATA结构数组,为方便只画了数组的一个元素,AddressOfData 指向IMAGE_IMPORT_BY_NAME结构。

IMAGE_IMPORT_DESCRIPTOR数组:每个引入的dll文件都对应数组中的一个元素,以全0的元素(20个bytes的0)表示数组的结束

IMAGE_THUNK_DATA32数组:同一组的以全0的元素(4个bytes的0)表示数组的结束,每个元素对应一个IMAGE_IMPORT_BY_NAME结构

IMAGE_IMPORT_BY_NAME:如..@Consts@initialization$qqrv. 表示

Unmangled Borland C++ Function: qualified function __fastcall Consts::initialization()

6981645_1.gif

为了减少这个图的大小,不得已将汇编和c++的结构都用上了。这个图是输入符号表初始化的情形,此时两个IMAGE_THUNK_DATA结构数组的对应元素都指向同一个IMAGE_IMPORT_BY_NAME结构。

程序加载到进程空间后,两个IMAGE_THUNK_DATA结构数组指向有所不同了。看下图:

6981645_2.gif

初始化的,“两个结构都指向同一个IMAGE_IMPORT_BY_NAME”,此时还没有api函数地址

6981645_3.gif

当PE文件准备执行时,前图已转换成上图。一个结构指向不变,另一个出现api函数地址

如果PE文件从kernel32.dll 中引入10个函数,那么IMAGE_IMPORT_DESCRIPTOR 结构的 Name1域包含指向字符串"kernel32.dll"的RVA,同时每个IMAGE_THUNK_DATA 数组有10个元素。(RVA是指相对地址,每一个可执行文件在加载到内存空间前,都以一个基址作为起点,其他地址以基址为准,均以相对地址表示。这样系统加载程序到不同的内存空间时,都可以方便的算出地址)

上述这些结构可以在winnt.h头文件里查到。

具体编程实现

我将手上的vc示例代码进行了适当修正,修改了一些资源泄漏的小问题,移植到c++builder6 & update4上,经过测试已经可以完成基本的api hook功能。有几个知识点说明一下:

1、  dll中共享内存变量的实现

正常编译下的dll,它的变量使用到的内存是独立的。比如你同时运行两个调用了某个dll的用户程序,试图对某一个在dll中定义的全局变量修改赋值的时候,两个程序里的变量值仍然是不同的。

共享的方法为:在.cpp文件(.h文件里如此设置会提示编译错误)的头部写上如上两行:

#pragma option -zRSHSEG      // 改变缺省数据段名

#pragma option -zTSHCLASS    // 改变缺省数据类名

HINSTANCE hdll = NULL;          // 用来保存该动态连接库的句柄

HHOOK hApiHook = NULL;          // 钩子句柄

HHOOK hWndProc = NULL;          // 窗口过程钩子用来拦截SendMessage

int threadId = 0;

另外建立一个与dll同名,不同后缀的def文件,如HookDll.def文件,写上:

LIBRARY HookDll.dll

EXPORTS

;...

SEGMENTS

SHSEG CLASS 'SHCLASS' SHARED

;end

这样设置后在.cpp文件中定义的变量,如果进行了初始化,将进入“SHCLASS”共享内存段(如果不初始化,将不改变其默认段属性)。

6981645_4.gif

上述的共享对于本示例代码并不是必须的,只是稍微演示了一下。

2、  api hook修改api函数入口点地址的时机

很显然,我们必须通过hook进入目标进程的地址空间后,再在位于该地址空间里的hook消息处理过程里修改输入符号表“指向”的api函数入口点地址,退出hook前也必须在这个消息处理过程里恢复原来的地址。只要我们牢记修改的过程发生在目标进程的地址空间中,就不会发生访问违例的错误了。

示例代码使用了WH_GETMESSAGE、WH_CALLWNDPROC两中hook来演示如何hook api,但WH_GETMESSAGE实际上并没有完成具体的功能。

为了让初学者尽快的掌握重点,我将代码进行了简化,是一个不健壮、不灵活的演示示例。

3、  函数的内外部表现形式

例如api函数MessageBox,这个形式是我们通常用到的,但到了dll里,它的名字很可能出现了两个形式,一个是MessageBoxA,另一个是MessageBoxW,这是因为系统需要适应Ansi和Unicode编码的两种形式,我们不在函数尾端添加“A”或“W”,是不能hook到需要的函数的。

4、  辅助pe格式查看工具

PE Explorer是一个非常好的查看pe资源的工具,通过它可以验证自己手工计算的pe地址,可以更快的掌握pe格式。

调试器ollydbg也是非常好的辅助工具,例如查看输入符号表中的api函数。

5、  程序文件列表

dll基本文件:Hook.h,Hook.cpp,HookDll.def

client验证方基本文件:HookTest.h,HookTest.cpp,ApiHookTest.cpp

6981645_5.gif

6981645_6.gif

6、  实现的功能

对记事本的MessageBoxW函数进行了hook,先执行自定义的

int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR M1, LPCWSTR M2, UINT M3)

{

return oldMessageBoxW(hWnd, M1, L"my api hook", M3);

}

从这里可以看到,由于目标进程空间中的执行线程并不知道你已经改变了api函数的实际入口地址,它在调用时仍旧将参数一成不变的压入堆栈(这个说法是汇编代码时看到的等价情形),事实上你已经提前接收到了函数调用的所有参数。这里就是篇首帖子的回复了。

6981645_7.gif

hook之前

6981645_8.gif

hook以后

示例代码

1、client验证方的代码非常简单。建立一个Application工程,在窗体上放一个memo(提示信息),两个button(一个SetHook,另一个RemoveHook)。

void __fastcall TForm1::Button1Click(TObject *Sender)

{

DWORD dwProcessId, dwThreadID;

HWND hWnd = FindWindow("Notepad", NULL);

if (!hWnd)

{

Memo1->Lines->Add("Nodepad is not found");

}

else

{

dwThreadID = GetWindowThreadProcessId(hWnd, &dwProcessId);

Memo1->Lines->Add(dwThreadID);

SetHook(dwThreadID);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)

{

RemoveHook();

}

//---------------------------------------------------------------------------

2、api hook dll稍微复杂些,建立一个dll工程之后,修改之。代码中有一些函数并未用上,ReplaceApiAddress是核心函数,文章开始处有示例代码下载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_726771.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么wifi有的网站进不去_无线mesh分布式路由选购攻略,让家里随处有好的WiFi信号...

现在家庭都要用到WiFi,走亲访友到别人家,先要WiFi密码是常事。用WiFi最大的一个问题就是,为什么信号不好?为什么玩游戏会断线,为什么网速这么慢?为什么看电影追剧老要缓冲。现在大家都知道了,用…

用正则扒网站图片_可能是目前PC端最好用的词典——Goldendict

对于语言学习者来说,好的词典是一个不可或缺的工具。在专门寻找PC端的词典之前,需要查词的时候,我大多都是使用浏览器的划词插件。或者使用搜索引擎这样固然方便,但是划词插件提供的信息太少,如果只是帮助我们阅读&…

云服务器连接网站吗,云服务器连接到网站吗

云服务器连接到网站吗 内容精选换一换场景描述每个虚拟私有云VPC代表一个私有网络,与其他VPC逻辑隔离,您可以将业务系统部署在华为云上,构建云上私有网络环境。如果您有多个业务系统例如生产环境和测试环境要严格进行隔离,那么可以…

SEO--网站流量提升

话术设置,提炼优质的话术 关键词的挖掘 1、头脑风暴 (开晨会,一堆人坐在一起聊。) 2、利用搜索引擎相关搜索(将关键词设置为搜索热词,利用工具:百度指数,查看关键词) 3、…

react里做一个修改效果_工作思维:做一个以效果性驱动的SEO人才

针对于SEO的工作而言,我们身为SEO从业者应该如何做好工作就是今天我们要讨论的话题,毕竟每一家公司都是以人才驱动效果,人才越多,公司效益越好。先来看SEO工作上的几个误区:1、领导安排工作都是有标准的你的上级或公司…

最出色的5个在线网站推荐,也许你要收藏一下

现在互联网行业发展迅速,网站资源越来越多,小编入行以来整理了好多的一些资源性的网站,在工作或者生活中的确帮助了很多,小编今天就分享一些比较好用的网站给小伙伴们,小伙伴们准备好了吗? SlideModel——高…

***不是已知元素 原因可能是网站中存在编译错误

在用visual studio 2005编辑asp.net页面时,有时会遇到:"***"不是已知元素。错误情况如下图:原因可能是网站中存在编译错误。这有可能是代码中的"***"确实有错,但是有时候你会发现代码根本就没有错&#xff0c…

url中能出现的字符_浅析网站URL优化有哪些问题需要注意呢?

众所周知,网站优化工作是确保网站长久性运营的基础,在众多优化内容方面有一项重要内容,那就是网站URL的优化。所谓的网站URL就是网站在互联网中每一信息资源的统一且在互联网中的唯一地址,也是大家俗称的网络地址。那么针对网站UR…

lua mysql 域名_使用 lua 开发的网站有哪些?

EventServer基于lua和libevent的完全异步、高性能的web框架。既可以作为游戏服务,也可以做web服务,支持websocket和https。关键是可以ffi使用c/c库,比如libcurl和iconv,也可以调用第三方lua库,比如smtp、redis、luasql…

点某个链接进网站,会发这个链接的会员加积分,实现方法(有时间限制)

例如:http://www.bobo.com?useridaxeidxls01wdcx(这个userid会有一个加密) 当某个用户发出一个邀请后,另一个用户通过这个链接进行网站后,为发这个链接的用户加10个积分。 实现方法: 建立一个用户附加表InviteUser_NewUser,结构如…

名字英文name域名_怎么正确选择网站域名要素分享

域名他的英文名称叫做Domain Name,他是一长串用点以及数字来进行分隔的名字组合而成的。而网站的域名就是说的在网站里面所使用的域名,大家在注册这种网站域名的时候应该怎么选择呢?第一、站在品牌的角度去考虑要知道好的网站域名其实对企业或…

大型网站技术架构:核心原理与案例分析 mobi_一文了解,网站架构演化

本文主要讲述网站架构演化历史,主要是让大家对当前主流技术演化的目的,以及技术背景有所了解。本文内容主要参照于大型网站技术架构:核心原理与案例分析[1],也推荐大家深入研读这本书。自上世纪90年代初CERN正式发布 Web 标准和第…

网站兼容——火狐浏览器刷新没有清空表单

2019独角兽企业重金招聘Python工程师标准>>> 在进行项目开发中,发现一些筛选条件,上一次选中后,刷新页面仍然存在。页面上的数据仍然是上一次表单中的数据,其实是很火狐浏览器的兼容性造成的。 解决办法: 经…

31.网站数据监控-1

31.网站数据监控-1 网站数据监控:思路:对网站数据字段监控并做MD5加密存入到数据,为了后期监控数据是否更新作比对,然后邮件通知,存入四个字段。 引入的包:md5_tools.py # -*- coding:utf-8 -*-import hash…

基于LNMP的小米电商网站搭建——运维实战手记第一篇

分享一篇文章,来自马哥教育学员阿龙。总项目流程图,详见Linux运维企业架构实战系列 - 阿龙along - 博客园实战一:搭建lnmp及类小米等商业网站的实现环境:关闭防火墙,selinux1、安装包,开启服务yum -y insta…

实现网站页面的QQ临时会话,分享到空间微博等按钮.

一 qq临时会话要实现qq临时会话首先要到qq在线状态官网开通qq在线状态&#xff0c;其中临时对话也分为加密和未加密。1.1:加密模式<a target"_blank" href"http://sighttp.qq.com/authd?IDKEY9a2ea740a2af0f88c15eb511395e2460bd84bf549dd66365">&l…

服务器物理分离,不同功能进行物理分离实现网站架构的伸缩性设计

回顾网站架构发展历程&#xff0c;网站架构发展史就是一部不断向网站增加服务器的历史。只要工程师能向网站的服务器集群中增加新的机器&#xff0c;只要新增加的服务器能线性提高网站的整体服务处理能力&#xff0c;网站就无需为不断增长的用户和访问而焦虑。一般说来&#xf…

java 网站cookie_JavaWeb之Cookie和Session

七、Cookie和Session目录&#xff1a;会话、Cookie、Session(重点)1.会话会话&#xff1a;用户打开一个浏览器&#xff0c;点击了很多超链接&#xff0c;访问多个Web资源&#xff0c;关闭浏览器&#xff0c;这个过程可以称之为会话。有状态会话&#xff1a;一位用户访问过某网站…

SEO优化如何让提高收录量

相信在做SEO优化的网络人员来说&#xff0c;最高兴的时候就是看见自己辛苦打出来的文章被收录了。 可是&#xff0c;收录量就有点。。。。 今天&#xff0c;我就来教教大家怎么提高收录量&#xff0c;主要分四个方面。 1、收录网站的时间间隔 网站的重点是网站页面收录之间的时…

网站被黑提醒该站点可能受到黑客攻击,部分页面已被非法篡改...

大清早的一上班收到3个网站客户的QQ联系&#xff0c;说是自己公司的网站被跳转到了北京sai车&#xff0c;cai票&#xff0c;du博网站上去了&#xff0c;我们SINE安全公司对3个网站进行了详细的安全检测&#xff0c;发现这3个客户的网站都是同样的症状&#xff0c;网站首页文件i…