32位windows的全局hook

1、思路:

整理以前的代码,顺便写个帖子。该方法是利用驱动构建调用门和中断门,然后利用调用门修改页相关dll的页属性,再利用中断门来hook相关的函数。当然也有更简单的方法,此方法是利用调用门和中断门的使用,当然64位下是行不通的,会触发pg。64需要切换gs,(x86是fs寄存器指向teb和kpcr)

2、驱动

#include <ntifs.h>
#include <ntddk.h>
#include <stdio.h>
#define DEVICENAME L"\\Device\\FuncHook"
#define SYMBOLNAME L"\\??\\Hook"

#define	StartHook CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define	StopHook CTL_CODE(FILE_DEVICE_UNKNOWN,0x900,METHOD_BUFFERED,FILE_ANY_ACCESS)
CHAR* GdtrTable[0x6] = { 0 };
CHAR* LdtrTale[0x6] = { 0 };
ULONG FuncAddress = 0;
ULONG MessageHwnd = 0;
ULONG MessageString = 0;
ULONG MessageTitle = 0;
ULONG MessageSelect = 0;
BOOLEAN FuncHook() {
	/**该方法由于不是目标程序的CR3,无法读取到目标程序内存,用调用门提权的方式**/
	/*
	ULONG CR3 = *(int*)((char*)Process + 0x18);
	KdPrint((CR3));
	if (CR3 == 0) {
		KdPrint(("寻找CR3失败"));
		return -1;
	//改变PTE属性
	__asm {
		pushad
		pushfd
		mov ecx,cr3
		mov ebx,CR3
		mov eax, FuncAddress
		//右移动18位置,相当于右移21位,再左移3位。2-9-9-12分页
		shr eax, 0x12
		mov esi,0x3ff8
		and eax,esi
		//想到与add eax,0xC0600000,找到PTE
		sub eax,0x3FA00000
		//取出PTE
		mov edx,[eax]
		//改变PTE属性为可读可写,or edx,0x0110     U/S=1 普通用户,
		or edx,0x5
		//右移动9位,取出PDT
		popfd
		popad
	*/
	//1、获取GDT的值

	__asm {
		pushad
		pushfd
		sgdt GdtrTable
		lea eax, [GdtrTable + 2]
		mov eax, [eax]
		//在0x90偏移处构建调用们
		lea eax, [eax + 0x94]
		mov ecx, FuncAddress      //0x77D517EA
		mov esi, ecx              //esi = 0x77D517EA					      
		and esi, 0xffff0000		 //esi = 0x77D50000
		add esi, 0xec00			//esi = 0x77D5ec00	
		mov[eax], esi
		lea eax, [eax - 4]
		and ecx, 0xffff
		add ecx, 0x00080000
		mov[eax], ecx
		popfd
		popad

	}

	return STATUS_SUCCESS;
}

VOID writefile() {
	OBJECT_ATTRIBUTES objectAttributes;
	IO_STATUS_BLOCK iostatus;
	HANDLE hFile;
	UNICODE_STRING logFileUnicodeString;
	//初始花unicode_string字符串
	RtlInitUnicodeString(&logFileUnicodeString, L"\\??\\C:\\1.txt");
	//初始化对象属性宏
	InitializeObjectAttributes(&objectAttributes, &logFileUnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL);
	NTSTATUS ntstatus = ZwCreateFile(&hFile, FILE_APPEND_DATA, &objectAttributes, &iostatus, NULL,
		FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
	UCHAR pBuffer[200] = { 0 };
	char* ProcessName = (char*)PsGetCurrentProcess() + 0x174;  //偏移0x174处,是fileImageName
	sprintf(pBuffer, "进程名称:%s HWND:%X Text:%s Caption:%s Type:%X \r\n", ProcessName, MessageHwnd,
		MessageString, MessageTitle, MessageSelect);
	KdPrint(("%s", pBuffer));
	ZwWriteFile(hFile, NULL, NULL, NULL, &iostatus, pBuffer, strlen(pBuffer), NULL, NULL);
	KdPrint(("The program really appended %d bytes\n", iostatus.Information));
	ZwClose(hFile);//关闭文件句柄
}

//建立中断门
VOID _declspec(naked) HookFunc() {
	__asm {
		pushad
		pushfd
		int 3
	}
	DbgPrint("%s", "HookFunc");
	_asm {
	//找到三环esp
		lea eax, [esp + 0x30]
		mov eax, [eax]
		//第一个参数
		mov ebx, eax
		lea eax, [ebx + 0x4]
		mov eax, [eax]
		mov [MessageHwnd], eax
		lea eax, [ebx + 0x8]
		mov eax, [eax]
		mov [MessageString], eax
		lea eax, [ebx + 0xc]
		mov eax, [eax]
		mov [MessageTitle], eax
		lea eax,[ebx+0x10]
		mov eax,[eax]
		mov [MessageSelect],eax
		
	}
	writefile();
	__asm {
		popfd
		popad
	}
	__asm {
		push 0x3b
		pop fs
		iretd
	}

}
BOOLEAN SetIntDoor(PVOID HookFunc) {
	__asm {
		pushad
		pushfd
			sidt LdtrTale
			mov eax,[LdtrTale+2]   //获取ldtr的地址
			add eax,0x100
			//构建调用们
			mov ebx,HookFunc
			mov esi,ebx
			//计算低四位
			and ebx,0xffff
			add ebx,0x00080000
			mov [eax],ebx
			//计算高四位
			and esi,0xffff0000
			add esi,0xee00
			add eax,0x4
			mov [eax],esi
		popfd
		popad
		
	}
	return STATUS_SUCCESS;

}


NTSTATUS DriverUnload(PDRIVER_OBJECT pDriver) {
	UNICODE_STRING symbolLink;
	RtlInitUnicodeString(&symbolLink, SYMBOLNAME);
	IoDeleteSymbolicLink(&symbolLink);
	IoDeleteDevice(pDriver->DeviceObject);
	KdPrint(("卸载成功"));
	return STATUS_SUCCESS;
}

NTSTATUS ChangePage(DEVICE_OBJECT* DeviceObject, IRP* Irp) {
	NTSTATUS status;
	PIO_STACK_LOCATION pIrpStack;
	ULONG uIoControlCode;
	PVOID pIoBuffer;
	ULONG InLength;
	ULONG OutLength;

	__asm {
		int 3
	}
	//获取IRP数据
	pIrpStack = IoGetCurrentIrpStackLocation(Irp);
	//获取控制码
	uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
	//获取缓冲区地址
	pIoBuffer = Irp->AssociatedIrp.SystemBuffer;
	//获取3环数据长度
	InLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
	//获取0环发送的数据长度
	OutLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
	PEPROCESS Process = 0;
	switch (uIoControlCode) {
	case StartHook:
		//获取三环发送过来的函数地址
		
		memcpy(&FuncAddress, pIoBuffer, 4);
		if (FuncAddress == 0) {
			KdPrint(("FuncAddress地址为0"));
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			return -1;
		}
		if (!Process) {
			
			if (NT_SUCCESS(FuncHook()) && NT_SUCCESS(SetIntDoor(HookFunc))){           //&& NT_SUCCESS(SetIntDoor(FuncAddress))
				*(int*)(pIoBuffer) = 1;
				Irp->IoStatus.Status = STATUS_SUCCESS;
				Irp->IoStatus.Information = 1;
				IoCompleteRequest(Irp, IO_NO_INCREMENT);
				return STATUS_SUCCESS;
			}
			else {
				KdPrint(("创建调用门失败"));
				Irp->IoStatus.Status = -1;
				Irp->IoStatus.Information = 0;
				IoCompleteRequest(Irp, IO_NO_INCREMENT);
				return -1;
			}
			
		}
		else
		{
			KdPrint(("没有获取到CR3或PID"));
			Irp->IoStatus.Status = -1;
			Irp->IoStatus.Information = 0;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			return -1;
		}

	}
	
}
NTSTATUS IrpCreate(DEVICE_OBJECT* DeviceObject, IRP* Irp) {
	KdPrint(("设备连接"));
	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;



}
NTSTATUS IrpClose(DEVICE_OBJECT* DeviceObject, IRP* Irp) {

	KdPrint(("设备断开"));
	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;



}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING Path) {
	//测试用函数
	


	NTSTATUS status;
	pDriver->DriverUnload = DriverUnload;

	UNICODE_STRING DeviceName;
	UNICODE_STRING SymbolName;
	DEVICE_OBJECT Device;
	//初始化设备对象名
	RtlInitUnicodeString(&SymbolName, SYMBOLNAME);
	RtlInitUnicodeString(&DeviceName, DEVICENAME);
	//创建符号链接
	status = IoCreateSymbolicLink(&SymbolName, &DeviceName);
	if (!NT_SUCCESS(status)) {
		KdPrint(("创建符号连接失败"));
		return status;
	}
	//创建设备对象
	status = IoCreateDevice(pDriver, NULL, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, &Device);
	if (!NT_SUCCESS(status)) {
		KdPrint(("创建设备对象失败"));
		return status;
	}
	//设置设备交互模式
	pDriver->Flags |= DO_BUFFERED_IO;
	//设置派遣函数
	pDriver->MajorFunction[IRP_MJ_CREATE] = IrpCreate;
	pDriver->MajorFunction[IRP_MJ_CLOSE] = IrpClose;
	pDriver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ChangePage;

	return STATUS_SUCCESS;
}

3、3环

#include "stdafx.h"
#include "resource.h"
#include <windows.h>
#include <WinIoCtl.h>
#define SYMBOLNAME L"\\\\.\\Hook"
#define IN_BUFFER_MAXLENGTH	            0x10		//输入缓存最大长度
#define OUT_BUFFER_MAXLENGTH	        0x4		//输出缓存最大长度
#define	StartHook CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define	StopHook CTL_CODE(FILE_DEVICE_UNKNOWN,0x900,METHOD_BUFFERED,FILE_ANY_ACCESS)

TCHAR szFilePath[MAX_PATH + 1]={0};
LPCWSTR SysName = L"\\FuncHook.sys";
LPCWSTR ServiceName = L"FuncHook";
HANDLE g_hDriver = 0;
DWORD FuncAddress = 0;
SC_HANDLE ScHandle = 0;
DWORD Start =0;
DWORD MessageBoxAddress  = 0;
DWORD HookFuncAddresss =0;
DWORD CR3get=0;

DWORD First = 0;
DWORD Second = 0;
DWORD Thirst = 0;
DWORD Foure = 0;

//构造调用门修改页表属性
void _declspec(naked) StartListen(){
	__asm{
		int 3
		pushad
		pushfd
			//改变messagebox的地址为write/read
			int 3
			mov eax,MessageBoxAddress
			mov esi,eax
			//chage PTE
			shr esi,0x12
			and esi,0x3FF8
			sub esi,0x3FA00000
			mov edx,[esi]
			or edx,0x3
			mov [esi],edx
			//change PDT
			shr eax,0x9
			and eax,0x7FFFF8
			add eax,0xc0000000
			mov edx,[eax]
			or edx,0x3
			mov [eax],edx
		/*	mov eax,cr3
			mov CR3,eax*/
		popfd
		popad
		retf
	}
}

//修改MessageBoxA的前两个字节为int 20

BOOL ChangeMeeageBoxA(){
	char * address = (char *)MessageBoxAddress;
	*(address) =0xcd;
	*(address+1)=0x20;
	if(*(address+1)!=0x20 && *(address)!=0xcd){
		return FALSE;
	}
	else{
		return TRUE;
	}

}

BOOL RecoverMessageBoxA(){
	char * address = (char *)MessageBoxAddress;
	*(address) =0x8b;
	*(address+1)=0xFF;
	if(*(address+1)!=0xFF && *(address)!=0x8b){
		return FALSE;
	}
	else{
		return TRUE;
	}

}

//void _declspec(naked) HookStart(){
//	__asm{
//		mov esi,cr3
//		mov edi,CR3get
//		mov cr3,edi     //
//		jmp HookFuncAddresss
//	}
//
//}
//void __declspec(naked) FuncHook(){
//	__asm{
//		push ebp
//		mov ebp,esp
//		push esi    //保存原来的CR3
//		pushad      //保存原来环境
//		pushfd
//		获取 参数 1
//		mov eax,[ebp+4]
//		mov First,eax
//		mov eax,[ebp+8]
//		mov Second,eax
//		mov eax,[ebp+0xc]
//		mov Thirst,eax
//		mov eax,[ebp+0x10]
//		mov Foure,eax
//		
//	}
//
//}
//打开驱动服务句柄
BOOL Open(LPCWSTR pLinkName){
	TCHAR szBuffer[10] ={0};
	g_hDriver = CreateFile(pLinkName,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
	if(g_hDriver ==INVALID_HANDLE_VALUE){
		DWORD error = ::GetLastError();
		wsprintf(szBuffer,L"打开服务句柄失败%d\n",error);
		MessageBox(0,szBuffer,0,0);
		CloseHandle(g_hDriver);
		return FALSE;
	}
	return TRUE;
}
//注册驱动服务

BOOL Register(){
		//获取驱动管理器
		ScHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
		if (ScHandle == NULL) {
			DWORD error = GetLastError();
		/*MessageBox(0, TEXT("获取服务管理器失败"), 0, 0);*/
			TCHAR ErrorMessage[0x30] = { 0 };
			wsprintf(ErrorMessage, TEXT("获取服务管理器失败:%x"), error);
			MessageBox(0,ErrorMessage,0,0);
			CloseServiceHandle(ScHandle);
			return FALSE;
		}
		//创建服务
		SC_HANDLE ScService = CreateService(ScHandle,ServiceName,ServiceName,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,szFilePath,NULL,NULL,NULL,NULL,NULL);
		if(ScService==NULL){
			DWORD error = GetLastError();
		if (error == ERROR_SERVICE_EXISTS) {
			CloseServiceHandle(ScService);

			return TRUE;
		}
		else {
			TCHAR ErrorMessage[0x30] = { 0 };
			wsprintf(ErrorMessage, TEXT("创建服务错误:%x"), error);
			MessageBox(0,ErrorMessage,0,0);
			CloseServiceHandle(ScService);
			CloseServiceHandle(ScHandle);
			return FALSE;
		}
	}
		CloseServiceHandle(ScService);
		return TRUE;	
}
//运行驱动
BOOL StartSys(){
	SC_HANDLE ServiceHandle = OpenService(ScHandle,ServiceName,SERVICE_ALL_ACCESS);
	if(ServiceHandle ==NULL){
		DWORD error = GetLastError();
		if (error == ERROR_SERVICE_DOES_NOT_EXIST) {
			TCHAR ErrorMessage[0x30] = { 0 };
			wsprintf(ErrorMessage, TEXT("服务已经不存在:%x"), error);
			MessageBox(0, ErrorMessage,0,0);
			CloseServiceHandle(ServiceHandle);
			
		}
		else {
			TCHAR ErrorMessage[0x30] = { 0 };
			wsprintf(ErrorMessage, TEXT("打开服务错误:%x"), error);
			MessageBox(0, ErrorMessage,0,0);
			CloseServiceHandle(ServiceHandle);
			
		}
		return FALSE;
	}
	if(!StartService(ServiceHandle,0,NULL)){
		DWORD error = GetLastError();
		if (error == ERROR_SERVICE_ALREADY_RUNNING)
		{
			return TRUE;
		}
		else
		{
			TCHAR ErrorMessage[0x30] = { 0 };
			wsprintf(ErrorMessage, TEXT("启动服务出错:%x"), error);
			MessageBox(0,ErrorMessage,0,0);
			CloseServiceHandle(ServiceHandle);
			return FALSE;
		}
	}
	return TRUE;
}
//停止驱动
BOOL StopSys(){
	SC_HANDLE serviceHandle = OpenService(ScHandle, ServiceName, SERVICE_ALL_ACCESS);
	if (serviceHandle == NULL) {
		DWORD error = GetLastError();
		if (error == ERROR_SERVICE_DOES_NOT_EXIST) {
			MessageBox(0,_T("服务已不存在"),0,0);
			CloseServiceHandle(serviceHandle);
		
		}
		else {
			TCHAR ErrorMessage[0x30] = { 0 };
			wsprintf(ErrorMessage, TEXT("打开服务错误:%x"), error);
			MessageBox(0,ErrorMessage,0,0);
			CloseServiceHandle(serviceHandle);
		}
		return FALSE;
	}
	SERVICE_STATUS error = {0};
	if(!ControlService(serviceHandle,SERVICE_CONTROL_STOP,&error)){
		DWORD errorCode = GetLastError();
		if (errorCode == ERROR_SERVICE_NOT_ACTIVE)
		{	
			CloseServiceHandle(serviceHandle);
			return TRUE;
		}
		else
		{
			TCHAR ErrorMessage[0x30] = { 0 };
			wsprintf(ErrorMessage, TEXT("停止驱动出错:%x"), errorCode);
			MessageBox(0,ErrorMessage,0,0);
			CloseServiceHandle(serviceHandle);
			return FALSE;
		}
	
	}
	SERVICE_STATUS status;
	QueryServiceStatus(serviceHandle,&status);
	if(status.dwCurrentState ==SERVICE_STOP_PENDING){
		DWORD dwWaitTime = status.dwWaitHint/10;
		if(dwWaitTime<1000){
			dwWaitTime=1000;
		}
		else if(dwWaitTime>10000){
			dwWaitTime=10000;
		}
		Sleep(dwWaitTime);
	}
	if(QueryServiceStatus(serviceHandle,&status)){
		if(status.dwCurrentState ==SERVICE_STOPPED){
				CloseServiceHandle(serviceHandle);
		}
	}
	CloseServiceHandle(serviceHandle);
	return TRUE;
}
//卸载驱动
BOOL DeleteSys(){
	SC_HANDLE serviceHandle = OpenService(ScHandle,ServiceName,SERVICE_ALL_ACCESS);
	if (serviceHandle == NULL) {
		DWORD error = GetLastError();
		if (error != ERROR_SERVICE_DOES_NOT_EXIST) {
			TCHAR ErrorMessage[0x30] = { 0 };
			wsprintf(ErrorMessage, TEXT("打开服务错误:%x"), error);
			MessageBox(0,ErrorMessage,0,0);
			CloseServiceHandle(serviceHandle);
			CloseServiceHandle(ScHandle);
			return FALSE;
		}
		
	}
	if (!DeleteService(serviceHandle) ){
		DWORD error = GetLastError();
			TCHAR ErrorMessage[0x30] = { 0 };
			wsprintf(ErrorMessage, TEXT("卸载驱动出错:%x"), error);
			MessageBox(0,ErrorMessage,0,0);
			CloseServiceHandle(serviceHandle);
			CloseServiceHandle(ScHandle);
			return FALSE;	
	}
	SERVICE_STATUS status;
	QueryServiceStatus(serviceHandle,&status);
	
	CloseServiceHandle(serviceHandle);
	CloseServiceHandle(ScHandle);
	ScHandle = NULL;
	return TRUE;
	
}
BOOL IoControl(DWORD dwIoCode,PVOID InBuffer,DWORD InBufferLength,PVOID OutBuffer,DWORD OutBufferLength){
	DWORD dw;
	DeviceIoControl(g_hDriver,dwIoCode,InBuffer,InBufferLength,OutBuffer,OutBufferLength,&dw,NULL);
	return TRUE;
}

INT_PTR CALLBACK  DiagBoxCallBackProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	switch (uMsg)
	{
	case WM_CLOSE: {
		
		if(Start){
			RecoverMessageBoxA();
			StopSys();
			DeleteSys();
			
		}
		EndDialog(hwnd,0);
		return TRUE;
	}
	case WM_COMMAND: {
		switch (LOWORD(wParam))
		{
		case IDC_START:{
			DWORD selcet = MessageBoxA(0,"开始监控?",0,MB_OKCANCEL);
			if(selcet == IDCANCEL){
				return TRUE;
			}
			
			DWORD out = 0;
			if(Register()){
				if(StartSys()){
					Open(SYMBOLNAME);

					IoControl(StartHook,&FuncAddress,IN_BUFFER_MAXLENGTH,&out,OUT_BUFFER_MAXLENGTH);			
					if(out ==1){
						Start = 1;
						CHAR CallAddress[] = {0x00,0x00,0x00,0x00,0x93,0x00};
						__asm{
							call fword ptr ds:[CallAddress]
							push 0x3b
							pop fs
						}
						if(!ChangeMeeageBoxA()){
							MessageBox(0,_T("修改MessageBoxA内容失败"),0,0);
						}
						MessageBoxA(0,"hello",0,0);
						//Hook MessageBoxA
						
					}
				}
			}
			return TRUE;
		}
		case IDC_STOP:
			
			if(Start ==1){
				RecoverMessageBoxA();
				StopSys();
				DeleteSys();
				Start=0;
				
			}
			return TRUE;
	}
	default:
		return FALSE;
		break;
	}
	return FALSE;	
	}
}

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
	_In_ LPWSTR    lpCmdLine, _In_ int       nCmdShow)
{

	GetCurrentDirectory(MAX_PATH,szFilePath);
	//拼接成驱动的路径

	lstrcatW(szFilePath,SysName);
	DWORD JmpAddress = (DWORD)StartListen;      //0x000322e9         E9 22 03 00 00
	DWORD Offset_W = (*(int*)((char*)JmpAddress+1));    //0x00 00 03 22     

	//*dword offset  = ((offset_w&0x000000ff)<<24)+((offset_w&0x0000ff00)<<8)+((offset_w&0x00ff0000)>>8)+((0xff000000&offset_w)>>24);*/
	FuncAddress = JmpAddress+5+Offset_W;
	
	MessageBoxAddress = (DWORD)&MessageBoxA;
	
	CHAR LDTR[6]={0};
	
	HookFuncAddresss = (DWORD)VirtualAlloc(NULL,0x1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	DialogBox(hInstance,MAKEINTRESOURCE(IDD_MAIN),0,DiagBoxCallBackProc);

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值