kernel.c
来自「一个类似windows」· C语言 代码 · 共 599 行 · 第 1/2 页
C
599 行
* with MmAllocPage() here because MmInit1() has not yet been
* called, so we use a predefined page in low memory
*/
KPCR = (PKIPCR)KPCR_BASE;
memset(KPCR, 0, PAGE_SIZE);
KPCR->Self = (PKPCR)KPCR;
KPCR->Prcb = &KPCR->PrcbData;
KPCR->Irql = SYNCH_LEVEL;
KPCR->NtTib.Self = &KPCR->NtTib;
KPCR->GDT = KiBootGdt;
KPCR->IDT = KiIdt;
KPCR->TSS = &KiBootTss;
KPCR->Number = 0;
KPCR->SetMember = 1 << 0;
KeActiveProcessors = 1 << 0;
KPCR->PrcbData.SetMember = 1 << 0;
KiPcrInitDone = 1;
PcrsAllocated++;
KiInitializeGdt (NULL);
Ki386BootInitializeTSS();
Ki386InitializeLdt();
/* Get processor information. */
Ki386GetCpuId();
/* Check FPU/MMX/SSE support. */
KiCheckFPU();
/* Mark the end of the exception handler list */
KPCR->NtTib.ExceptionList = (PVOID)-1;
KeInitDpc(KPCR->Prcb);
KeInitExceptions ();
KeInitInterrupts ();
KeActiveProcessors |= 1 << 0;
if (KPCR->PrcbData.FeatureBits & X86_FEATURE_PGE)
{
ULONG Flags;
/* Enable global pages */
Ke386GlobalPagesEnabled = TRUE;
Ke386SaveFlags(Flags);
Ke386DisableInterrupts();
Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);
Ke386RestoreFlags(Flags);
}
/* Search for pae and noexecute */
p1 = (PCHAR)KeLoaderBlock.CommandLine;
while(*p1 && (p2 = strchr(p1, '/')))
{
p2++;
if (!_strnicmp(p2, "PAE", 3))
{
if (p2[3] == ' ' || p2[3] == 0)
{
p2 += 3;
Pae = TRUE;
}
}
else if (!_strnicmp(p2, "NOEXECUTE", 9))
{
if (p2[9] == ' ' || p2[9] == '=' || p2[9] == 0)
{
p2 += 9;
NoExecute = TRUE;
}
}
p1 = p2;
}
#if 0
/*
* FIXME:
* Make the detection of the noexecute feature more portable.
*/
if(KPCR->PrcbData.CpuType == 0xf &&
RtlCompareMemory("AuthenticAMD", KPCR->PrcbData.VendorString, 12) == 12)
{
if (NoExecute)
{
ULONG Flags, l, h;
Ke386SaveFlags(Flags);
Ke386DisableInterrupts();
Ke386Rdmsr(0xc0000080, l, h);
l |= (1 << 11);
Ke386Wrmsr(0xc0000080, l, h);
Ke386NoExecute = TRUE;
Ke386RestoreFlags(Flags);
}
}
else
{
NoExecute=FALSE;
}
#endif
Ke386Pae = Ke386GetCr4() & X86_CR4_PAE ? TRUE : FALSE;
#if 0
/* Enable PAE mode */
if ((Pae && (KPCR->PrcbData.FeatureBits & X86_FEATURE_PAE)) || NoExecute)
{
MiEnablePAE((PVOID*)LastKernelAddress);
Ke386PaeEnabled = TRUE;
}
#endif
if (KPCR->PrcbData.FeatureBits & X86_FEATURE_SYSCALL)
{
extern void KiFastCallEntry(void);
/* CS Selector of the target segment. */
Ke386Wrmsr(0x174, KGDT_R0_CODE, 0);
/* Target ESP. */
Ke386Wrmsr(0x175, 0, 0);
/* Target EIP. */
Ke386Wrmsr(0x176, (ULONG_PTR)KiFastCallEntry, 0);
}
/* Does the CPU Support 'prefetchnta' (SSE) */
if(KPCR->PrcbData.FeatureBits & X86_FEATURE_SSE)
{
ULONG Protect;
Protect = MmGetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal);
MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect | PAGE_IS_WRITABLE);
/* Replace the ret by a nop */
*(PCHAR)RtlPrefetchMemoryNonTemporal = 0x90;
MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect);
}
}
VOID
INIT_FUNCTION
NTAPI
KeInit2(VOID)
{
PKIPCR Pcr = (PKIPCR)KeGetCurrentKPCR();
KiInitializeBugCheck();
KeInitializeDispatcher();
KiInitializeSystemClock();
if (Pcr->PrcbData.FeatureBits & X86_FEATURE_PAE)
{
DPRINT("CPU supports PAE mode\n");
if (Ke386Pae)
{
DPRINT("CPU runs in PAE mode\n");
if (Ke386NoExecute)
{
DPRINT("NoExecute is enabled\n");
}
}
else
{
DPRINT("CPU doesn't run in PAE mode\n");
}
}
if ((Pcr->PrcbData.FeatureBits & (X86_FEATURE_FXSR | X86_FEATURE_MMX | X86_FEATURE_SSE | X86_FEATURE_SSE2)) ||
(Ke386CpuidFlags2 & X86_EXT_FEATURE_SSE3))
{
DPRINT("CPU supports" "%s%s%s%s%s" ".\n",
((Pcr->PrcbData.FeatureBits & X86_FEATURE_FXSR) ? " FXSR" : ""),
((Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX) ? " MMX" : ""),
((Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE) ? " SSE" : ""),
((Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2) ? " SSE2" : ""),
((Ke386CpuidFlags2 & X86_EXT_FEATURE_SSE3) ? " SSE3" : ""));
}
if (Ke386GetCr4() & X86_CR4_OSFXSR)
{
DPRINT("SSE enabled.\n");
}
if (Ke386GetCr4() & X86_CR4_OSXMMEXCPT)
{
DPRINT("Unmasked SIMD exceptions enabled.\n");
}
if (Pcr->PrcbData.VendorString[0])
{
DPRINT("CPU Vendor: %s\n", Pcr->PrcbData.VendorString);
}
if (Ke386CpuidModel[0])
{
DPRINT("CPU Model: %s\n", Ke386CpuidModel);
}
DPRINT("Ke386CacheAlignment: %d\n", Ke386CacheAlignment);
if (Ke386L1CacheSize)
{
DPRINT("Ke386L1CacheSize: %dkB\n", Ke386L1CacheSize);
}
if (Pcr->L2CacheSize)
{
DPRINT("Ke386L2CacheSize: %dkB\n", Pcr->L2CacheSize);
}
}
VOID INIT_FUNCTION
Ki386SetProcessorFeatures(VOID)
{
PKIPCR Pcr = (PKIPCR)KeGetCurrentKPCR();
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Kernel");
UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"FastSystemCallDisable");
HANDLE KeyHandle;
ULONG ResultLength;
struct
{
KEY_VALUE_PARTIAL_INFORMATION Info;
UCHAR Buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,
Data[0]) + sizeof(ULONG)];
} ValueData;
NTSTATUS Status;
ULONG FastSystemCallDisable = 0;
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE;
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE;
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8) ? TRUE : FALSE;
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX) ? TRUE : FALSE;
SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE) ? TRUE : FALSE;
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
(Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW) ? TRUE : FALSE;
SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC) ? TRUE : FALSE;
SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386Pae;
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2) ? TRUE : FALSE;
/* Does the CPU Support Fast System Call? */
if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) {
/* FIXME: Check for Family == 6, Model < 3 and Stepping < 3 and disable */
/* Make sure it's not disabled in registry */
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenKey(&KeyHandle,
KEY_QUERY_VALUE,
&ObjectAttributes);
if (NT_SUCCESS(Status)) {
/* Read the Value then Close the Key */
Status = ZwQueryValueKey(KeyHandle,
&ValueName,
KeyValuePartialInformation,
&ValueData,
sizeof(ValueData),
&ResultLength);
if (NT_SUCCESS(Status))
{
if (ResultLength == sizeof(ValueData) &&
ValueData.Info.Type == REG_DWORD)
{
FastSystemCallDisable = *(PULONG)ValueData.Info.Data != 0;
}
ZwClose(KeyHandle);
}
}
} else {
/* Disable SYSENTER/SYSEXIT, because the CPU doesn't support it */
FastSystemCallDisable = 1;
}
if (FastSystemCallDisable) {
/* Use INT2E */
const unsigned char Entry[7] = {0x8D, 0x54, 0x24, 0x08, /* lea 0x8(%esp),%edx */
0xCD, 0x2E, /* int 0x2e */
0xC3}; /* ret */
memcpy(&SharedUserData->SystemCall, Entry, sizeof(Entry));
} else {
/* Use SYSENTER */
const unsigned char Entry[5] = {0x8B, 0xD4, /* movl %esp,%edx */
0x0F, 0x34, /* sysenter */
0xC3}; /* ret */
memcpy(&SharedUserData->SystemCall, Entry, sizeof(Entry));
/* Enable SYSENTER/SYSEXIT */
KiFastSystemCallDisable = 0;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?