Use IRQL value in the emulated KPCR structure rather than overwriting the Windows TIB structure (#42)

* Use IRQL value in the emulated KPCR structure rather than overwriting the Windows TIB structure.

Note: The entire KPCR is currently per thread, this is not correct as the KPCR should be per-cpu.
The issue here is that the first part of the KPCR, NT_TIB should be per thread.

I haven't figured out a good way to keep that portion per-thread while keeping the rest of the structure global,
that said, it will function fine as long as the same thread calls the IRQL functions.

* Move KPCR fetch code into KeGetPcr();

This exists as a macro on the Xbox, but we implement it as a function because the xbox approach requires FS to point to the KPCR
This isn't possible on 64-bit Windows, even with 32-bit code, so this approach is required.
This commit is contained in:
Luke Usher 2016-12-20 21:46:07 +00:00 committed by GitHub
parent 73c0b0ca68
commit af663c8f44
2 changed files with 29 additions and 21 deletions

View File

@ -55,6 +55,12 @@ namespace NtDll
#include "EmuNtDll.h"
};
// ******************************************************************
// * Declaring this in a header causes errors with xboxkrnl
// * namespace, so we must declare it within any file that uses it
// ******************************************************************
xboxkrnl::KPCR* KeGetPcr();
// ******************************************************************
// * 0x0033 - InterlockedCompareExchange()
// ******************************************************************
@ -200,15 +206,8 @@ XBSYSAPI EXPORTNUM(160) xboxkrnl::UCHAR FASTCALL xboxkrnl::KfRaiseIrql
LOG_FUNC_ONE_ARG(NewIrql);
UCHAR OldIrql;
KPCR* Pcr = nullptr;
// Fetch KPCR data structure
__asm {
push eax
mov eax, fs:[0x14]
mov Pcr, eax
pop eax
}
KPCR* Pcr = KeGetPcr();
if (NewIrql < Pcr->Irql) {
// TODO: Enable this after KeBugCheck is implemented

View File

@ -57,6 +57,26 @@ namespace NtDll
#include <chrono>
#include <thread>
// ******************************************************************
// * KeGetPcr()
// * NOTE: This is a macro on the Xbox, however we implement it
// * as a function so it can suit our emulated KPCR structure
// ******************************************************************
xboxkrnl::KPCR* KeGetPcr()
{
xboxkrnl::KPCR* Pcr = nullptr;
__asm {
push eax
mov eax, fs:[0x14]
mov Pcr, eax
pop eax
}
return Pcr;
}
// ******************************************************************
// * 0x005C - KeAlertResumeThread()
// ******************************************************************
@ -222,12 +242,7 @@ XBSYSAPI EXPORTNUM(103) xboxkrnl::KIRQL NTAPI xboxkrnl::KeGetCurrentIrql(void)
KIRQL Irql;
// TODO : Untested :
__asm
{
mov al, byte ptr fs : [24h]
mov Irql, al
}
Irql = KeGetPcr()->Irql;
RETURN(Irql);
}
@ -439,13 +454,7 @@ XBSYSAPI EXPORTNUM(129) xboxkrnl::UCHAR NTAPI xboxkrnl::KeRaiseIrqlToDpcLevel()
CxbxKrnlCleanup("Bugcheck: Caller of KeRaiseIrqlToDpcLevel is higher than DISPATCH_LEVEL!");
KIRQL kRet = NULL;
__asm
{
mov al, byte ptr fs:[24h]
mov kRet, al
mov al, DISPATCH_LEVEL
mov byte ptr fs:[24h], al
}
KeGetPcr()->Irql = DISPATCH_LEVEL;
#ifdef _DEBUG_TRACE
DbgPrintf("Raised IRQL to DISPATCH_LEVEL (2).\n");