全局钩子注入

全局钩子注入全局钩子介绍hook,指利用api来提前拦截并处理windows消息的一种技术。如键盘钩子,许多木马都有这东西,监视你的键盘操作。全局钩子是系统钩子的一种,当指定的一些消息被系统中任

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

全局钩子注入

全局钩子介绍

hook,指利用api来提前拦截并处理windows消息的一种技术。如键盘钩子,许多木马都有这东西,监视你的键盘操作。

全局钩子是系统钩子的一种,当指定的一些消息被系统中任何应用程序所处理时,这个钩子就被调用

钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。对每种类型的钩子由系统来维护一个钩子链,最近安装的钩子放在链的开始,而最先安装的钩子放在最后,也就是后加入的先获得控制权。要实现Win32的系统钩子,必须调用SDK中的API函数SetWindowsHookEx来安装这个钩子函数,这个函数的原型是HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId)

其中,第一个参数是钩子的类型;第二个参数是钩子函数的地址;第三个参数是包含钩子函数的模块句柄;第四个参数指定监视的线程。如果指定确定的线程,即为线程专用钩子;如果指定为空,即为全局钩子。其中,全局钩子函数必须包含在DLL(动态链接库)中,而线程专用钩子还可以包含在可执行文件中。得到控制权的钩子函数在完成对消息的处理后,如果想要该消息继续传递,那么它必须调用另外一个SDK中的API函数CallNextHookEx来传递它。钩子函数也可以通过直接返回TRUE来丢弃该消息,并阻止该消息的传递。

SetWindowsHookEx

设置钩子API

HHOOK WINAPI SetWindowsHookEx(
  _In_  int    idHook,           // 设置钩子的类型.意思就是我要设置的钩子是什么钩子. 可以是监视窗口过程.可以是监视消息队列.
  _In_ HOOKPROC lpfn,            // 根据钩子类型.设置不同的回调函数.
  _In_ HINSTANCE hMod,          //  钩子设置的Dll实例句柄,就是DLL的句柄
  _In_ DWORD dwThreadId           //  设置钩子的线程ID. 如果为0 则设置为全局钩子.
);
                         // HHOOK 返回值. 是一个钩子过程句柄.

参数

idHook

要安装钩子的程序类型

全局钩子注入

lpfn

一个指向钩子程序的指针。如果dwThread参数为0或指定由不同进程创建线程标识符,则lpfn参数必须指向DLL中的钩子过程,否则,lpfn可以指向与前进程关联的代码中的钩子过程。

hMod:

包含由lpfn参数指向的钩子过程的 DLL 句柄。所述HMOD参数必须设置为NULL,如果dwThreadId参数指定由当前进程,并且如果钩子程序是与当前过程相关联的所述代码中创建的线程。

dwThreadId:

与钩子过程关联的线程的标识符。对于桌面应用程序,如果此参数为零,则挂钩过程与调用线程在同一桌面上运行的所有现有线程相关联。

返回值

如果函数成功,则返回值是钩子过程的句柄,否则返回值为NULL

GetModuleHandle

获取模块句柄API

HMODULE WINAPI GetModuleHandle(
  _In_opt_ LPCTSTR lpModuleName          // 获取的实例句柄的文件名.可以是Dll可以使exe  如果为NULL 这是当前dll/exe的实例句柄
);     

UnhookWindowsHookEx

取消设置钩子API

BOOL WINAPI UnhookWindowsHookEx(
  _In_ HHOOK hhk                        //参数一是 SetWindowHookEx的返回值.也就是钩子过程句柄. 
); 

CallNextHookEx

继续调用钩子链中的钩子过程

LRESULT WINAPI CallNextHookEx(
  _In_opt_ HHOOK hhk,          //保存的钩子过程,也就是SetWindowsHookEx返回值.
  _In_      int     nCode,           // 根据SetWindowsHookEx设置的钩子回调而产生的不同的nCode代码. 什么意思? 意思就是如果设置的钩子类型是鼠标消息.那么那个nCode就是鼠标消息.如果是键盘这是键盘
  _In_ WPARAM wParam,                // 同2参数一样.附加参数. 根据钩子回调类型.附加参数有不同的意义.比如如果是鼠标.那么这个有可能代表的就是鼠标的x位置.键盘就可能是键代码
  _In_ LPARAM lParam                 /// 同3参数一样.附加参数.
);

代码案例1

#include <Windows.h>
#include<stdio.h>

HHOOK g_hHook;
LRESULT GetMsgProc(
	int code,
	WPARAM wParam,
	LPARAM lParam)
{
	
	return ::CallNextHookEx(g_hHook, code, wParam, lParam);
}

int main()
{
	HMODULE hDll;
	hDll = ::LoadLibrary("hookdll.dll");
	g_hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, hDll, 0);
	if (g_hHook == NULL) {
		printf("Hook Failed!\n");
		return -1;
	}
	else
	{
		printf("Hook Success!\n");
		system("pause");
	}
	UnhookWindowsHookEx(g_hHook);
	printf("UnHook");

}

DLL文件编写

#include "pch.h"
#include<Windows.h>



BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    MessageBox(0, 0, "Success", 0);
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

全局钩子注入

全局钩子注入

全局钩子注入

代码案例2

cpp代码

#include <Windows.h>
#include<stdio.h>

int main() {
	typedef BOOL(*_SetGlobalHook)();
	typedef BOOL(*_UnsetGlobalHook)();
	
	
	HMODULE hmodoule;
	hmodoule =::LoadLibrary("hookdll.dll");
	_SetGlobalHook SetGlobalHook =(_SetGlobalHook)GetProcAddress(hmodoule, "SetGlobalHook");
	int a = SetGlobalHook();
	if (a) {
		printf("HOOK");
	}
	else
	{
		printf("HOOK ERRER!!!");
	}

	_UnsetGlobalHook UnsetGlobalHook = (_UnsetGlobalHook)GetProcAddress(hmodoule, "UnsetGlobalHook");
	UnsetGlobalHook();
	printf("UNHOOK");
	system("pause");
	return 0;

}

dll代码

#include "pch.h"
#include<Windows.h>


//共享内存
#pragma data_seg("mydata")                   //而不是放在shared中,从而导致多个进程之间的共享行为失败
#pragma data_seg()
#pragma comment(linker,"/SECTION:mydata,RWS")
HHOOK g_hHook = NULL;    //必须赋初值,否则微软编译器会把没有初始化的数据放到普通的未初始化数据段中
HMODULE g_hModule;        //钩子句柄    

extern "C" _declspec(dllexport)
//卸载钩子
BOOL UnsetGlobalHook()
{
    if (g_hHook)
    {
        UnhookWindowsHookEx(g_hHook);
    }
    return TRUE;
}

//钩子的回调函数
LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
{
    MessageBox(NULL, "你被监视了", "提示", MB_ICONWARNING | MB_OKCANCEL);

    //CallNextHookEx函数表示将当前钩子传递给钩子链中的下一个钩子
    //第一个参数当前钩子的句柄。如果直接返回0,则表示中断钩子传递
    //对钩子进行拦截
    return CallNextHookEx(g_hHook, code, wParam, lParam);

}

extern "C" _declspec(dllexport)
//设置全局钩子
BOOL SetGlobalHook()
{
    //SetWindowsHookEx,第一个参数表示钩子的类型,WH_GETMESSAGE表示安装消息队列的消息钩子
    //可以监视发送到消息队列的消息。第二个参数表示钩子回调函数,第三个参数表示包含钩子回调
    //函数的DLL模块句柄,如果要设置全局钩子,则该参数必须指定DLL模块句柄,第四个参数表示与
    //钩子关联的线程ID,0表示为全局钩子,关联所有线程。
    g_hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, g_hModule, 0);
    if (g_hHook == NULL)
    {
        return FALSE;
    }
    return TRUE;
}


BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        g_hModule = hModule;
        break;
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119850.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • include用法PHP,php之include的使用[通俗易懂]

    服务器端包含(SSI)用于创建可在多个页面重复使用的函数、页眉、页脚或元素。PHPinclude和require语句在PHP中,您能够在服务器执行PHP文件之前把该文件插入另一个PHP文件中。include和require语句用于在执行流中向其他文件插入有用的的代码。include和require很相似,除了在错误处理方面的差异:require会产生致命错误…

    2022年4月14日
    59
  • Java数组元素求和[通俗易懂]

    Java数组元素求和[通俗易懂]今天给大家解析,Java中数组元素求和的过程一听到求和我们应该首先想到,要运用到**+=**publicclassQiuhe{publicstaticvoidmain(String[]args){//定义一个静态初始化int[]arr={1,2,3,4,5,6,7,8,9};//再定义一个数据用来接收最后的和…

    2022年7月16日
    26
  • oracle删除索引释放空间,oracle 索引迁移,释放磁盘空间[通俗易懂]

    oracle删除索引释放空间,oracle 索引迁移,释放磁盘空间[通俗易懂]索引文件迁移步骤:准备工作:1)备份GBOS用户表索引:通过plsqlDevelop工具将GBOS用户表索引全部导出,以做备份。1.查看索引表空间具有那些数据文件selectfile_id,file_name,tablespace_name,bytes/1024/1024M,blocksfromdba_data_fileswhereTABLESPACE_NAME=’USERINDEX…

    2022年9月4日
    2
  • 【带你入门】java网络编程

    【带你入门】java网络编程网络编程网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习。在学习网络编程以前,很多初学者可能觉得网络编程是比较复杂的系统工程,需要了解很多和网络相关的基础知识,其实这些都不是很必需的。首先来问一个问题:你会打手机吗?很多人可能说肯定会啊,不就是按按电话号码,拨打电话嘛,很简单的事情啊!其实初学者如果入门网

    2022年6月12日
    39
  • 关于ARM2440中断源个数的一点想法[通俗易懂]

    关于ARM2440中断源个数的一点想法[通俗易懂]关于ARM2440中断源个数的一点想法

    2022年4月21日
    39
  • javascript中数据类型有哪些_四种基本数据类型

    javascript中数据类型有哪些_四种基本数据类型JavaScript里有几种数据类型

    2022年9月6日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号