Mini-merge from my local changes. Rewrite of Process Creation. Notable improvements:

- Subsystemization of Process Creation code. Memory code done by new Mm functions (not all used yet),
      Kernel code done by Ke*, etc.
    - Written to be compatible with the information in "Windows Internals".
    - Optimized and cleaned up.
    - ObInsertObject is now called at the end, fixing a plethora of wrong things that were covered with FIXMEs.
    - PEB is allocated with a Memory Area, and so will TEB soon, which allows 4KB allocation without 64KB gra
      nularity.
    - System DLL Mapping/Loading has been changed to be cached at system bootup, resulting in faster code.
    
Also changed Peb to report NT 5.0

NOTE: Messy, more to come soon. The full benefits of this patch won't be realized until the complete changes
      are in.

svn path=/trunk/; revision=14660
This commit is contained in:
Alex Ionescu 2005-04-18 00:42:31 +00:00
parent a9920ccd9d
commit 7740536c18
20 changed files with 663 additions and 883 deletions

View file

@ -144,6 +144,7 @@ OBJECTS_MM = \
mm/pool.o \ mm/pool.o \
mm/ppool.o \ mm/ppool.o \
mm/physical.o \ mm/physical.o \
mm/process.o \
mm/region.o \ mm/region.o \
mm/rmap.o \ mm/rmap.o \
mm/section.o \ mm/section.o \

View file

@ -494,7 +494,7 @@ ExpInitializeExecutive(VOID)
/* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */ /* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
IoInit(); IoInit();
/* TBD */ /* TBD */
PoInit((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock, ForceAcpiDisable); PoInit((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock, ForceAcpiDisable);
@ -562,6 +562,9 @@ ExpInitializeExecutive(VOID)
/* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */ /* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
IoInit3(); IoInit3();
/* Load the System DLL and its Entrypoints */
LdrpInitializeSystemDll();
/* Initialize the Default Locale */ /* Initialize the Default Locale */
PiInitDefaultLocale(); PiInitDefaultLocale();

View file

@ -259,7 +259,14 @@ FASTCALL
KiAbortWaitThread(PKTHREAD Thread, KiAbortWaitThread(PKTHREAD Thread,
NTSTATUS WaitStatus, NTSTATUS WaitStatus,
KPRIORITY Increment); KPRIORITY Increment);
VOID
STDCALL
KeInitializeProcess(struct _KPROCESS *Process,
KPRIORITY Priority,
KAFFINITY Affinity,
LARGE_INTEGER DirectoryTableBase);
ULONG ULONG
STDCALL STDCALL
KeForceResumeThread(IN PKTHREAD Thread); KeForceResumeThread(IN PKTHREAD Thread);

View file

@ -34,10 +34,18 @@ LdrInitModuleManagement (
); );
NTSTATUS NTSTATUS
LdrpMapSystemDll ( STDCALL
HANDLE ProcessHandle, LdrpMapSystemDll(PEPROCESS Process,
PVOID * LdrStartupAddress PVOID *DllBase);
);
NTSTATUS
STDCALL
LdrpInitializeSystemDll(VOID);
NTSTATUS
STDCALL
LdrpGetSystemDllEntryPoints(VOID);
PVOID PVOID
LdrpGetSystemDllEntryPoint (VOID); LdrpGetSystemDllEntryPoint (VOID);
PVOID PVOID

View file

@ -37,6 +37,7 @@ typedef ULONG PFN_TYPE, *PPFN_TYPE;
#define MEMORY_AREA_KERNEL_STACK (11) #define MEMORY_AREA_KERNEL_STACK (11)
#define MEMORY_AREA_PAGED_POOL (12) #define MEMORY_AREA_PAGED_POOL (12)
#define MEMORY_AREA_NO_ACCESS (13) #define MEMORY_AREA_NO_ACCESS (13)
#define MEMORY_AREA_PEB_OR_TEB (14)
#define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \ #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
((x) / (4*1024*1024)) ((x) / (4*1024*1024))
@ -496,6 +497,17 @@ BOOLEAN MmIsAvailableSwapPage(VOID);
VOID MmShowOutOfSpaceMessagePagingFile(VOID); VOID MmShowOutOfSpaceMessagePagingFile(VOID);
/* process.c ****************************************************************/
NTSTATUS
STDCALL
MmCreateProcessAddressSpace(IN struct _EPROCESS* Process,
IN PSECTION_OBJECT Section OPTIONAL);
NTSTATUS
STDCALL
MmCreatePeb(PEPROCESS Process);
/* i386/pfault.c *************************************************************/ /* i386/pfault.c *************************************************************/
NTSTATUS MmPageFault(ULONG Cs, NTSTATUS MmPageFault(ULONG Cs,
@ -579,6 +591,17 @@ MmCheckForPageOp(PMEMORY_AREA MArea, HANDLE Pid, PVOID Address,
VOID VOID
MmInitializePageOp(VOID); MmInitializePageOp(VOID);
/* process.c *****************************************************************/
PVOID
STDCALL
MmCreateKernelStack(BOOLEAN GuiStack);
VOID
STDCALL
MmDeleteKernelStack(PVOID Stack,
BOOLEAN GuiStack);
/* balace.c ******************************************************************/ /* balace.c ******************************************************************/
VOID MmInitializeMemoryConsumer(ULONG Consumer, VOID MmInitializeMemoryConsumer(ULONG Consumer,
@ -737,7 +760,11 @@ VOID MmDeletePageTable(struct _EPROCESS* Process, PVOID Address);
PFN_TYPE MmGetPfnForProcess(struct _EPROCESS* Process, PVOID Address); PFN_TYPE MmGetPfnForProcess(struct _EPROCESS* Process, PVOID Address);
NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src, struct _EPROCESS* Dest); NTSTATUS
STDCALL
MmCopyMmInfo(struct _EPROCESS* Src,
struct _EPROCESS* Dest,
PPHYSICAL_ADDRESS DirectoryTableBase);
NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process); NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);

View file

@ -492,6 +492,11 @@ VOID STDCALL PsExitSpecialApc(PKAPC Apc,
PVOID *NormalContext, PVOID *NormalContext,
PVOID *SystemArgument1, PVOID *SystemArgument1,
PVOID *SystemArgument2); PVOID *SystemArgument2);
NTSTATUS
STDCALL
PspInitializeProcessSecurity(PEPROCESS Process,
PEPROCESS Parent OPTIONAL);
#define THREAD_STATE_INITIALIZED (0) #define THREAD_STATE_INITIALIZED (0)
#define THREAD_STATE_READY (1) #define THREAD_STATE_READY (1)

View file

@ -117,9 +117,7 @@ SepCreateImpersonationTokenDacl(PTOKEN Token,
VOID SepInitializeTokenImplementation(VOID); VOID SepInitializeTokenImplementation(VOID);
NTSTATUS SepCreateSystemProcessToken(struct _EPROCESS* Process); PTOKEN STDCALL SepCreateSystemProcessToken(VOID);
NTSTATUS SepInitializeNewProcess(struct _EPROCESS* NewProcess,
struct _EPROCESS* ParentProcess);
NTSTATUS SeExchangePrimaryToken(struct _EPROCESS* Process, NTSTATUS SeExchangePrimaryToken(struct _EPROCESS* Process,
PACCESS_TOKEN NewToken, PACCESS_TOKEN NewToken,
@ -148,6 +146,16 @@ SepPrivilegeCheck(PTOKEN Token,
ULONG PrivilegeControl, ULONG PrivilegeControl,
KPROCESSOR_MODE PreviousMode); KPROCESSOR_MODE PreviousMode);
NTSTATUS
STDCALL
SepDuplicateToken(PTOKEN Token,
POBJECT_ATTRIBUTES ObjectAttributes,
BOOLEAN EffectiveOnly,
TOKEN_TYPE TokenType,
SECURITY_IMPERSONATION_LEVEL Level,
KPROCESSOR_MODE PreviousMode,
PTOKEN* NewAccessToken);
NTSTATUS NTSTATUS
SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE AccessMode,

View file

@ -756,6 +756,7 @@ KiInitializeUserApc(IN PVOID Reserved,
Esp[4] = (ULONG)SystemArgument2; Esp[4] = (ULONG)SystemArgument2;
Esp[5] = (ULONG)Context; Esp[5] = (ULONG)Context;
TrapFrame->Eip = (ULONG)LdrpGetSystemDllApcDispatcher(); TrapFrame->Eip = (ULONG)LdrpGetSystemDllApcDispatcher();
DPRINT("TrapFrame->Eip: %x\n", TrapFrame->Eip);
TrapFrame->Esp = (ULONG)Esp; TrapFrame->Esp = (ULONG)Esp;
} }

View file

@ -205,13 +205,14 @@ KiBlockThread(PNTSTATUS Status,
} else { } else {
/* Set the Thread Data as Requested */ /* Set the Thread Data as Requested */
DPRINT("Dispatching Thread as blocked\n"); DPRINT("Dispatching Thread as blocked: %d\n", Thread->WaitStatus);
Thread->Alertable = Alertable; Thread->Alertable = Alertable;
Thread->WaitMode = (UCHAR)WaitMode; Thread->WaitMode = (UCHAR)WaitMode;
Thread->WaitReason = WaitReason; Thread->WaitReason = WaitReason;
/* Dispatch it and return status */ /* Dispatch it and return status */
KiDispatchThreadNoLock(THREAD_STATE_BLOCKED); KiDispatchThreadNoLock(THREAD_STATE_BLOCKED);
DPRINT("Dispatching Thread as blocked: %d\n", Thread->WaitStatus);
if (Status != NULL) *Status = Thread->WaitStatus; if (Status != NULL) *Status = Thread->WaitStatus;
} }

View file

@ -19,7 +19,7 @@
#define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF)) #define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
ULONG NtMajorVersion = 4; ULONG NtMajorVersion = 5;
ULONG NtMinorVersion = 0; ULONG NtMinorVersion = 0;
ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(6, 0); ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(6, 0);
#ifdef __GNUC__ #ifdef __GNUC__

View file

@ -53,6 +53,35 @@ UpdatePageDirs(PKTHREAD Thread, PKPROCESS Process)
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD)); MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
} }
VOID
STDCALL
KeInitializeProcess(PKPROCESS Process,
KPRIORITY Priority,
KAFFINITY Affinity,
LARGE_INTEGER DirectoryTableBase)
{
DPRINT1("KeInitializeProcess. Process: %x, DirectoryTableBase: %x\n", Process, DirectoryTableBase);
/* Initialize the Dispatcher Header */
KeInitializeDispatcherHeader(&Process->DispatcherHeader,
ProcessObject,
sizeof(KPROCESS),
FALSE);
/* Initialize Scheduler Data, Disable Alignment Faults and Set the PDE */
Process->Affinity = Affinity;
Process->BasePriority = Priority;
Process->ThreadQuantum = 6;
Process->DirectoryTableBase = DirectoryTableBase;
Process->AutoAlignment = TRUE;
Process->IopmOffset = 0xFFFF;
Process->State = PROCESS_STATE_ACTIVE;
/* Initialize the Thread List */
InitializeListHead(&Process->ThreadListHead);
DPRINT1("The Process has now been initalized with the Kernel\n");
}
ULONG ULONG
STDCALL STDCALL
KeSetProcess(PKPROCESS Process, KeSetProcess(PKPROCESS Process,
@ -148,6 +177,7 @@ KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE
} }
/* Swap the Processes */ /* Swap the Processes */
DPRINT("Swapping\n");
KiSwapProcess(Process, SavedApcState->Process); KiSwapProcess(Process, SavedApcState->Process);
/* Return to old IRQL*/ /* Return to old IRQL*/

View file

@ -445,7 +445,6 @@ KeWaitForMultipleObjects(ULONG Count,
*/ */
if (CurrentObject->Type == IO_TYPE_FILE) { if (CurrentObject->Type == IO_TYPE_FILE) {
DPRINT1("Hack used: %x\n", &((PFILE_OBJECT)CurrentObject)->Event);
CurrentObject = (PDISPATCHER_HEADER)(&((PFILE_OBJECT)CurrentObject)->Event); CurrentObject = (PDISPATCHER_HEADER)(&((PFILE_OBJECT)CurrentObject)->Event);
} }
@ -571,7 +570,7 @@ KeWaitForMultipleObjects(ULONG Count,
DPRINT("Waking Queue\n"); DPRINT("Waking Queue\n");
KiWakeQueue(CurrentThread->Queue); KiWakeQueue(CurrentThread->Queue);
} }
/* Block the Thread */ /* Block the Thread */
DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode, WaitReason, KeGetCurrentThread()); DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode, WaitReason, KeGetCurrentThread());
KiBlockThread(&Status, KiBlockThread(&Status,

View file

@ -24,6 +24,9 @@ PVOID SystemDllCallbackDispatcher = NULL;
PVOID SystemDllExceptionDispatcher = NULL; PVOID SystemDllExceptionDispatcher = NULL;
PVOID SystemDllRaiseExceptionDispatcher = NULL; PVOID SystemDllRaiseExceptionDispatcher = NULL;
PVOID LdrpSystemDllBase = NULL;
PVOID LdrpSystemDllSection = NULL;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
PVOID LdrpGetSystemDllExceptionDispatcher(VOID) PVOID LdrpGetSystemDllExceptionDispatcher(VOID)
@ -51,282 +54,223 @@ PVOID LdrpGetSystemDllRaiseExceptionDispatcher(VOID)
return(SystemDllRaiseExceptionDispatcher); return(SystemDllRaiseExceptionDispatcher);
} }
NTSTATUS LdrpMapSystemDll(HANDLE ProcessHandle, NTSTATUS
PVOID* LdrStartupAddr) STDCALL
/* LdrpGetSystemDllEntryPoints(VOID)
* FUNCTION: LdrpMapSystemDll maps the system dll into the specified process
* address space and returns its startup address.
* PARAMETERS:
* ProcessHandle
* Points to the process to map the system dll into
*
* LdrStartupAddress
* Receives the startup address of the system dll on function
* completion
*
* RETURNS: Status
*/
{ {
CHAR BlockBuffer [1024]; ANSI_STRING ProcedureName;
DWORD ImageBase; NTSTATUS Status;
ULONG ImageSize;
NTSTATUS Status; /* Retrieve ntdll's startup address */
OBJECT_ATTRIBUTES FileObjectAttributes; DPRINT("Getting Entrypoint: %p\n", LdrpSystemDllBase);
HANDLE FileHandle; RtlInitAnsiString(&ProcedureName, "LdrInitializeThunk");
HANDLE NTDllSectionHandle; Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
UNICODE_STRING DllPathname = ROS_STRING_INITIALIZER(L"\\SystemRoot\\system32\\ntdll.dll"); &ProcedureName,
PIMAGE_DOS_HEADER DosHeader; 0,
PIMAGE_NT_HEADERS NTHeaders; &SystemDllEntryPoint);
PEPROCESS Process, CurrentProcess;
ANSI_STRING ProcedureName; if (!NT_SUCCESS(Status)) {
ULONG ViewSize;
IO_STATUS_BLOCK Iosb; DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
return (Status);
}
/* /* Get User APC Dispatcher */
* Locate and open NTDLL to determine ImageBase DPRINT("Getting Entrypoint\n");
* and LdrStartup RtlInitAnsiString(&ProcedureName, "KiUserApcDispatcher");
*/ Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
InitializeObjectAttributes(&FileObjectAttributes, &ProcedureName,
&DllPathname, 0,
0, &SystemDllApcDispatcher);
NULL,
NULL); if (!NT_SUCCESS(Status)) {
DPRINT("Opening NTDLL\n");
Status = ZwOpenFile(&FileHandle, DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
FILE_READ_ACCESS, return (Status);
&FileObjectAttributes, }
&Iosb,
FILE_SHARE_READ, /* Get Exception Dispatcher */
FILE_SYNCHRONOUS_IO_NONALERT); DPRINT("Getting Entrypoint\n");
if (!NT_SUCCESS(Status)) RtlInitAnsiString(&ProcedureName, "KiUserExceptionDispatcher");
{ Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
DPRINT1("NTDLL open failed (Status %x)\n", Status); &ProcedureName,
return Status; 0,
} &SystemDllExceptionDispatcher);
Status = ZwReadFile(FileHandle,
0, if (!NT_SUCCESS(Status)) {
0,
0, DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
&Iosb, return (Status);
BlockBuffer, }
sizeof(BlockBuffer),
0, /* Get Callback Dispatcher */
0); DPRINT("Getting Entrypoint\n");
if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer)) RtlInitAnsiString(&ProcedureName, "KiUserCallbackDispatcher");
{ Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
DPRINT1("NTDLL header read failed (Status %x)\n", Status); &ProcedureName,
ZwClose(FileHandle); 0,
return Status; &SystemDllCallbackDispatcher);
}
if (!NT_SUCCESS(Status)) {
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
return (Status);
}
/* Get Raise Exception Dispatcher */
DPRINT("Getting Entrypoint\n");
RtlInitAnsiString(&ProcedureName, "KiRaiseUserExceptionDispatcher");
Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
&ProcedureName,
0,
&SystemDllRaiseExceptionDispatcher);
if (!NT_SUCCESS(Status)) {
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
return (Status);
}
/* /* Return success */
* FIXME: this will fail if the NT headers are return(STATUS_SUCCESS);
* more than 1024 bytes from start. }
*/
DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
NTHeaders = (PIMAGE_NT_HEADERS) (BlockBuffer + DosHeader->e_lfanew);
if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|| (DosHeader->e_lfanew == 0L)
|| (*(PULONG) NTHeaders != IMAGE_NT_SIGNATURE))
{
DPRINT1("NTDLL format invalid\n");
ZwClose(FileHandle);
return(STATUS_UNSUCCESSFUL);
}
ImageBase = NTHeaders->OptionalHeader.ImageBase;
ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
/*
* Create a section for NTDLL
*/
DPRINT("Creating section\n");
Status = ZwCreateSection(&NTDllSectionHandle,
SECTION_ALL_ACCESS,
NULL,
NULL,
PAGE_READONLY,
SEC_IMAGE | SEC_COMMIT,
FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT1("NTDLL create section failed (Status %x)\n", Status);
ZwClose(FileHandle);
return(Status);
}
ZwClose(FileHandle);
/*
* Map the NTDLL into the process
*/
ViewSize = 0;
ImageBase = 0;
Status = ZwMapViewOfSection(NTDllSectionHandle,
ProcessHandle,
(PVOID*)&ImageBase,
0,
ViewSize,
NULL,
&ViewSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("NTDLL map view of secion failed (Status %x)", Status);
ZwClose(NTDllSectionHandle);
return(Status);
}
DPRINT("Referencing process\n"); NTSTATUS
Status = ObReferenceObjectByHandle(ProcessHandle, STDCALL
PROCESS_ALL_ACCESS, LdrpMapSystemDll(PEPROCESS Process,
PsProcessType, PVOID *DllBase)
KernelMode, {
(PVOID*)&Process, NTSTATUS Status;
NULL); ULONG ViewSize = 0;
if (!NT_SUCCESS(Status)) PVOID ImageBase = 0;
{
DPRINT1("ObReferenceObjectByProcess() failed (Status %x)\n", Status); /* Map the System DLL */
return(Status); DPRINT("Mapping System DLL\n");
} Status = MmMapViewOfSection(LdrpSystemDllSection,
Process,
(PVOID*)&ImageBase,
0,
0,
NULL,
&ViewSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status)) {
DPRINT1("Failed to map System DLL Into Process\n");
}
if (DllBase) *DllBase = ImageBase;
return Status;
}
CurrentProcess = PsGetCurrentProcess(); NTSTATUS
if (Process != CurrentProcess) STDCALL
{ LdrpInitializeSystemDll(VOID)
DPRINT("Attaching to Process\n"); {
KeAttachProcess(&Process->Pcb); UNICODE_STRING DllPathname = ROS_STRING_INITIALIZER(L"\\SystemRoot\\system32\\ntdll.dll");
OBJECT_ATTRIBUTES FileObjectAttributes;
IO_STATUS_BLOCK Iosb;
HANDLE FileHandle;
HANDLE NTDllSectionHandle;
NTSTATUS Status;
CHAR BlockBuffer[1024];
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NTHeaders;
/* Locate and open NTDLL to determine ImageBase and LdrStartup */
InitializeObjectAttributes(&FileObjectAttributes,
&DllPathname,
0,
NULL,
NULL);
DPRINT("Opening NTDLL\n");
Status = ZwOpenFile(&FileHandle,
FILE_READ_ACCESS,
&FileObjectAttributes,
&Iosb,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status)) {
DPRINT1("NTDLL open failed (Status %x)\n", Status);
return Status;
} }
/* /* Load NTDLL is valid */
* retrieve ntdll's startup address DPRINT("Reading NTDLL\n");
*/ Status = ZwReadFile(FileHandle,
if (SystemDllEntryPoint == NULL) 0,
{ 0,
RtlInitAnsiString (&ProcedureName, 0,
"LdrInitializeThunk"); &Iosb,
Status = LdrGetProcedureAddress ((PVOID)ImageBase, BlockBuffer,
&ProcedureName, sizeof(BlockBuffer),
0, 0,
&SystemDllEntryPoint); 0);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer)) {
{
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); DPRINT1("NTDLL header read failed (Status %x)\n", Status);
if (Process != CurrentProcess) ZwClose(FileHandle);
{ return Status;
KeDetachProcess(); }
}
ObDereferenceObject(Process); /* Check if it's valid */
ZwClose(NTDllSectionHandle); DosHeader = (PIMAGE_DOS_HEADER)BlockBuffer;
return (Status); NTHeaders = (PIMAGE_NT_HEADERS)(BlockBuffer + DosHeader->e_lfanew);
}
*LdrStartupAddr = SystemDllEntryPoint; if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE) ||
} (DosHeader->e_lfanew == 0L) ||
(*(PULONG) NTHeaders != IMAGE_NT_SIGNATURE)) {
/*
* Retrieve the offset of the APC dispatcher from NTDLL DPRINT1("NTDLL format invalid\n");
*/ ZwClose(FileHandle);
if (SystemDllApcDispatcher == NULL) return(STATUS_UNSUCCESSFUL);
{ }
RtlInitAnsiString (&ProcedureName,
"KiUserApcDispatcher"); /* Create a section for NTDLL */
Status = LdrGetProcedureAddress ((PVOID)ImageBase, DPRINT("Creating section\n");
&ProcedureName, Status = ZwCreateSection(&NTDllSectionHandle,
0, SECTION_ALL_ACCESS,
&SystemDllApcDispatcher); NULL,
if (!NT_SUCCESS(Status)) NULL,
{ PAGE_READONLY,
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); SEC_IMAGE | SEC_COMMIT,
if (Process != CurrentProcess) FileHandle);
{ if (!NT_SUCCESS(Status)) {
KeDetachProcess();
} DPRINT1("NTDLL create section failed (Status %x)\n", Status);
ObDereferenceObject(Process); ZwClose(FileHandle);
ZwClose(NTDllSectionHandle); return(Status);
return (Status); }
} ZwClose(FileHandle);
}
/* Reference the Section */
/* DPRINT("ObReferenceObjectByHandle section: %d\n", NTDllSectionHandle);
* Retrieve the offset of the exception dispatcher from NTDLL Status = ObReferenceObjectByHandle(NTDllSectionHandle,
*/ SECTION_ALL_ACCESS,
if (SystemDllExceptionDispatcher == NULL) MmSectionObjectType,
{ KernelMode,
RtlInitAnsiString (&ProcedureName, (PVOID*)&LdrpSystemDllSection,
"KiUserExceptionDispatcher"); NULL);
Status = LdrGetProcedureAddress ((PVOID)ImageBase, if (!NT_SUCCESS(Status)) {
&ProcedureName,
0, DPRINT1("NTDLL section reference failed (Status %x)\n", Status);
&SystemDllExceptionDispatcher); return(Status);
if (!NT_SUCCESS(Status)) }
{
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); /* Map it */
if (Process != CurrentProcess) LdrpMapSystemDll(PsGetCurrentProcess(), &LdrpSystemDllBase);
{ DPRINT("LdrpSystemDllBase: %x\n", LdrpSystemDllBase);
KeDetachProcess();
} /* Now get the Entrypoints */
ObDereferenceObject(Process); LdrpGetSystemDllEntryPoints();
ZwClose(NTDllSectionHandle);
return (Status); return STATUS_SUCCESS;
}
}
/*
* Retrieve the offset of the callback dispatcher from NTDLL
*/
if (SystemDllCallbackDispatcher == NULL)
{
RtlInitAnsiString (&ProcedureName,
"KiUserCallbackDispatcher");
Status = LdrGetProcedureAddress ((PVOID)ImageBase,
&ProcedureName,
0,
&SystemDllCallbackDispatcher);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
if (Process != CurrentProcess)
{
KeDetachProcess();
}
ObDereferenceObject(Process);
ZwClose(NTDllSectionHandle);
return (Status);
}
}
/*
* Retrieve the offset of the raise exception dispatcher from NTDLL
*/
if (SystemDllRaiseExceptionDispatcher == NULL)
{
RtlInitAnsiString (&ProcedureName,
"KiRaiseUserExceptionDispatcher");
Status = LdrGetProcedureAddress ((PVOID)ImageBase,
&ProcedureName,
0,
&SystemDllRaiseExceptionDispatcher);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
if (Process != CurrentProcess)
{
KeDetachProcess();
}
ObDereferenceObject(Process);
ZwClose(NTDllSectionHandle);
return (Status);
}
}
if (Process != CurrentProcess)
{
KeDetachProcess();
}
ObDereferenceObject(Process);
ZwClose(NTDllSectionHandle);
return(STATUS_SUCCESS);
} }
/* EOF */ /* EOF */

View file

@ -319,9 +319,12 @@ NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process)
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest) NTSTATUS
STDCALL
MmCopyMmInfo(PEPROCESS Src,
PEPROCESS Dest,
PPHYSICAL_ADDRESS DirectoryTableBase)
{ {
PKPROCESS KProcess = &Dest->Pcb;
NTSTATUS Status; NTSTATUS Status;
ULONG i, j; ULONG i, j;
PFN_TYPE Pfn[7]; PFN_TYPE Pfn[7];
@ -389,8 +392,9 @@ NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest)
MmDeleteHyperspaceMapping(PageDirectory); MmDeleteHyperspaceMapping(PageDirectory);
} }
KProcess->DirectoryTableBase.QuadPart = PFN_TO_PTE(Pfn[0]);
DPRINT("Finished MmCopyMmInfo()\n"); DirectoryTableBase->QuadPart = PFN_TO_PTE(Pfn[0]);
DPRINT("Finished MmCopyMmInfo(): %I64x\n", DirectoryTableBase->QuadPart);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }

View file

@ -384,6 +384,7 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
break; break;
case MEMORY_AREA_VIRTUAL_MEMORY: case MEMORY_AREA_VIRTUAL_MEMORY:
case MEMORY_AREA_PEB_OR_TEB:
Status = MmNotPresentFaultVirtualMemory(AddressSpace, Status = MmNotPresentFaultVirtualMemory(AddressSpace,
MemoryArea, MemoryArea,
(PVOID)Address, (PVOID)Address,

View file

@ -111,7 +111,7 @@ NtWaitForMultipleObjects(IN ULONG ObjectCount,
UserRequest, UserRequest,
PreviousMode, PreviousMode,
Alertable, Alertable,
TimeOut, TimeOut,
WaitBlockArray); WaitBlockArray);
/* dereference all objects */ /* dereference all objects */

View file

@ -473,7 +473,6 @@ NtCreateThread (
UserMode, UserMode,
NULL ); NULL );
KeInsertQueueApc(LdrInitApc, NULL, NULL, IO_NO_INCREMENT); KeInsertQueueApc(LdrInitApc, NULL, NULL, IO_NO_INCREMENT);
/* /*
* The thread is non-alertable, so the APC we added did not set UserApcPending to TRUE. * The thread is non-alertable, so the APC we added did not set UserApcPending to TRUE.
* We must do this manually. Do NOT attempt to set the Thread to Alertable before the call, * We must do this manually. Do NOT attempt to set the Thread to Alertable before the call,

View file

@ -41,8 +41,7 @@ static PCREATE_PROCESS_NOTIFY_ROUTINE
PiProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT]; PiProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
static PLOAD_IMAGE_NOTIFY_ROUTINE static PLOAD_IMAGE_NOTIFY_ROUTINE
PiLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT]; PiLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT];
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
PEPROCESS PEPROCESS
@ -113,8 +112,7 @@ PiKillMostProcesses(VOID)
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
PEPROCESS current; PEPROCESS current;
ExAcquireFastMutex(&PspActiveProcessMutex); ExAcquireFastMutex(&PspActiveProcessMutex);
current_entry = PsActiveProcessHead.Flink; current_entry = PsActiveProcessHead.Flink;
while (current_entry != &PsActiveProcessHead) while (current_entry != &PsActiveProcessHead)
{ {
@ -271,8 +269,16 @@ PsInitProcessManagment(VOID)
InsertHeadList(&PsActiveProcessHead, InsertHeadList(&PsActiveProcessHead,
&PsInitialSystemProcess->ProcessListEntry); &PsInitialSystemProcess->ProcessListEntry);
InitializeListHead(&PsInitialSystemProcess->ThreadListHead); InitializeListHead(&PsInitialSystemProcess->ThreadListHead);
SepCreateSystemProcessToken(PsInitialSystemProcess); #ifndef SCHED_REWRITE
PTOKEN BootToken;
/* No parent, this is the Initial System Process. Assign Boot Token */
BootToken = SepCreateSystemProcessToken();
BootToken->TokenInUse = TRUE;
PsInitialSystemProcess->Token = BootToken;
ObReferenceObject(BootToken);
#endif
} }
VOID VOID
@ -298,99 +304,6 @@ PspPostInitSystemProcess(VOID)
} }
} }
static NTSTATUS
PsCreatePeb(HANDLE ProcessHandle,
PEPROCESS Process,
PVOID ImageBase)
{
ULONG AllocSize;
ULONG PebSize;
PPEB Peb;
LARGE_INTEGER SectionOffset;
ULONG ViewSize;
PVOID TableBase;
NTSTATUS Status;
PAGED_CODE();
/* Allocate the Process Environment Block (PEB) */
Process->TebBlock = (PVOID) MM_ROUND_DOWN(PEB_BASE, MM_VIRTMEM_GRANULARITY);
AllocSize = MM_VIRTMEM_GRANULARITY;
Status = NtAllocateVirtualMemory(ProcessHandle,
&Process->TebBlock,
0,
&AllocSize,
MEM_RESERVE,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
return(Status);
}
ASSERT((ULONG_PTR) Process->TebBlock <= PEB_BASE &&
PEB_BASE + PAGE_SIZE <= (ULONG_PTR) Process->TebBlock + AllocSize);
Peb = (PPEB)PEB_BASE;
PebSize = PAGE_SIZE;
Status = NtAllocateVirtualMemory(ProcessHandle,
(PVOID*)&Peb,
0,
&PebSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
return(Status);
}
DPRINT("Peb %p PebSize %lu\n", Peb, PebSize);
ASSERT((PPEB) PEB_BASE == Peb && PAGE_SIZE <= PebSize);
Process->TebLastAllocated = (PVOID) Peb;
ViewSize = 0;
SectionOffset.QuadPart = (ULONGLONG)0;
TableBase = NULL;
Status = MmMapViewOfSection(NlsSectionObject,
Process,
&TableBase,
0,
0,
&SectionOffset,
&ViewSize,
ViewShare,
MEM_TOP_DOWN,
PAGE_READONLY);
if (!NT_SUCCESS(Status))
{
DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status);
return(Status);
}
DPRINT("TableBase %p ViewSize %lx\n", TableBase, ViewSize);
KeAttachProcess(&Process->Pcb);
/* Initialize the PEB */
RtlZeroMemory(Peb, sizeof(PEB));
Peb->ImageBaseAddress = ImageBase;
Peb->OSMajorVersion = 4;
Peb->OSMinorVersion = 0;
Peb->OSBuildNumber = 1381;
Peb->OSPlatformId = 2; //VER_PLATFORM_WIN32_NT;
Peb->OSCSDVersion = 6 << 8;
Peb->AnsiCodePageData = (char*)TableBase + NlsAnsiTableOffset;
Peb->OemCodePageData = (char*)TableBase + NlsOemTableOffset;
Peb->UnicodeCaseTableData = (char*)TableBase + NlsUnicodeTableOffset;
Process->Peb = Peb;
KeDetachProcess();
DPRINT("PsCreatePeb: Peb created at %p\n", Peb);
return(STATUS_SUCCESS);
}
PKPROCESS PKPROCESS
KeGetCurrentProcess(VOID) KeGetCurrentProcess(VOID)
/* /*
@ -445,472 +358,276 @@ IoGetCurrentProcess(VOID)
} }
NTSTATUS NTSTATUS
STDCALL
PspCreateProcess(OUT PHANDLE ProcessHandle, PspCreateProcess(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess OPTIONAL, IN HANDLE ParentProcess OPTIONAL,
IN BOOLEAN InheritObjectTable, IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL, IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL, IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL) IN HANDLE ExceptionPort OPTIONAL)
{ {
HANDLE hProcess; HANDLE hProcess;
PEPROCESS Process; PEPROCESS Process;
PEPROCESS pParentProcess; PEPROCESS pParentProcess;
PKPROCESS KProcess; PEPORT pDebugPort = NULL;
PVOID LdrStartupAddr; PEPORT pExceptionPort = NULL;
PVOID BaseAddress; PSECTION_OBJECT SectionObject = NULL;
PMEMORY_AREA MemoryArea; NTSTATUS Status = STATUS_SUCCESS;
PHYSICAL_ADDRESS BoundaryAddressMultiple; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
KPROCESSOR_MODE PreviousMode; PHYSICAL_ADDRESS DirectoryTableBase;
PVOID ImageBase = NULL; KAFFINITY Affinity;
PEPORT pDebugPort = NULL; DirectoryTableBase.QuadPart = (ULONGLONG)0;
PEPORT pExceptionPort = NULL;
PSECTION_OBJECT SectionObject = NULL;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("PspCreateProcess(ObjectAttributes %x)\n", ObjectAttributes); DPRINT("PspCreateProcess(ObjectAttributes %x)\n", ObjectAttributes);
PreviousMode = ExGetPreviousMode(); /* Reference the Parent if there is one */
if(ParentProcess != NULL)
{
Status = ObReferenceObjectByHandle(ParentProcess,
PROCESS_CREATE_PROCESS,
PsProcessType,
PreviousMode,
(PVOID*)&pParentProcess,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference the parent process: Status: 0x%x\n", Status);
return(Status);
}
/* Inherit Parent process's Affinity. */
Affinity = pParentProcess->Pcb.Affinity;
}
else
{
pParentProcess = NULL;
Affinity = KeActiveProcessors;
}
BoundaryAddressMultiple.QuadPart = 0; /* Add the debug port */
if (DebugPort != NULL)
if(ParentProcess != NULL) {
{ Status = ObReferenceObjectByHandle(DebugPort,
Status = ObReferenceObjectByHandle(ParentProcess, PORT_ALL_ACCESS,
PROCESS_CREATE_PROCESS, LpcPortObjectType,
PsProcessType, PreviousMode,
PreviousMode, (PVOID*)&pDebugPort,
(PVOID*)&pParentProcess, NULL);
NULL); if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status)) {
{ DPRINT1("Failed to reference the debug port: Status: 0x%x\n", Status);
DPRINT1("Failed to reference the parent process: Status: 0x%x\n", Status); goto exitdereferenceobjects;
return(Status); }
} }
}
else
{
pParentProcess = NULL;
}
/* /* Add the exception port */
* Add the debug port if (ExceptionPort != NULL)
*/ {
if (DebugPort != NULL) Status = ObReferenceObjectByHandle(ExceptionPort,
{ PORT_ALL_ACCESS,
Status = ObReferenceObjectByHandle(DebugPort, LpcPortObjectType,
PORT_ALL_ACCESS, PreviousMode,
LpcPortObjectType, (PVOID*)&pExceptionPort,
PreviousMode, NULL);
(PVOID*)&pDebugPort,
NULL); if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status)) {
{ DPRINT1("Failed to reference the exception port: Status: 0x%x\n", Status);
DPRINT1("Failed to reference the debug port: Status: 0x%x\n", Status); goto exitdereferenceobjects;
goto exitdereferenceobjects; }
} }
}
/* /* Add the Section */
* Add the exception port if (SectionHandle != NULL)
*/ {
if (ExceptionPort != NULL)
{
Status = ObReferenceObjectByHandle(ExceptionPort,
PORT_ALL_ACCESS,
LpcPortObjectType,
PreviousMode,
(PVOID*)&pExceptionPort,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference the exception port: Status: 0x%x\n", Status);
goto exitdereferenceobjects;
}
}
if (SectionHandle != NULL)
{
Status = ObReferenceObjectByHandle(SectionHandle, Status = ObReferenceObjectByHandle(SectionHandle,
0, 0,
MmSectionObjectType, MmSectionObjectType,
PreviousMode, PreviousMode,
(PVOID*)&SectionObject, (PVOID*)&SectionObject,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to reference process image section: Status: 0x%x\n", Status); DPRINT1("Failed to reference process image section: Status: 0x%x\n", Status);
goto exitdereferenceobjects; goto exitdereferenceobjects;
} }
} }
Status = ObCreateObject(PreviousMode, /* Create the Object */
PsProcessType, DPRINT("Creating Process Object\n");
ObjectAttributes, Status = ObCreateObject(PreviousMode,
PreviousMode, PsProcessType,
NULL, ObjectAttributes,
sizeof(EPROCESS), PreviousMode,
0, NULL,
0, sizeof(EPROCESS),
(PVOID*)&Process); 0,
if (!NT_SUCCESS(Status)) 0,
{ (PVOID*)&Process);
DPRINT1("Failed to create process object, Status: 0x%x\n", Status);
exitdereferenceobjects:
if(SectionObject != NULL)
ObDereferenceObject(SectionObject);
if(pExceptionPort != NULL)
ObDereferenceObject(pExceptionPort);
if(pDebugPort != NULL)
ObDereferenceObject(pDebugPort);
if(pParentProcess != NULL)
ObDereferenceObject(pParentProcess);
return Status;
}
KProcess = &Process->Pcb;
RtlZeroMemory(Process, sizeof(EPROCESS));
Status = PsCreateCidHandle(Process,
PsProcessType,
&Process->UniqueProcessId);
if(!NT_SUCCESS(Status))
{
DPRINT1("Failed to create CID handle (unique process ID)! Status: 0x%x\n", Status);
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
Process->DebugPort = pDebugPort;
Process->ExceptionPort = pExceptionPort;
if(SectionObject != NULL)
{
UNICODE_STRING FileName;
PWCHAR szSrc;
PCHAR szDest;
USHORT lnFName = 0;
/*
* Determine the image file name and save it to the EPROCESS structure
*/
FileName = SectionObject->FileObject->FileName;
szSrc = (PWCHAR)(FileName.Buffer + (FileName.Length / sizeof(WCHAR)) - 1);
while(szSrc >= FileName.Buffer)
{
if(*szSrc == L'\\')
{
szSrc++;
break;
}
else
{
szSrc--;
lnFName++;
}
}
/* copy the image file name to the process and truncate it to 15 characters
if necessary */
szDest = Process->ImageFileName;
lnFName = min(lnFName, sizeof(Process->ImageFileName) - 1);
while(lnFName-- > 0)
{
*(szDest++) = (UCHAR)*(szSrc++);
}
/* *szDest = '\0'; */
}
KeInitializeDispatcherHeader(&KProcess->DispatcherHeader,
ProcessObject,
sizeof(EPROCESS),
FALSE);
/* Inherit parent process's affinity. */
if(pParentProcess != NULL)
{
KProcess->Affinity = pParentProcess->Pcb.Affinity;
Process->InheritedFromUniqueProcessId = pParentProcess->UniqueProcessId;
Process->SessionId = pParentProcess->SessionId;
}
else
{
KProcess->Affinity = KeActiveProcessors;
}
KProcess->BasePriority = PROCESS_PRIO_NORMAL;
KProcess->IopmOffset = 0xffff;
KProcess->LdtDescriptor[0] = 0;
KProcess->LdtDescriptor[1] = 0;
InitializeListHead(&KProcess->ThreadListHead);
KProcess->ThreadQuantum = 6;
KProcess->AutoAlignment = 0;
MmInitializeAddressSpace(Process,
&Process->AddressSpace);
ObCreateHandleTable(pParentProcess,
InheritObjectTable,
Process);
MmCopyMmInfo(pParentProcess ? pParentProcess : PsInitialSystemProcess, Process);
KeInitializeEvent(&Process->LockEvent, SynchronizationEvent, FALSE);
Process->LockCount = 0;
Process->LockOwner = NULL;
Process->Win32WindowStation = (HANDLE)0;
ExAcquireFastMutex(&PspActiveProcessMutex);
InsertTailList(&PsActiveProcessHead, &Process->ProcessListEntry);
InitializeListHead(&Process->ThreadListHead);
ExReleaseFastMutex(&PspActiveProcessMutex);
Process->Pcb.State = PROCESS_STATE_ACTIVE;
/*
* Now we have created the process proper
*/
MmLockAddressSpace(&Process->AddressSpace);
/* Protect the highest 64KB of the process address space */
BaseAddress = (PVOID)MmUserProbeAddress;
Status = MmCreateMemoryArea(Process,
&Process->AddressSpace,
MEMORY_AREA_NO_ACCESS,
&BaseAddress,
0x10000,
PAGE_NOACCESS,
&MemoryArea,
FALSE,
FALSE,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
MmUnlockAddressSpace(&Process->AddressSpace);
DPRINT1("Failed to protect the highest 64KB of the process address space\n");
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
/* Protect the lowest 64KB of the process address space */
#if 0
BaseAddress = (PVOID)0x00000000;
Status = MmCreateMemoryArea(Process,
&Process->AddressSpace,
MEMORY_AREA_NO_ACCESS,
&BaseAddress,
0x10000,
PAGE_NOACCESS,
&MemoryArea,
FALSE,
FALSE,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
MmUnlockAddressSpace(&Process->AddressSpace);
DPRINT1("Failed to protect the lowest 64KB of the process address space\n");
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
#endif
/* Protect the 60KB above the shared user page */
BaseAddress = (char*)USER_SHARED_DATA + PAGE_SIZE;
Status = MmCreateMemoryArea(Process,
&Process->AddressSpace,
MEMORY_AREA_NO_ACCESS,
&BaseAddress,
0x10000 - PAGE_SIZE,
PAGE_NOACCESS,
&MemoryArea,
FALSE,
FALSE,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
MmUnlockAddressSpace(&Process->AddressSpace);
DPRINT1("Failed to protect the memory above the shared user page\n");
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
/* Create the shared data page */
BaseAddress = (PVOID)USER_SHARED_DATA;
Status = MmCreateMemoryArea(Process,
&Process->AddressSpace,
MEMORY_AREA_SHARED_DATA,
&BaseAddress,
PAGE_SIZE,
PAGE_READONLY,
&MemoryArea,
FALSE,
FALSE,
BoundaryAddressMultiple);
MmUnlockAddressSpace(&Process->AddressSpace);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create shared data page\n");
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
#if 1
/*
* FIXME - the handle should be created after all things are initialized, NOT HERE!
*/
Status = ObInsertObject ((PVOID)Process,
NULL,
DesiredAccess,
0,
NULL,
&hProcess);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create a handle for the process\n");
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
#endif
/*
* FIXME - Map ntdll
*/
Status = LdrpMapSystemDll(hProcess, /* FIXME - hProcess shouldn't be available at this point! */
&LdrStartupAddr);
if (!NT_SUCCESS(Status))
{
DbgPrint("LdrpMapSystemDll failed (Status %x)\n", Status);
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
/*
* Map the process image
*/
if (SectionObject != NULL)
{
ULONG ViewSize = 0;
DPRINT("Mapping process image\n");
Status = MmMapViewOfSection(SectionObject,
Process,
(PVOID*)&ImageBase,
0,
ViewSize,
NULL,
&ViewSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
ObDereferenceObject(SectionObject);
if (!NT_SUCCESS(Status))
{
DbgPrint("Failed to map the process section (Status %x)\n", Status);
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
}
if(pParentProcess != NULL)
{
/*
* Duplicate the token
*/
Status = SepInitializeNewProcess(Process, pParentProcess);
if (!NT_SUCCESS(Status))
{
DbgPrint("SepInitializeNewProcess failed (Status %x)\n", Status);
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
}
else
{
/* FIXME */
}
/*
* FIXME - Create PEB
*/
DPRINT("Creating PEB\n");
Status = PsCreatePeb(hProcess, /* FIXME - hProcess shouldn't be available at this point! */
Process,
ImageBase);
if (!NT_SUCCESS(Status))
{
DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status);
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
/*
* Maybe send a message to the creator process's debugger
*/
#if 0
if (pParentProcess->DebugPort != NULL)
{
LPC_DBG_MESSAGE Message;
HANDLE FileHandle;
ObCreateHandle(NULL, // Debugger Process
NULL, // SectionHandle
FILE_ALL_ACCESS,
FALSE,
&FileHandle);
Message.Header.MessageSize = sizeof(LPC_DBG_MESSAGE);
Message.Header.DataSize = sizeof(LPC_DBG_MESSAGE) -
sizeof(LPC_MESSAGE);
Message.Type = DBG_EVENT_CREATE_PROCESS;
Message.Data.CreateProcess.FileHandle = FileHandle;
Message.Data.CreateProcess.Base = ImageBase;
Message.Data.CreateProcess.EntryPoint = NULL; //
Status = LpcSendDebugMessagePort(pParentProcess->DebugPort,
&Message);
}
#endif
PspRunCreateProcessNotifyRoutines(Process, TRUE);
/*
* FIXME - the handle should be created not before this point!
*/
#if 0
Status = ObInsertObject ((PVOID)Process,
NULL,
DesiredAccess,
0,
NULL,
&hProcess);
#endif
if (NT_SUCCESS(Status))
{
_SEH_TRY
{
*ProcessHandle = hProcess;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
}
/*
* don't dereference the debug port, exception port and section object even
* if ObInsertObject() failed, the process is alive! We just couldn't return
* the handle to the caller!
*/
ObDereferenceObject(Process); if (!NT_SUCCESS(Status))
if(pParentProcess != NULL) {
ObDereferenceObject(pParentProcess); DPRINT1("Failed to create process object, Status: 0x%x\n", Status);
goto exitdereferenceobjects;
}
/* Clean up the Object */
DPRINT("Cleaning Process Object\n");
RtlZeroMemory(Process, sizeof(EPROCESS));
/* Inherit stuff from the Parent since we now have the object created */
if (pParentProcess)
{
Process->InheritedFromUniqueProcessId = pParentProcess->UniqueProcessId;
Process->SessionId = pParentProcess->SessionId;
}
/* FIXME: Set up the Quota Block from the Parent
PspInheritQuota(Parent, Process); */
/* FIXME: Set up Dos Device Map from the Parent
ObInheritDeviceMap(Parent, Process) */
/* Set the Process' LPC Ports */
Process->DebugPort = pDebugPort;
Process->ExceptionPort = pExceptionPort;
/* Setup the Lock Event */
DPRINT("Initialzing Process Lock\n");
KeInitializeEvent(&Process->LockEvent, SynchronizationEvent, FALSE);
/* Setup the Thread List Head */
DPRINT("Initialzing Process ThreadListHead\n");
InitializeListHead(&Process->ThreadListHead);
/* Create or Clone the Handle Table */
DPRINT("Initialzing Process Handle Table\n");
ObCreateHandleTable(pParentProcess, InheritObjectTable, Process);
DPRINT("Handle Table: %x\n", Process->ObjectTable);
/* Set Process's Directory Base */
DPRINT("Initialzing Process Directory Base\n");
MmCopyMmInfo(pParentProcess ? pParentProcess : PsInitialSystemProcess,
Process,
&DirectoryTableBase);
/* Now initialize the Kernel Process */
DPRINT("Initialzing Kernel Process\n");
KeInitializeProcess(&Process->Pcb,
PROCESS_PRIO_NORMAL,
Affinity,
DirectoryTableBase);
/* Duplicate Parent Token */
DPRINT("Initialzing Process Token\n");
Status = PspInitializeProcessSecurity(Process, pParentProcess);
if (!NT_SUCCESS(Status))
{
DbgPrint("PspInitializeProcessSecurity failed (Status %x)\n", Status);
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
/* Create the Process' Address Space */
DPRINT("Initialzing Process Address Space\n");
Status = MmCreateProcessAddressSpace(Process, SectionObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create Address Space\n");
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
if (SectionObject)
{
/* Map the System Dll */
DPRINT("Mapping System DLL\n");
LdrpMapSystemDll(Process, NULL);
}
/* Create a handle for the Process */
DPRINT("Initialzing Process CID Handle\n");
Status = PsCreateCidHandle(Process,
PsProcessType,
&Process->UniqueProcessId);
if(!NT_SUCCESS(Status))
{
DPRINT1("Failed to create CID handle (unique process ID)! Status: 0x%x\n", Status);
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
/* FIXME: Insert into Job Object */
/* Create PEB only for User-Mode Processes */
if (pParentProcess)
{
DPRINT("Creating PEB\n");
Status = MmCreatePeb(Process);
if (!NT_SUCCESS(Status))
{
DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status);
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
/* Let's take advantage of this time to kill the reference too */
ObDereferenceObject(pParentProcess);
}
/* W00T! The process can now be activated */
DPRINT("Inserting into Active Process List\n");
ExAcquireFastMutex(&PspActiveProcessMutex);
InsertTailList(&PsActiveProcessHead, &Process->ProcessListEntry);
ExReleaseFastMutex(&PspActiveProcessMutex);
/* FIXME: SeCreateAccessStateEx */
/* Insert the Process into the Object Directory */
DPRINT("Inserting Process Object\n");
Status = ObInsertObject(Process,
NULL,
DesiredAccess,
0,
NULL,
&hProcess);
if (!NT_SUCCESS(Status))
{
DPRINT1("Could not get a handle to the Process Object\n");
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
DPRINT("Done. Returning handle: %x\n", hProcess);
if (NT_SUCCESS(Status))
{
_SEH_TRY
{
*ProcessHandle = hProcess;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
} _SEH_END;
}
/* FIXME: ObGetObjectSecurity(Process, &SecurityDescriptor)
SeAccessCheck
*/
ObReferenceObject(Process);
ObReferenceObject(Process);
return Status; return Status;
exitdereferenceobjects:
if(SectionObject != NULL) ObDereferenceObject(SectionObject);
if(pExceptionPort != NULL) ObDereferenceObject(pExceptionPort);
if(pDebugPort != NULL) ObDereferenceObject(pDebugPort);
if(pParentProcess != NULL) ObDereferenceObject(pParentProcess);
return Status;
} }

View file

@ -13,8 +13,6 @@
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
/* GLOBALS ******************************************************************/
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
/* /*
@ -144,6 +142,66 @@ PsOpenTokenOfProcess(HANDLE ProcessHandle,
return Status; return Status;
} }
NTSTATUS
STDCALL
PspInitializeProcessSecurity(PEPROCESS Process,
PEPROCESS Parent OPTIONAL)
{
NTSTATUS Status = STATUS_SUCCESS;
/* If we have a parent, then duplicate the Token */
if (Parent) {
PTOKEN pNewToken;
PTOKEN pParentToken;
OBJECT_ATTRIBUTES ObjectAttributes;
pParentToken = (PACCESS_TOKEN)Parent->Token;
/* Initialize the Object Attributes */
InitializeObjectAttributes(&ObjectAttributes,
NULL,
0,
NULL,
NULL);
/* Duplicate the Token */
Status = SepDuplicateToken(pParentToken,
&ObjectAttributes,
FALSE,
TokenPrimary,
pParentToken->ImpersonationLevel,
KernelMode,
&pNewToken);
if(!NT_SUCCESS(Status)) {
DPRINT1("Failed to Duplicate Token\n");
return Status;
}
Process->Token = pNewToken;
} else {
#ifdef SCHED_REWRITE
PTOKEN BootToken;
/* No parent, this is the Initial System Process. Assign Boot Token */
BootToken = SepCreateSystemProcessToken();
BootToken->TokenInUse = TRUE;
Process->Token = BootToken;
ObReferenceObject(BootToken);
#else
DPRINT1("PspInitializeProcessSecurity called with no parent.\n");
#endif
}
/* Return to caller */
return Status;
}
NTSTATUS NTSTATUS
STDCALL STDCALL
PspAssignPrimaryToken(PEPROCESS Process, PspAssignPrimaryToken(PEPROCESS Process,

View file

@ -169,6 +169,7 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token,
NTSTATUS NTSTATUS
STDCALL
SepDuplicateToken(PTOKEN Token, SepDuplicateToken(PTOKEN Token,
POBJECT_ATTRIBUTES ObjectAttributes, POBJECT_ATTRIBUTES ObjectAttributes,
BOOLEAN EffectiveOnly, BOOLEAN EffectiveOnly,
@ -300,39 +301,6 @@ SepDuplicateToken(PTOKEN Token,
return(Status); return(Status);
} }
NTSTATUS
SepInitializeNewProcess(struct _EPROCESS* NewProcess,
struct _EPROCESS* ParentProcess)
{
NTSTATUS Status;
PTOKEN pNewToken;
PTOKEN pParentToken;
OBJECT_ATTRIBUTES ObjectAttributes;
pParentToken = (PACCESS_TOKEN) ParentProcess->Token;
InitializeObjectAttributes(&ObjectAttributes,
NULL,
0,
NULL,
NULL);
Status = SepDuplicateToken(pParentToken,
&ObjectAttributes,
FALSE,
TokenPrimary,
pParentToken->ImpersonationLevel,
KernelMode,
&pNewToken);
if ( ! NT_SUCCESS(Status) )
return Status;
NewProcess->Token = pNewToken;
return(STATUS_SUCCESS);
}
/* /*
* @unimplemented * @unimplemented
*/ */
@ -1800,9 +1768,9 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
return Status; return Status;
} }
PTOKEN
NTSTATUS STDCALL
SepCreateSystemProcessToken(struct _EPROCESS* Process) SepCreateSystemProcessToken(VOID)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG uSize; ULONG uSize;
@ -1833,28 +1801,28 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
(PVOID*)&AccessToken); (PVOID*)&AccessToken);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(Status); return NULL;
} }
Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId); Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ObDereferenceObject(AccessToken); ObDereferenceObject(AccessToken);
return(Status); return NULL;
} }
Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId); Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ObDereferenceObject(AccessToken); ObDereferenceObject(AccessToken);
return(Status); return NULL;
} }
Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId); Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ObDereferenceObject(AccessToken); ObDereferenceObject(AccessToken);
return Status; return NULL;
} }
AccessToken->TokenLock = &SepTokenLock; AccessToken->TokenLock = &SepTokenLock;
@ -2002,11 +1970,10 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
if ( ! NT_SUCCESS(Status) ) if ( ! NT_SUCCESS(Status) )
{ {
ObDereferenceObject(AccessToken); ObDereferenceObject(AccessToken);
return Status; return NULL;
} }
Process->Token = AccessToken; return AccessToken;
return(STATUS_SUCCESS);
} }