1. FF 25 JMP 在EPTFake页是不是不可信 使用会直接不触发代码 BSOD
VOID
EptHookWriteAbsoluteJumpPure(PCHAR TargetBuffer, SIZE_T TargetAddress)
{
TargetBuffer[0] = 0x48; // mov rax, imm64
TargetBuffer[1] = 0xB8;
*(PSIZE_T)(TargetBuffer + 2) = TargetAddress;
TargetBuffer[10] = 0xFF; // jmp rax
TargetBuffer[11] = 0xE0;
}
VOID
EptHookWriteAbsoluteJumpPure1(PCHAR TargetBuffer, SIZE_T TargetAddress)
{
// jmp qword ptr [rip+0]
TargetBuffer[0] = 0xFF;
TargetBuffer[1] = 0x25;
TargetBuffer[2] = 0x00; // offset low
TargetBuffer[3] = 0x00; // offset high
TargetBuffer[4] = 0x00;
TargetBuffer[5] = 0x00;
// 64-bit target address (will be read by jmp)
*(SIZE_T *)&TargetBuffer[6] = TargetAddress;
}2.
```
!HYPER_CALL[GBDS] FFFFB50B18B16100 0000000000000000 0000000000000000 IRQL: 0
!HYPER_CALL[0000] 0000000000000000 0000000000000000 0000000000000000 IRQL: 0
VmxGetCurrentExecutionMode 1
FFFFF80115600000 ->ntOsKernl
FFFFF80115CA4230 ->lpObpReferenceObjectByHandleWithTag
0000000000000000 ObpReferenceObjectByHandleWithTagHook->Trampoline
FFFFB50B195B5610 lpHooked->Trampoline
44 88 4C 24 20 4C 89 44 24 18 89 54 24 10 48 B8 3E 42 CA 15 01 F8 FF FF FF E0 00 00 00 00 00 00 ObpReferenceObjectByHandleWithTagHOOK xxx! FFFFB50B195B5610
ObpReferenceObjectByHandleWithTagHOOK xxx! FFFFB50B195B5610
Handle: 0000000000000208, ObjectType: FFFFB50B136C47A0 0000000000000001 0000000000000001 FFFFF603A01629F0 0000000000000000
<-SYSTEM REBOOT 直接系统重启了 都没有BSOD
```
int called= 0;
extern PVOID lastHooked;
PVOID
ObpReferenceObjectByHandleWithTagHook(
HANDLE Handle, //
ACCESS_MASK DesiredAccess, // rdx
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode, // r9 K=0 U=1
ULONG _x746C6644,
PVOID * Object,
POBJECT_HANDLE_INFORMATION HandleInformation,
PVOID ZeroBit)
{
DesiredAccess &= 0xFFFFFFFF;
AccessMode &= 0xFFFFFFFF;
_x746C6644 &= 0xFFFFFFFF;
Log("ObpReferenceObjectByHandleWithTagHOOK xxx! %p\n", ObpReferenceObjectByHandleWithTagOrig);
Log("Handle: %p, ObjectType: %p %p %p %p %p\n", Handle, ObjectType, AccessMode, DesiredAccess, Object, HandleInformation);
if (!ObpReferenceObjectByHandleWithTagOrig)
{
*(PVOID *)&ObpReferenceObjectByHandleWithTagOrig = lastHooked;
Log("+ObpReferenceObjectByHandleHook called! %p\n", ObpReferenceObjectByHandleWithTagOrig);
}
//UNREFERENCED_PARAMETER
auto Status = ((NTSTATUS(*)(HANDLE, ACCESS_MASK, POBJECT_TYPE, KPROCESSOR_MODE, ULONG, PVOID *, POBJECT_HANDLE_INFORMATION, PVOID))
ObpReferenceObjectByHandleWithTagOrig)(
Handle,
DesiredAccess,
ObjectType,
AccessMode,
_x746C6644,
Object,
HandleInformation,
ZeroBit);
Log("+Status called! %X\n", Status); // !!!!!!!!!!!!这里不会触发 是不是trampoline的问题
if (1)
return (PVOID)Status;
BOOLEAN bCallFromUs = IsDebugger(PsGetCurrentProcess());
if (NT_SUCCESS(Status) && (ObjectType == *PsProcessType))
{
// 判断当前调用者是否是调试器进程
if (!bCallFromUs)
{
// 判断访问的对象是否是我们的调试器
if (Object && IsDebugger(*(PEPROCESS *)Object))
{
Status = STATUS_UNSUCCESSFUL;
Log("[+]Removed called! %p\n", *(PEPROCESS *)Object);
*(PEPROCESS *)Object = NULL;
}
}
else
{
Log("ObpReferenceObjectByHandleHook called! %p\n", ObReferenceObjectByHandleOrig);
Log("Handle: %p, ObjectType: %p %p %p %p %p\n", Handle, ObjectType, AccessMode, DesiredAccess, Object, HandleInformation);
}
}
return (PVOID)Status;
}
BOOLEAN
EptHookInstructionMemory1(PEPT_HOOKED_PAGE_DETAIL Hook,
CR3_TYPE ProcessCr3,
PVOID TargetFunction,
PVOID TargetFunctionInSafeMemory,
PVOID HookFunction)
{
PHIDDEN_HOOKS_DETOUR_DETAILS DetourHookDetails;
SIZE_T SizeOfHookedInstructions;
SIZE_T OffsetIntoPage;
CR3_TYPE Cr3OfCurrentProcess;
//
// 获取目标函数在页内的偏移
//
OffsetIntoPage = ADDRMASK_EPT_PML1_OFFSET((SIZE_T)TargetFunction);
//
// 检查函数是否跨页(不支持跨页 Hook)
//
if ((OffsetIntoPage + 19) > PAGE_SIZE - 1)
{
LogError("Err, function extends past a page boundary");
return FALSE;
}
//
// 计算需要覆盖的指令长度(使用 LDE / Length Disassembler Engine)
// EPTHOOK2 仅支持 64-bit kernel
//
for (SizeOfHookedInstructions = 0;
SizeOfHookedInstructions < 12;
SizeOfHookedInstructions += DisassemblerLengthDisassembleEngineInVmxRootOnTargetProcess(
(PVOID)((UINT64)TargetFunctionInSafeMemory + SizeOfHookedInstructions),
FALSE))
{
// 循环累加指令长度,直到覆盖至少 12 字节
}
//
// 为 trampoline 分配可执行内存
//
Hook->Trampoline = (CHAR *)PoolManagerRequestPool(EXEC_TRAMPOLINE, TRUE, MAX_EXEC_TRAMPOLINE_SIZE);
if (!Hook->Trampoline)
{
LogError("Err, could not allocate trampoline function buffer");
return FALSE;
}
//
// 切换到目标进程的地址空间,读取原函数指令到 trampoline
//
Cr3OfCurrentProcess = SwitchToProcessMemoryLayoutByCr3(ProcessCr3);
//
// 安全读取内存内容(不能直接 RtlCopyMemory,因为可能是用户空间地址)
//
MemoryMapperReadMemorySafe((UINT64)TargetFunction, Hook->Trampoline, SizeOfHookedInstructions);
//
// 恢复原进程 CR3
//
SwitchToPreviousProcess(Cr3OfCurrentProcess);
//
// 在 trampoline 尾部添加绝对跳转,跳回原函数剩余指令
//
//EptHookWriteAbsoluteJump2(&Hook->Trampoline[SizeOfHookedInstructions], (SIZE_T)TargetFunction + SizeOfHookedInstructions);
EptHookWriteAbsoluteJumpPure(&Hook->Trampoline[SizeOfHookedInstructions], (SIZE_T)TargetFunction + SizeOfHookedInstructions);
lastHooked = (PVOID)Hook->Trampoline;
//
// 构建调试器 / Hook 返回结构 DetourHookDetails
//
DetourHookDetails = (HIDDEN_HOOKS_DETOUR_DETAILS *)PoolManagerRequestPool(DETOUR_HOOK_DETAILS, TRUE, sizeof(HIDDEN_HOOKS_DETOUR_DETAILS));
DetourHookDetails->HookedFunctionAddress = TargetFunction; // 原函数地址
DetourHookDetails->ReturnAddress = Hook->Trampoline; // Trampoline 地址(原函数可调用)
//
// 保存 DetourHookDetails 地址到 Hook 结构,用于后续释放
//
Hook->AddressOfEptHook2sDetourListEntry = (UINT64)DetourHookDetails;
//
// 插入到全局 Hook 列表
//
InsertHeadList(&g_EptHook2sDetourListHead, &(DetourHookDetails->OtherHooksList));
//
// 在伪造页内写入跳转到 Hook 函数
// 当 CPU 执行到 FakePage 时触发 VMCALL 或 VMExit 进入 Hook
//
//EptHookWriteAbsoluteJump2(&Hook->FakePageContents[OffsetIntoPage], (SIZE_T)HookFunction);
EptHookWriteAbsoluteJumpPure(&Hook->FakePageContents[OffsetIntoPage], (SIZE_T)HookFunction);
return TRUE; // Hook 成功
}A func -> AEx Func
这种情况 EPT Hook A -> 自己的Func调用AEx 这种不设计tramp的都是不会失败
想不通问题了 故请教
传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!