关于dll注入方式的学习(全局钩子注入)
何为dll注入
DLL注入技术,一般来讲是向一个正在运行的进程插入/注入代码的过程。我们注入的代码以动态链接库(DLL)的形式存在。DLL文件在运行时将按需加载(类似于UNIX系统中的共享库(share object,扩展名为.so))。然而实际上,我们可以以其他的多种形式注入代码(正如恶意软件中所常见的,任意PE文件,shellcode代码/程序集等)。
全局钩子注入
在Windows大部分应用都是基于消息机制,他们都拥有一个消息过程函数,根据不同消息完成不同功能,windows通过钩子机制来截获和监视系统中的这些消息。一般钩子分局部钩子与全局钩子,局部钩子一般用于某个线程,而全局钩子一般通过dll文件实现相应的钩子函数。
核心函数
SetWindowsHookEx
HHOOK WINAPI SetWindowsHookEx (
__in int idHook , \钩子类型
__in HOOKPROC lpfn , \回调函数地址
__in HINSTANCE hMod , \实例句柄
__in DWORD dwThreadId ); \线程ID
通过设定钩子类型与回调函数的地址,将定义的钩子函数安装到挂钩链中。如果函数成功返回钩子的句柄,如果函数失败,则返回NULL
实现原理
由上述介绍可以知道如果创建的是全局钩子,那么钩子函数必须在一个DLL中。这是因为进程的地址空间是独立的,发生对应事件的进程不能调用其他进程地址空间的钩子函数。如果钩子函数的实现代码在DLL中,则在对应事件发生时,系统会把这个DLL加较到发生事体的进程地址空间中,使它能够调用钩子函数进行处理。
在操作系统中安装全局钩子后,只要进程接收到可以发出钩子的消息,全局钩子的DLL文件就会由操作系统自动或强行地加载到该进程中。因此,设置全局钩子可以达到DLL注入的目的。创建一个全局钩子后,在对应事件发生的时候,系统就会把 DLL加载到发生事件的进程中,这样,便实现了DLL注入。
为了能够让DLL注入到所有的进程中,程序设置WH_GETMESSAGE
消息的全局钩子。因为WH_GETMESSAGE
类型的钩子会监视消息队列,并且 Windows系统是基于消息驱动的,所以所有进程都会有自己的一个消息队列,都会加载 WH_GETMESSAGE
类型的全局钩子DLL。
那么设置WH_GETMESSAGE
就可以通过以下代码实现,记得加上判断是否设置成功
// 设置全局钩子BOOL SetHook ()
{g_Hook = :: SetWindowsHookEx ( WH_GETMESSAGE , ( HOOKPROC ) GetMsgProc , g_hDllMoudle , 0 );if ( g_Hook == NULL ){return FALSE ;}return TRUE ;
}
这里第二个参数是回调函数,那么我们还需要写一个回调函数的实现,这里就需要用到CallNextHookEx
这个api,主要是第一个参数,这里传入钩子的句柄的话,就会把当前钩子传递给下一个钩子,若参数传入0则对钩子进行拦截
// 钩子回调函数
LRESULT GetMsgProc ( int code , WPARAM wParam , LPARAM lParam ) {return :: CallNextHookEx ( g_Hook , code , wParam , lParam );
}
既然我们写入了钩子,如果不使用的情况下就需要将钩子卸载掉,那么这里使用到UnhookWindowsHookEx
这个api来卸载钩子
// 卸载钩子
BOOL UnsetHook ()
{if ( g_Hook ){:: UnhookWindowsHookEx ( g_Hook );}
}
既然我们使用到了SetWindowsHookEx
这个api,就需要进行进程间的通信,进程通信的方法有很多,比如自定义消息、管道、dll共享节、共享内存等等,这里就用共享内存来实现进程通信
// 共享内存
#pragma data_seg("mydata")HHOOK g_hHook = NULL ;
#pragma data_seg()
#pragma comment(linker, "/SECTION:mydata,RWS"
实现过程
首先新建一个dll
在pch.h
头文件里面声明这几个我们定义的函数都是裸函数,由我们自己平衡堆栈
extern "C" _declspec ( dllexport ) int SetHook ();
extern "C" _declspec ( dllexport ) LRESULT GetMsgProc ( int code , WPARAM wParam , LPARAM lParam );
extern "C" _declspec ( dllexport ) BOOL UnsetHook ();
然后在pch.cpp
里面写入三个函数并创建共享内存
// pch.cpp: 与预编译标头对应的源文件#include "pch.h"
#include <windows.h>
#include <stdio.h>extern HMODULE g_hDllModule ;// 共享内存
#pragma data_seg("mydata")
HHOOK g_hHook = NULL ;
#pragma data_seg()
#pragma comment(linker, "/SECTION:mydata,RWS")//钩子回调函数
LRESULT GetMsgProc ( int code , WPARAM wParam , LPARAM lParam ) {return :: CallNextHookEx ( g_hHook , code , wParam , lParam );
}// 设置钩子
BOOL SetHook () {g_hHook = SetWindowsHookEx ( WH_GETMESSAGE , ( HOOKPROC ) GetMsgProc , g_hDllModule , 0 );if ( NULL == g_hHook ) {return FALSE ;}return TRUE ;
}// 卸载钩子
BOOL UnsetHook () {if ( g_hHook ) {UnhookWindowsHookEx ( g_hHook );}return TRUE ;
}
然后再在dllmain.cpp
设置DLL_PROCESS_ATTACH
,然后编译生成Golbal.dll
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
HMODULE g_hDllModule = NULL ;BOOL APIENTRY DllMain ( HMODULE hModule ,DWORD ul_reason_for_call ,LPVOID lpReserved)
{switch ( ul_reason_for_call ){case DLL_PROCESS_ATTACH : {g_hDllModule = hModule ;break ;}case DLL_THREAD_ATTACH :case DLL_THREAD_DETACH :case DLL_PROCESS_DETACH :break ;}return TRUE ;
}
再创建一个控制台项目
使用LoadLibrabryW
加载dll,生成GolbalInjectDll.cpp
文件
// GolbalInjectDll.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include <iostream>
#include <Windows.h>int main () {typedef BOOL ( * typedef_SetGlobalHook )();typedef BOOL ( * typedef_UnsetGlobalHook )();HMODULE hDll = NULL ;typedef_SetGlobalHook SetGlobalHook = NULL ;typedef_UnsetGlobalHook UnsetGlobalHook = NULL ;BOOL bRet = FALSE ;do{hDll = :: LoadLibraryW ( TEXT ( "F:\C++\GolbalDll\Debug\GolbalDll.dll" ));if ( NULL == hDll ){printf ( "LoadLibrary Error[%d]\n" , :: GetLastError ());break ;}SetGlobalHook = ( typedef_SetGlobalHook ) :: GetProcAddress ( hDll , "SetHook" );if ( NULL == SetGlobalHook ){printf ( "GetProcAddress Error[%d]\n" , :: GetLastError ());break ;}bRet = SetGlobalHook ();if ( bRet ){printf ( "SetGlobalHook OK.\n" );}else{printf ( "SetGlobalHook ERROR.\n" );}system ( "pause" );UnsetGlobalHook = ( typedef_UnsetGlobalHook ) :: GetProcAddress ( hDll , "UnsetHook" );if ( NULL == UnsetGlobalHook ){printf ( "GetProcAddress Error[%d]\n" , :: GetLastError ());break ;}UnsetGlobalHook ();printf ( "UnsetGlobalHook OK.\n" );} while ( FALSE );system ( "pause" );return 0 ;
}
执行即可注入GolbalDll.dll
文末福利
1. 网络安全学习路线图:
【图片过大被平台压缩导致模糊,可以在文末免费下载高清完整版】
2. 网络安全学习视频教程
3. 网络安全学习文档资料
【需要资料的朋友,可以扫描下方二维码,免费获取《282G 全套网络安全学习资料包》】
关于dll注入方式的学习(全局钩子注入)相关推荐
- 【安全技术】关于几种dll注入方式的学习
何为dll注入 DLL注入技术,一般来讲是向一个正在运行的进程插入/注入代码的过程.我们注入的代码以动态链接库(DLL)的形式存在.DLL文件在运行时将按需加载(类似于UNIX系统中的共享库(shar ...
- Spring 的三种注入方式,到底哪种注入方式最佳?
1. 实例的注入方式 首先来看看 Spring 中的实例该如何注入,总结起来,无非三种: 属性注入 set 方法注入 构造方法注入 我们分别来看下. 1.1 属性注入 属性注入是大家最为常见也是使用最 ...
- Spring的三种注入方式(为什么推荐构造器注入?)
Spring的三种注入方式 一.属性注入 @Resource和@Autowired的区别 为什么尽量使用 @Resource? 二.setter 注入 三.构造器注入 具体可以看看Spring官网 为 ...
- 扯一把 Spring 的三种注入方式,到底哪种注入方式最佳?
循环依赖这个问题,按理说我们在日常的程序设计中应该避免,其实这个本来也是能够避免的.不过由于总总原因,我们可能还是会遇到一些循环依赖的问题,特别是在面试的过程中,面试考察循环依赖,主要是想考察候选人对 ...
- 【C++】代码实现:全局钩子注入技术
一.概述 在 Windows 中大部分的应用程序都是基于消息机制的,它们都有一个过程函数,根据不同的消息完成不同的功能. Windows 操作系统提供的钩子机制就是用来截获和监视系统中这些消息的. ...
- sql部分注入方式的学习
前言 文章同步于我的个人博客https://quan9i.top/sqlway/,欢迎大家访问. 近期在进行sql注入实战的时候发现一些注入方式并不是很擅长运用,在这里对部分注入方式进行总结,希望能对 ...
- Spring中bean属性注入方式总结:构造方法、setter注入、p命令空间注入、SpEL注入、集合注入
1. 构造方法注入 constructor-arg用于配置构造方法一个参数 name :参数的名称 value:设置普通数据 ref:引用数据,一般是另一个bean id值 index :参数的索引号 ...
- IOC操作Bean管理XML方式(创建对象和set注入属性)
目录 1.什么是 Bean 管理: (1)通过 Spring 创建对象 (2)通过 Spring 注入属性 2.IOC 操作 Bean 管理有两种方式: (1)基于 xml 配置文件方式实现 (1.1 ...
- 练习 进程钩子 全局钩子
C++ 关于钩子的知识点博客网上基本写的都非常详细,这里只是简单分享一下本人练手的编程步骤和一些简单认识. 钩子程序就大概分成了2种: (1) 进程中的钩子:它 的作用范围只是限定在某个进程中,或者某 ...
最新文章
- php stdclass,php中new stdclass()用在什么场景
- 【HDU - 5649】DZY Loves Sorting(线段树,区间更新区间查询,思维,01缩数变换,线段树分割)
- jsp 连接MS server 数据库的例子
- 从两道经典试题谈C/C++中联合体(union)的使用
- sessionStorage与clone方法在项目中的应用
- 事务回退机制 android,【Android基础】——Fragment-使用方法
- Trie 树内存消耗问题
- 使用Vue.js和ASP.NET Core MVC实现CQRS模式
- JavaScript 简史 1
- STM32系列 STM32F4xx 独立看门狗(IWDG)
- Maven——原理与使用(一)
- phalapi 数据库锁_[7.11]-phalapi-进阶篇5(数据库读写分离) | PhalApi(π框架) - PHP轻量级开源接口框架...
- iso 9000下载_ISO 9000 | 软件工程
- ascii码值大小顺序排序c语言,ascii码值的大小顺序是怎样的?
- html修改按钮属性,button属性
- 超棒工具8个高质量图标搜索引擎
- python zip压缩文件
- FTP和FXP的区别
- SAP 各种适配器配器
- 2022年版中国腰果酚市场趋势研究与竞争策略分析报告