前段时间看到有人问了这个问题,自己也去看了下
很简单,IDA看下AddVectoredExceptionHandler就出来了
如果是想外部进程获取的话,
搜索下LdrpVectorHandlerList变量,再外部实现RtlDecodePointer解密就行了
下面代码是自身进程的检测
#include <stdio.h>
#include <Windows.h>
LONG WINAPI VectoredHandler1(struct _EXCEPTION_POINTERS* ExceptionInfo)
{
ULONG code = ExceptionInfo->ExceptionRecord->ExceptionCode;
ULONG_PTR address = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
return 0;//不处理,返回让下一个异常函数处理
}
LONG WINAPI VectoredHandler2(struct _EXCEPTION_POINTERS* ExceptionInfo)
{
ULONG code = ExceptionInfo->ExceptionRecord->ExceptionCode;
ULONG_PTR address = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
return 1;//这里随便返回个1,防止VectoredHandler2跟VectoredHandler1优化成了一个函数
}
LONG WINAPI VectoredHandler3(struct _EXCEPTION_POINTERS* ExceptionInfo)
{
ULONG code = ExceptionInfo->ExceptionRecord->ExceptionCode;
ULONG_PTR address = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
return 2;//这里随便返回个2,正常程序别这样返回就行了
}
int main()
{
LIST_ENTRY* ExceptionHandler = (LIST_ENTRY*)AddVectoredExceptionHandler(1, VectoredHandler1);
LIST_ENTRY* ExceptionHandler2 = (LIST_ENTRY*)AddVectoredExceptionHandler(1, VectoredHandler2);
ULONG64(WINAPI * RtlEncodePointer)(PVOID a1);
ULONG64(WINAPI * RtlDecodePointer)(PVOID a1);
(FARPROC&)RtlEncodePointer = GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlEncodePointer");
(FARPROC&)RtlDecodePointer = GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlDecodePointer");
printf("VectoredHandler1=%p,%p\n", ExceptionHandler,VectoredHandler1);//
printf("VectoredHandler2=%p,%p\n", ExceptionHandler2,VectoredHandler2);
printf("VectoredHandler3=%p\n", VectoredHandler3);
printf("----HOOK前的VEH----\n");
//遍历VEH
LIST_ENTRY* curNode = ExceptionHandler;
do
{
ULONG64 FuncAdd = RtlDecodePointer(((ULONG64**)curNode)[0x20 / 8]);
//系统不一样,这里的偏移不意义,我所知道的,1803函数偏移在0x18
//我当前22H2以及WIN11都是0x20
printf("FuncAdd=%p,%p\n", curNode, FuncAdd);
curNode = (LIST_ENTRY * )curNode->Flink;
} while (curNode!= ExceptionHandler);
//hook ExceptionHandler的处理函数VectoredHandler2->VectoredHandler3
printf("----HOOK中----\n");
curNode = ExceptionHandler;
do
{
ULONG64 FuncAdd = RtlDecodePointer(((ULONG64**)curNode)[0x20 / 8]);
//系统不一样,这里的偏移不意义,我所知道的,1803函数偏移在0x18
//我当前22H2以及WIN11都是0x20
//
if (FuncAdd==(ULONG64)VectoredHandler2)
{
((ULONG64**)curNode)[0x20 / 8] = (ULONG64*)RtlEncodePointer(VectoredHandler3);
printf("HookFuncAdd=%p-->%p\n", FuncAdd, VectoredHandler3);
break;
}
curNode = (LIST_ENTRY*)curNode->Flink;
} while (curNode != ExceptionHandler);
printf("----HOOK后的VEH----\n");
curNode = ExceptionHandler;
do
{
ULONG64 FuncAdd = RtlDecodePointer(((ULONG64**)curNode)[0x20 / 8]);
//系统不一样,这里的偏移不意义,我所知道的,1803函数偏移在0x18
//我当前22H2以及WIN11都是0x20
printf("FuncAdd=%p,%p\n", curNode, FuncAdd);
curNode = (LIST_ENTRY*)curNode->Flink;
} while (curNode != ExceptionHandler);
getchar();
}
执行结果
VectoredHandler1=0000018A6199C800,00007FF76DA81070
VectoredHandler2=0000018A6199C770,00007FF76DA81080
VectoredHandler3=00007FF76DA81090
----HOOK前的VEH----
FuncAdd=0000018A6199C800,00007FF76DA81070
FuncAdd=00007FF9078913F0,89140800279C636F
FuncAdd=0000018A6199C770,00007FF76DA81080
----HOOK中----
HookFuncAdd=00007FF76DA81080-->00007FF76DA81090
----HOOK后的VEH----
FuncAdd=0000018A6199C800,00007FF76DA81070
FuncAdd=00007FF9078913F0,89140800279C636F
FuncAdd=0000018A6199C770,00007FF76DA81090
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课