HOOK API技术

HOOK API技术

HOOK学习笔记与心得

奇技淫巧之调试被远程线程注入的DLL

windows核心编程_系统消息与自定义钩子hook使用

[Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术]

Hook :Microsoft Detours 2.1简介

detours3.0文档

Hook简单实用

detours hook其它进程的api

逆向神器IDA

一. 什么是HOOK(钩子)

对于Window系统,它是建立在事件驱动机制上.整个系统都是通过消息传递实现的.

hook(钩子)是一种特殊的消息处理机制,它可以监视系统或者进程中的各种事件消息,截获发往目标窗口的消息并进行处理.

二.HOOK分类

  • 线程钩子监视指定线程的事件消息
  • 系统钩子监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库(DLL)中。这是系统钩子和线程钩子很大的不同之处。

三.HOOK工作原理

在正确使用钩子函数前,先讲解工作钩子函数的工作原理.

当你创建一个钩子时,WINDOWS会先在内存中创建一个数据结构,该数据结构包含了钩子的相关信息,然后把该结构体加到已经存在的钩子链表中去.新的钩子将加到老的前面.当一个事件发生时,如果您安装的是一个线程钩子,您进程中的钩子函数将被调用.如果是一个系统钩子,系统就必须把钩子函数插入到其它进程的地址空间,要做到这一点要求钩子函数必须在一个动态链接库中,所以如果您想要使用系统钩子,就必须把该钩子函数放到动态链接库中去.

四.HOOK API技术

本文主要介绍的就是HOOK API的技术.

Windows系统API函数都是被封装到DLL中,在某个应用程序要调用一个API函数的时候,如果这个函数所在的DLL没有被加载到本进程中则加载它,然后保存当前环境(各个寄存器和函数调用完后的返回地址等).

接着程序会跳转到这个API函数的入口地址去执行此处的指令.

由此看来,想在调用真正的API之前先调用我们的函数,那么可以修改这个API函数的入口处的代码,使他先跳转到我们的函数地址,然后在我们的函数最后再调用原来的API函数.

HOOK API 可以理解成对程序将要执行系统函数的一个拦截, 拦截后执行自己写的代码以达到完成某种特定的目的,再恢复程序继续执行,很多PJ中的Patch 机器码,盗号木马等都是用这个方法.

五.Detours

5.1 Detours介绍

Detours 是Microsoft开发一个库.

它具有两方面的功能:

  • 拦截x86机器上的任意的win32 API函数;
  • 插入任意的数据段到PE文件中,修改DDL文件的导入表;

Detours是一个用来在二进制级别上对程序中的函数(Function)或者过程(Procedure)进行修改的工具库.

一般我们将这种技术称为"Hook".

Detours的实现原理是将目标函数的前几个字节改为jmp指令跳转到自己的函数地址,以此接管对目标函数的调用,并插入自己的处理代码.

在现实中,这种技术可以应用在很多场景下.比如Hook某些Windows API,在实际调用到系统函数前进行一些过滤工作;软件中使用到了一些没有源代码的第三方库,但是又想增强其中某些函数的功能,等等.

在这里插入图片描述

在这里插入图片描述

5.2 Detours库x86 x64编译

参考 Detour hook库x86 x64编译

5.3 Detours的简单使用

注意点:

  1. 导入Detour时,需要导入头文件和库文件。
#include "../Detours/include/detours.h"
#pragma comment (lib,"../Detours/lib.X86/detours.lib")
  1. 要对挂钩函数进行保存。先定义一个函数指针保存要挂钩的函数,目的是为了最后的还原。

  2. 挂钩的函数一定要与原函数的原型一模一样(除函数名外)。包含返回值、参数类型。

  3. 挂钩的思路:

    • 找到要挂钩的函数.并提取出来;
    • 定义一个与函数原型一样的新函数.
    • 进行挂钩
// 进行挂钩
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach();
DetourTransactionCommit();

//----

// 解除钩子
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach();
DetourTransactionCommit();

为什么使用DLL

1.扩展了应用程序的特性
2.简化了项目管理
3.节省内存
4.促进资源共享
5.促进本地化 本地有一个DLL不需要重复下载
6.解决各版本的差异

注意:

DLL与应用程序共享一个进程空间
在DLL中分配的内存必须由DLL来进行释放
应用程序不会因为DLL的卸载而释放空间

DLL与EXE的不同点:
1.生成的程序属性不同。
2.入口函数不同。DLL是DllMain()

简单使用DEMO
源代码:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

//包含Detour的头文件和库文件
#include "../Detours/include/detours.h"
#pragma comment (lib,"../Detours/lib.X86/detours.lib")

//保存函数原型
static int (WINAPI *OldMesssageBoxW)(
_In_opt_ HWND hWnd,
_In_opt_ LPCWSTR lpText,
_In_opt_ LPCWSTR lpCaption,
_In_ UINT uType)=MessageBoxW;

//改写函数
static int WINAPI NewMessageBoxW(
    _In_opt_ HWND hWnd,
    _In_opt_ LPCWSTR lpText,
    _In_opt_ LPCWSTR lpCaption,
    _In_ UINT uType)
{
    return OldMesssageBoxW(NULL, L"new MessageBox", L"Please", MB_OK);
    
}
//开始下钩子
void StartHook()
{
    //开始事务
    DetourTransactionBegin();
    //更新线程信息  
    DetourUpdateThread(GetCurrentThread());
    //将拦截的函数附加到原函数的地址上
    DetourDatach(&(PVOID&)OldMesssageBoxW, NewMessageBoxW);
    //结束事务
    DetourTransactionCommit();
}

//解除钩子
void EndHook()
{    
    //开始事务
    DetourTransactionBegin();
    //更新线程信息 
    DetourUpdateThread(GetCurrentThread());
    //将拦截的函数从原函数的地址上解除
    DetourDetach(&(PVOID&)OldMesssageBoxW, NewMessageBoxW);
    //结束事务
    DetourTransactionCommit();
}


int _tmain(int argc, _TCHAR* argv[])
{
    //应原样输出
    MessageBoxW(NULL, L"old MessageBox", L"Please", MB_OK);
    
    //应改变输出
    StartHook();
    MessageBoxW(NULL, L"old MessageBox", L"Please", MB_OK);
    
    //应原样输出
    EndHook();
    MessageBoxW(NULL, L"old MessageBox", L"Please", MB_OK);
    
    system("pause");
    return 0;
}

六. Detours实现的第三方Dll钩子测试代码

实现了一个Demo. 实现了将DLL注入EXE. 实现API的替换.
代码提交至GithubDetoursDemo

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值