Win10 X64 HOOK KiUserExceptionDispatcher

Win10 X64 HOOK KiUserExceptionDispatcher

HOOK.ASM

extrn NewKiUserExceptionDispatcher : proc 
extrn OrgKiUserExceptionDispatcher : proc  
extrn OldKiUserExceptionDispatcher : proc 
.data
.code


;hook 
public MyKiUserExceptionDispatcher

MyKiUserExceptionDispatcher PROC  
    mov   rcx, rsp 
    add  rcx,4F0h
    mov   rdx,rsp  
    call  NewKiUserExceptionDispatcher ;先经过我们自己的异常处理

    ;mov rax,[OldKiUserExceptionDispatcher]  ;这样跳转回去会异常 原因未知
    ;jmp rax 

    ;
    mov   rax, [OrgKiUserExceptionDispatcher] ;直接用原函数+偏移 跳到RtlDispatchException 这样可以
    mov   rax,[rax]
    add   rax ,1ch
    jmp   rax; RtlDispatchException
    ret
MyKiUserExceptionDispatcher ENDP

END

HOOKFUC.H

#pragma once
#include <windows.h>

typedef VOID(WINAPI* PtrKiUserExceptionDispatcher)();
namespace HookEmu {
	//extern "C" C形式导出
	extern "C" PtrKiUserExceptionDispatcher OrgKiUserExceptionDispatcher;
	extern "C" PtrKiUserExceptionDispatcher OldKiUserExceptionDispatcher;
	extern HMODULE hNtDll ;
	
}
 

namespace HookFunction {
	 extern VOID HookKi();

}

namespace KiuserExc
{
	extern "C" void MyKiUserExceptionDispatcher();//汇编导出
	extern "C" void   NewKiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord, PCONTEXT  Context);
}
namespace VEH_Tess
{
	extern LONG __stdcall VEHandler(
		EXCEPTION_POINTERS* ExceptionInfo
	);
	extern void InitVeh();
}


namespace HelpFuc {

	static VOID StackTrace64(PCONTEXT  Context);
}

HOOKFUC.CPP

#include "hookFun.h"
#include "MinHook.h"
#include <stdio.h>
namespace HookEmu {
	PtrKiUserExceptionDispatcher OrgKiUserExceptionDispatcher = 0;
	HMODULE hNtDll = NULL;
	PtrKiUserExceptionDispatcher OldKiUserExceptionDispatcher = nullptr;
}
namespace HookFunction {

	  VOID HookKi()
	{
		printf("ADDRESS:%llx", &KiuserExc::MyKiUserExceptionDispatcher);
		HookEmu::hNtDll = GetModuleHandleA("Ntdll.dll");
		HookEmu::OrgKiUserExceptionDispatcher = (PtrKiUserExceptionDispatcher)GetProcAddress(HookEmu::hNtDll, "KiUserExceptionDispatcher");


		if (MH_Initialize() == MH_OK)
		{
			if (MH_OK == MH_CreateHook(HookEmu::OrgKiUserExceptionDispatcher, (DWORD64*)&KiuserExc::MyKiUserExceptionDispatcher, reinterpret_cast<void**>(&HookEmu::OldKiUserExceptionDispatcher)))
			{
				if (MH_OK == MH_EnableHook(HookEmu::OrgKiUserExceptionDispatcher))
				{
					printf("钩子安装成功!\n");
				}
			}
		}
		return;
	}
}

namespace KiuserExc {

	void   NewKiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord, PCONTEXT  Context)
	{
		printf(":HK\n");
		if (Context)
		{
			//HelpFuc::StackTrace64(Context);
			if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS)
			{
				printf(":HK\n");

				// Now each Thread handle should have its own CONTEXT.
				/*BeckupHardwareBP[CurrOffset].Dr0 = Context->Dr0;
				BeckupHardwareBP[CurrOffset].Dr1 = Context->Dr1;
				BeckupHardwareBP[CurrOffset].Dr2 = Context->Dr2;
				BeckupHardwareBP[CurrOffset].Dr3 = Context->Dr3;
				BeckupHardwareBP[CurrOffset].Dr6 = Context->Dr6;
				BeckupHardwareBP[CurrOffset].Dr7 = Context->Dr7;
	*/

				Context->Dr0 = 0;
				Context->Dr1 = 0;
				Context->Dr2 = 0;
				Context->Dr3 = 0;
				Context->Dr6 = 0;
				Context->Dr7 = 0;
				//Context->Rip += 1;
			}
		}
	}
}
namespace  VEH_Tess
{
	LONG __stdcall VEHandler(
		EXCEPTION_POINTERS* ExceptionInfo
	)
	{
		ExceptionInfo->ContextRecord->Rip += 1;
		printf("VEH 异常将被忽略 发生地址:%p RAX:0x%016I64x RCX:0x%016I64x RDX:0x%016I64x R8:0x%016I64x  R9:0x%016I64x\n", ExceptionInfo->ContextRecord->Rip, ExceptionInfo->ContextRecord->Rax, ExceptionInfo->ContextRecord->Rcx, ExceptionInfo->ContextRecord->Rdx, ExceptionInfo->ContextRecord->R8, ExceptionInfo->ContextRecord->R9);

		return EXCEPTION_CONTINUE_EXECUTION;//忽略异常=什么都没发生 try块当然也无法捕获到
	}


	void InitVeh()
	{
		AddVectoredExceptionHandler(1, VEHandler);//正常的监视全局异常
	}
}


namespace HelpFuc
{
	static VOID StackTrace64(PCONTEXT  Context)
	{

		KNONVOLATILE_CONTEXT_POINTERS NvContext;
		UNWIND_HISTORY_TABLE          UnwindHistoryTable;
		PRUNTIME_FUNCTION             RuntimeFunction;
		PVOID                         HandlerData;
		ULONG64                       EstablisherFrame;
		ULONG64                       ImageBase;

		RtlZeroMemory(
			&UnwindHistoryTable,
			sizeof(UNWIND_HISTORY_TABLE));

		RuntimeFunction = RtlLookupFunctionEntry(
			Context->Rip,
			&ImageBase,
			&UnwindHistoryTable
		);

		RtlZeroMemory(
			&NvContext,
			sizeof(KNONVOLATILE_CONTEXT_POINTERS));

		if (!RuntimeFunction)
		{
			printf("Rip:%llx\n", Context->Rip);
			Context->Rip = (ULONG64)(*(PULONG64)Context->Rsp);
			printf("new Rip:%llx\n", Context->Rip);
			Context->Rsp += 8;
			printf("RSP+=8\n");
		}
		else
		{
			RtlVirtualUnwind(
				UNW_FLAG_EHANDLER,
				ImageBase,
				Context->Rip,
				RuntimeFunction,
				Context,
				&HandlerData,
				&EstablisherFrame,
				&NvContext);
		}

		printf("ret Rip:%llx\n", Context->Rip);
		return;
	}
}

MAIN.CPP


#include <iostream>
#include "hookFun.h"
#include "MinHook.h"
 



void func(int cc) {

    __debugbreak();
	printf("func ok\n");
}

int main()
{ 
    VEH_Tess::InitVeh();
    HookFunction::HookKi();
    while(1){
        func(11);
        getchar();
    }
	printf("********************\n");
    getchar();

     
}
 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
一:SSDT表的hook检测和恢复 ~!~~~ 二:IDT表的hook检测和恢复 ~~~~~~(idt多处理器的恢复没处理,自己机器是单核的,没得搞,不过多核的列举可以) 三:系统加载驱动模块的检测 通过使用一个全局hash表(以DRIVEROBJECT为对象)来使用以下的方法来存储得到的结果,最终显示出来 1.常规的ZwQuerySystemInformation来列举 2通过打开驱动对象目录来列举 3搜索内核空间匹配驱动的特征来列举(这个功能里面我自己的主机一运行就死机,别的机器都没事,手动设置热键来蓝屏都不行,没dump没法分析,哎,郁闷) 4从本驱动的Modulelist开始遍历来列举驱动 四:进程的列举和进程所加载的dll检测 采用以下方法来列举进程: 1ZwQuerySystemInformation参数SystemProcessesAndThreadsInformation来枚举 2进程EPROCESS 结构的Activelist遍历来枚举 3通过解析句柄表来枚举进程 4通过Handletablelisthead枚举进程 5进程创建时都会向csrss来注册,从这个进程里面句柄表来枚举进程 6通过自身进程的HANDLETABLE来枚举进程 7通过EPROCESS的SessionProcessLinks来枚举进程 8通过EPROCESS ---VM---WorkingSetExpansionLinks获取进程 9暴力搜索内存MmSystemRangeStart以上查找PROCESS对象 进程操作: 进程的唤醒和暂停通过获取PsSuspendProcess和PsResumeProcess来操作的 进程结束通过进程空间清0和插入apc。 采用以下方法查找DLL: 1遍历VAD来查找dll 2挂靠到对应的进程查找InLoadOrderLinks来枚举dll 3暴力搜索对应进程空间查找pe特征来枚举dll DLL的操作: Dll的卸载是通过MmUnmapViewOfSection和MmmapViewOfSection(从sdt表中相应函数搜索到的)来实现的(本来想直接清0 dll空间,有时行有时不行)(只要将这个进程的ntdll卸载了,进程就结束了,一个好的杀进程的办法撒,绿色环保无污染),注入dll使用的是插入apc实现的。(注入的dll必须是realse版的。Debug版会出现***错误,全局dll注入貌似也是)插入apc效果不是很好,要有线程有告警状态才执行。 五:线程信息的检测 遍历ThreadList来枚举线程 线程的暂停和唤醒都是通过反汇编获取PsResumeThread和PsSuspendThread直接从r3传来ETHREAD来操作的,通过插入APC来结束线程 六:shadow sdt表的hook检测与恢复 没有采用pdb来解决函数名问题,直接写入xp和03的shandow表函数名(主要是自己的网不稳定,连windbg有时都连不上微软) 七:系统所有的过滤驱动的检测 查看各device下是否挂接有驱动之类的,可直接卸载 八:系统常用回调历程的检测和清除 只检查了PsSetLoadImageNotifyRoutine PsSetCreateThreadNotifyRoutine PsSetCreateProcessNotifyRoutine CmRegisterCallback这几个,至于那个什么shutdown回调不知道是啥玩意,就没搞了,有知道的顺便告诉我下撒,谢谢 九:文件系统fat和ntfs的分发函数检测 直接反汇编fat和ntfs的DriverEntry得到对应的填充分发的偏移,然后和当前已经运行的文件系统的分发相比是否被hook,并附带恢复 十:文件查看功能 自己解析ntfs和fat的结构,来实现列举文件和直接写磁盘删除。附带有普通的删除和发生IRP来删除。不过这里面有点问题,ntfs删除有时把目录给搞坏了,大家凑合着吧, Ntfs网上删除这些操作的代码不多,就是sudami大大的利用ntfs-3g来实现的,看了下,太多了,充满了结构。然后自己对照着系统删除文件时目录的变化来自己实现的。只处理了$BITMAP对应的位清除,父目录的对应文件的索引项的覆盖,删除文件对应的filerecord清0. 另外偷懒时间都没处理,呵呵,y的,一个破时间都都搞好几个字节移来移去的。 十一:常用内核模块钩子的检测和恢复 这里只检测了主要的内核模块nkrnlpa**.exe的.win32k.sys,hal.dll,比对它们的原始文件从而查找eat inline hook,iat hook ,和inline hook。Inline是从TEXT段开始一段位置开始比较的。(有点慢貌似,等待显示扫描完成就好了) 十二:应用层进程所加载dll的钩子 应用层钩子检测和内核模块钩子检测原理一样,不过为了能读写别的进程的空间,并没有使用openprocess去打开进程,而是通过KiattachProcess挂靠到当前进程,然后通过在r0直接读写进程空间的。
x64 Inline Hook(内联钩子)是一种在x64架构下实现的钩子技术,用于在程序运行时对函数进行修改或者监控。钩子技术可以用于实现一些高级功能,如函数拦截、行为修改和调试等。 Inline Hook的主要原理是通过修改函数的机器码,将目标函数的执行流程改变到一个特定的钩子函数,从而实现我们所需的功能。这个钩子函数可以进行一系列的操作,如记录参数、修改参数、替换返回值等。 x64 Inline Hook实现相对复杂,因为x64架构下的指令集更加复杂,并且x64架构引入了新的寄存器和指令,如RAX、R10、R11,还有新的调用惯例等。因此,在实现x64 Inline Hook前,我们需要对x64汇编指令和调用惯例有深入的了解。 具体实现Inline Hook主要包括以下几个步骤: 1. 定位到目标函数的地址。可以通过符号表、导入表或者动态调试等方式获取目标函数的地址。 2. 备份目标函数的原始字节码。为了在后续操作中恢复目标函数的完整执行流程,我们需要保留原始字节码。 3. 修改目标函数的字节码。通过修改目标函数的机器码,将执行流程转移到我们的钩子函数。 4. 编写钩子函数。钩子函数的参数和返回值需要与目标函数保持一致,并实现所需的功能。 5. 恢复目标函数的原始字节码。在钩子函数执行完毕后,需要将目标函数的字节码恢复到原始状态,以确保程序正常运行。 6. 跳回目标函数。在钩子函数执行完成后,我们需要将执行流程跳转回原始的目标函数。 需要注意的是,Inline Hook的实现需要考虑到多线程的情况,并且要保证对内存的修改是线程安全的,以及在恢复原始字节码时要避免潜在的问题。 总的来说,x64 Inline Hook是一种强大的技术,可以用于实现程序的函数修改和监控等高级功能。但它的实现相对复杂,需要对x64架构和汇编指令有深入的理解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值