;
; Points the stack pointer at the supplied argument and returns to the caller.
;
public AdjustStackCallPointer
AdjustStackCallPointer PROC
mov rsp, rcx
xchg r8, rcx
jmp rdx
AdjustStackCallPointer ENDP
// Both of these routines reference the assembly code described above
extern VOID OrigKeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR
BugCheckParameter4);
extern VOID AdjustStackCallPointer(IN ULONG_PTR NewStackPointer, IN PVOID StartAddress, IN PVOID Argument);
// The offset into the ETHREAD structure that holds the start routine.
static ULONG ThreadStartRoutineOffset = 0;
// The pointer into KeBugCheckEx after what has been overwritten by the hook.
PVOID OrigKeBugCheckExRestorePointer;
VOID KeBugCheckExHook(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
{
PUCHAR LockedAddress;
PCHAR ReturnAddress;
PMDL Mdl = NULL;
// Call the real KeBugCheckEx if this isn't the bug check code we're looking for.
if (BugCheckCode != 0x109)
{
//DebugPrint(("Passing through bug check %.4x to %p.", BugCheckCode, OrigKeBugCheckEx));
OrigKeBugCheckEx(BugCheckCode, BugCheckParameter1, BugCheckParameter2, BugCheckParameter3, BugCheckParameter4);
}
else
{
PCHAR CurrentThread = (PCHAR)PsGetCurrentThread();
PVOID StartRoutine = *(PVOID **)(CurrentThread + ThreadStartRoutineOffset);
PVOID StackPointer = IoGetInitialStack();
//DebugPrint(("Restarting the current worker thread %p at %p (SP=%p, off=%lu).", PsGetCurrentThread(), StartRoutine, StackPointer, ThreadStartRoutineOffset));
DbgPrint("拦截了0x109号蓝屏\n");
DbgPrint("Restarting the current worker thread %p at %p (SP=%p, off=%lu).\n", PsGetCurrentThread(), StartRoutine, StackPointer, ThreadStartRoutineOffset);
// Shift the stack pointer back to its initial value and call the routine.
//We subtract eight to ensure that the stack is aligned properly as thread entry point routines would expect.
AdjustStackCallPointer((ULONG_PTR)StackPointer - 0x8, StartRoutine, NULL);
}
// In either case, we should never get here.
__debugbreak();
}
VOID DisablePatchProtectionSystemThreadRoutine(IN PVOID Nothing)
{
UNICODE_STRING SymbolName;
NTSTATUS Status = STATUS_SUCCESS;
PUCHAR LockedAddress;
PUCHAR CurrentThread = (PUCHAR)PsGetCurrentThread();
PCHAR KeBugCheckExSymbol;
PMDL Mdl = NULL;
do
{
// Find the thread's start routine offset.
for (ThreadStartRoutineOffset = 0; ThreadStartRoutineOffset < 0x1000; ThreadStartRoutineOffset += 4)
{
//DisablePatchProtection2SystemThreadRoutine
if (*(PVOID **)(CurrentThread + ThreadStartRoutineOffset) == (PVOID)DisablePatchProtectionSystemThreadRoutine) {
break;
}
}
//DebugPrint(("Thread start routine offset is 0x%.4x.", ThreadStartRoutineOffset));
// If we failed to find the start routine offset for some strange reason, then return not supported.
if (ThreadStartRoutineOffset >= 0x1000)
{
Status = STATUS_NOT_SUPPORTED;
break;
}
// Get the address of KeBugCheckEx.
if (!(KeBugCheckExSymbol = MmGetSystemRoutineAddress(&SymbolName)))
{
Status = STATUS_PROCEDURE_NOT_FOUND;
break;
}
// Calculate the restoration pointer.
OrigKeBugCheckExRestorePointer = (PVOID)(KeBugCheckExSymbol + 0xf);
// Create an initialize the MDL.
if (!(Mdl = MmCreateMdl(NULL, (PVOID)KeBugCheckExSymbol, 0xf)))
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
MmBuildMdlForNonPagedPool(Mdl);
// Probe & Lock.
if (!(LockedAddress = (PUCHAR)MmMapLockedPages(Mdl, KernelMode)))
{
IoFreeMdl(Mdl);
Status = STATUS_ACCESS_VIOLATION;
break;
}
// Set the aboslute address to our hook.
*(PULONG64)(HookStub + 0x2) = (ULONG64)KeBugCheckExHook;
//DebugPrint(("Copying hook stub to %p from %p (Symbol %p).", LockedAddress, HookStub, KeBugCheckExSymbol));
// Copy the relative jmp into the hook routine.
RtlCopyMemory(LockedAddress, HookStub, 0xf);
// Cleanup the MDL.
MmUnmapLockedPages(LockedAddress, Mdl);
IoFreeMdl(Mdl);
} while (0);
KeBugCheckEx(0x109,0,0,0,0);//测试专用。
}
// A pointer to KeBugCheckExHook
PVOID KeBugCheckExHookPointer = KeBugCheckExHook;
// Create the system worker thread so that we can automatically find the offset inside the ETHREAD structure to the thread's start routine.
Status = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, &Attributes, NULL, NULL, DisablePatchProtectionSystemThreadRoutine, NULL);
注意:
如果出现下面的情况:
1>d:\winddk\work\c\amd64\asm.asm(1) : error A2039:line too long
1>d:\winddk\work\c\amd64\asm.asm(1) : error A2088:END directive required at end of file
google一下说是某个版本的ml.exe问题,可能后来改进了。解决办法是:
用系统自带的记事本打开文件,一看源代码只有一行。注释:用别的编辑工具都是好好的。
解决办法:在记事本里面手工格式化代码就ok!
made by correy
made at 2013.02.18
QQ:112426112
Email:kouleguan at hotmail dot com
Homepage:369K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3y4G2M7Y4u0W2P5g2)9J5k6i4N6W2j5Y4y4Q4x3X3g2U0L8$3@1`.