processhacker-code-5632\1.x\trunk\NProcessHacker\hook.h

typedef struct _PH_HOOK
{
PVOID Function;
PVOID Target;
BOOLEAN Hooked;
CHAR Bytes[5];
} PH_HOOK, *PPH_HOOK;

这个结构体用来保存每个Hook的信息,Function是hook点的地址, Target是Trampoline的地址,Bytes用来备份Function点处原来的5个字节。

processhacker-code-5632\1.x\trunk\NProcessHacker\hook.c

VOID PHAPI PhInitializeHook(
PPH_HOOK Hook,
PVOID Function,
PVOID Target
)
{
memset(Hook, 0, sizeof(PH_HOOK));
Hook->Function = Function;
Hook->Target = Target;
}

初始化Hook结构体,指定hook点与Trampoline的地址。

NTSTATUS PHAPI PhHook(
PPH_HOOK Hook
)
{
NTSTATUS status = STATUS_SUCCESS;
ULONG oldProtection;
PCHAR function; /* Change the page protection of the target page so we can write to it. */
if (!VirtualProtect(Hook->Function, 5, PAGE_EXECUTE_READWRITE, &oldProtection))
return STATUS_ACCESS_VIOLATION; __try
{
function = (PCHAR)Hook->Function;
/* Copy the original five bytes for unhooking. */
memcpy(Hook->Bytes, function, 5);
/* Hook the function by writing a jump instruction. */
Hook->Hooked = TRUE;
/* jmp Target */
*function = 0xe9;
*(PULONG_PTR)(function + 1) = (ULONG_PTR)Hook->Target - (ULONG_PTR)Hook->Function - 5;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
status = GetExceptionCode();
} /* Restore the old page protection. */
VirtualProtect(Hook->Function, 5, oldProtection, NULL); return status;
}

用于完成对Hook点的5个字节的替换,替换成e9 XXXXXXXX[Trampoline与Hook点之间的偏移距离]。

NTSTATUS PHAPI PhUnhook(
PPH_HOOK Hook
)
{
NTSTATUS status = STATUS_SUCCESS;
ULONG oldProtection; /* Change the page protection of the target page so we can write to it. */
if (!VirtualProtect(Hook->Function, 5, PAGE_EXECUTE_READWRITE, &oldProtection))
return STATUS_ACCESS_VIOLATION; __try
{
/* Unpatch the function by restoring the original first 5 bytes. */
memcpy(Hook->Function, Hook->Bytes, 5);
Hook->Hooked = FALSE;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
status = GetExceptionCode();
} /* Restore the old page protection. */
VirtualProtect(Hook->Function, 5, oldProtection, NULL); return status;
}

Unhook的过程恰好相反,用备份的5个字节恢复Hook点。

Process Hacker源码中的用户态hook的做法的更多相关文章

  1. Eclipse与Android源码中ProGuard工具的使用

    由于工作需要,这两天和同事在研究android下面的ProGuard工具的使用,通过查看android官网对该工具的介绍以及网络上其它相关资料,再加上自己的亲手实践,算是有了一个基本了解.下面将自己的 ...

  2. 访何红辉:谈谈Android源码中的设计模式

    最近Android 6.0版本的源代码开放下载,刚好分析Android源码的技术书籍<Android源码设计模式解析与实战>上市,我们邀请到它的作者何红辉,来谈谈Android源码中的设计 ...

  3. Android 源码中的设计模式

    最近看了一些android的源码,发现设计模式无处不在啊!感觉有点乱,于是决定要把设计模式好好梳理一下,于是有了这篇文章. 面向对象的六大原则 单一职责原则 所谓职责是指类变化的原因.如果一个类有多于 ...

  4. Eclipse与Android源码中ProGuard工具的使用(代码混淆)

    由于工作需要,这两天和同事在研究android下面的ProGuard工具的使用,通过查看android官网对该工具的介绍以及网络上其它相关资料,再加上自己的亲手实践,算是有了一个基本了解.下面将自己的 ...

  5. ASP.NET MVC Filters 4种默认过滤器的使用【附示例】 数据库常见死锁原因及处理 .NET源码中的链表 多线程下C#如何保证线程安全? .net实现支付宝在线支付 彻头彻尾理解单例模式与多线程 App.Config详解及读写操作 判断客户端是iOS还是Android,判断是不是在微信浏览器打开

    ASP.NET MVC Filters 4种默认过滤器的使用[附示例]   过滤器(Filters)的出现使得我们可以在ASP.NET MVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响 ...

  6. Spring Boot源码中模块详解

    Spring Boot源码中模块详解 一.源码 spring boot2.1版本源码地址:https://github.com/spring-projects/spring-boot/tree/2.1 ...

  7. 002-创建型-04-建造者模式(Builder)、JDK1.7源码中的建造者模式、Spring中的建造者模式

    一.概述 建造者模式的定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象 ...

  8. 07 flask源码剖析之用户请求过来流程

    07 Flask源码之:用户请求过来流程 目录 07 Flask源码之:用户请求过来流程 1.创建ctx = RequestContext对象 2. 创建app_ctx = AppContext对象 ...

  9. 挖掘隐藏在源码中的Vue技巧!

    前言 最近关于Vue的技巧文章大热,我自己也写过一篇(vue开发中的"骚操作"),但这篇文章的技巧是能在Vue的文档中找到蛛丝马迹的,而有些文章说的技巧在Vue文档中根本找不到踪迹 ...

随机推荐

  1. Linux随笔 - Linux统计某文件夹下文件、文件夹的个数

    统计某文件夹下文件的个数 ls -l |grep "^-"|wc -l 统计某文件夹下目录的个数 ls -l |grep "^d"|wc -l 统计文件夹下文件 ...

  2. Java学习之包

    一.包:就是类的命名空间(在文件系统中的表现形式就是文件夹) 二.代码编写规则 1.写在程序文件的第一行 2.格式:package 包名[.包名1.包名2......] 类的全名称 包名.类名 例如: ...

  3. 安装php时,configure: error: xml2-config not found. Please check your libxml2 installation

    参考文章:http://blog.csdn.net/anljf/article/details/6981247 安装php时的报错configure: error: xml2-config not f ...

  4. xshell的安装及连接linux的使用方法

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/lx_Frolf/article/deta ...

  5. 解决让刷新页面时不提示 "重试或取消”对话框

    如果刷新一个已经提交过的页面时,系统总是会提示一个 "重试或取消”的对话框.,如果是一个普通的页面,好象也无所谓,有就有,大不了多点一下.但是当我们是在子窗体中刷新父窗体时,就显得有点多余了 ...

  6. python字符串常用函数-大小写,删除空格,字符串切片

  7. 关于日历实现代码里lunarInfo(农历)数组

    var lunarInfo=new Array( 0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x0 ...

  8. log4j基础配置使用

    添加log4j的jar包:可以从maven处下载:https://mvnrepository.com/artifact/log4j/log4j/1.2.17 <!-- https://mvnre ...

  9. viewport的深入调研

    1.viewport概念:viewport就是设备的屏幕上能用来显示我们的网页的那一块区域. viewport的默认值980px或1024px等,以下是浏览器的默认viewport宽度 2.css中的 ...

  10. 同事遇到了一个问题(在DllMain函数之前抢控制权)

    同事有个需求,他的进程会加载一个DLL,他需要在那个DLL的DllMain函数执行之前控制DLL,修改DLL的内存. 以上工作要求全部在应用层执行. 这个其实有点悲剧. 因为这个需求其实有点坑,因为需 ...