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/ppool.o \
mm/physical.o \
mm/process.o \
mm/region.o \
mm/rmap.o \
mm/section.o \

View file

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

View file

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

View file

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

View file

@ -37,6 +37,7 @@ typedef ULONG PFN_TYPE, *PPFN_TYPE;
#define MEMORY_AREA_KERNEL_STACK (11)
#define MEMORY_AREA_PAGED_POOL (12)
#define MEMORY_AREA_NO_ACCESS (13)
#define MEMORY_AREA_PEB_OR_TEB (14)
#define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
((x) / (4*1024*1024))
@ -496,6 +497,17 @@ BOOLEAN MmIsAvailableSwapPage(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 *************************************************************/
NTSTATUS MmPageFault(ULONG Cs,
@ -579,6 +591,17 @@ MmCheckForPageOp(PMEMORY_AREA MArea, HANDLE Pid, PVOID Address,
VOID
MmInitializePageOp(VOID);
/* process.c *****************************************************************/
PVOID
STDCALL
MmCreateKernelStack(BOOLEAN GuiStack);
VOID
STDCALL
MmDeleteKernelStack(PVOID Stack,
BOOLEAN GuiStack);
/* balace.c ******************************************************************/
VOID MmInitializeMemoryConsumer(ULONG Consumer,
@ -737,7 +760,11 @@ VOID MmDeletePageTable(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);

View file

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

View file

@ -117,9 +117,7 @@ SepCreateImpersonationTokenDacl(PTOKEN Token,
VOID SepInitializeTokenImplementation(VOID);
NTSTATUS SepCreateSystemProcessToken(struct _EPROCESS* Process);
NTSTATUS SepInitializeNewProcess(struct _EPROCESS* NewProcess,
struct _EPROCESS* ParentProcess);
PTOKEN STDCALL SepCreateSystemProcessToken(VOID);
NTSTATUS SeExchangePrimaryToken(struct _EPROCESS* Process,
PACCESS_TOKEN NewToken,
@ -148,6 +146,16 @@ SepPrivilegeCheck(PTOKEN Token,
ULONG PrivilegeControl,
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
SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN KPROCESSOR_MODE AccessMode,

View file

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

View file

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

View file

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

View file

@ -53,6 +53,35 @@ UpdatePageDirs(PKTHREAD Thread, PKPROCESS Process)
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
STDCALL
KeSetProcess(PKPROCESS Process,
@ -148,6 +177,7 @@ KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE
}
/* Swap the Processes */
DPRINT("Swapping\n");
KiSwapProcess(Process, SavedApcState->Process);
/* Return to old IRQL*/

View file

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

View file

@ -24,6 +24,9 @@ PVOID SystemDllCallbackDispatcher = NULL;
PVOID SystemDllExceptionDispatcher = NULL;
PVOID SystemDllRaiseExceptionDispatcher = NULL;
PVOID LdrpSystemDllBase = NULL;
PVOID LdrpSystemDllSection = NULL;
/* FUNCTIONS *****************************************************************/
PVOID LdrpGetSystemDllExceptionDispatcher(VOID)
@ -51,282 +54,223 @@ PVOID LdrpGetSystemDllRaiseExceptionDispatcher(VOID)
return(SystemDllRaiseExceptionDispatcher);
}
NTSTATUS LdrpMapSystemDll(HANDLE ProcessHandle,
PVOID* LdrStartupAddr)
/*
* 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
*/
NTSTATUS
STDCALL
LdrpGetSystemDllEntryPoints(VOID)
{
CHAR BlockBuffer [1024];
DWORD ImageBase;
ULONG ImageSize;
NTSTATUS Status;
OBJECT_ATTRIBUTES FileObjectAttributes;
HANDLE FileHandle;
HANDLE NTDllSectionHandle;
UNICODE_STRING DllPathname = ROS_STRING_INITIALIZER(L"\\SystemRoot\\system32\\ntdll.dll");
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NTHeaders;
PEPROCESS Process, CurrentProcess;
ANSI_STRING ProcedureName;
ULONG ViewSize;
IO_STATUS_BLOCK Iosb;
ANSI_STRING ProcedureName;
NTSTATUS Status;
/* Retrieve ntdll's startup address */
DPRINT("Getting Entrypoint: %p\n", LdrpSystemDllBase);
RtlInitAnsiString(&ProcedureName, "LdrInitializeThunk");
Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
&ProcedureName,
0,
&SystemDllEntryPoint);
if (!NT_SUCCESS(Status)) {
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
return (Status);
}
/*
* 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;
}
Status = ZwReadFile(FileHandle,
0,
0,
0,
&Iosb,
BlockBuffer,
sizeof(BlockBuffer),
0,
0);
if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer))
{
DPRINT1("NTDLL header read failed (Status %x)\n", Status);
ZwClose(FileHandle);
return Status;
}
/* Get User APC Dispatcher */
DPRINT("Getting Entrypoint\n");
RtlInitAnsiString(&ProcedureName, "KiUserApcDispatcher");
Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
&ProcedureName,
0,
&SystemDllApcDispatcher);
if (!NT_SUCCESS(Status)) {
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
return (Status);
}
/* Get Exception Dispatcher */
DPRINT("Getting Entrypoint\n");
RtlInitAnsiString(&ProcedureName, "KiUserExceptionDispatcher");
Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
&ProcedureName,
0,
&SystemDllExceptionDispatcher);
if (!NT_SUCCESS(Status)) {
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
return (Status);
}
/* Get Callback Dispatcher */
DPRINT("Getting Entrypoint\n");
RtlInitAnsiString(&ProcedureName, "KiUserCallbackDispatcher");
Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
&ProcedureName,
0,
&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);
}
/*
* FIXME: this will fail if the NT headers are
* 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);
}
/* Return success */
return(STATUS_SUCCESS);
}
DPRINT("Referencing process\n");
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_ALL_ACCESS,
PsProcessType,
KernelMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("ObReferenceObjectByProcess() failed (Status %x)\n", Status);
return(Status);
}
NTSTATUS
STDCALL
LdrpMapSystemDll(PEPROCESS Process,
PVOID *DllBase)
{
NTSTATUS Status;
ULONG ViewSize = 0;
PVOID ImageBase = 0;
/* Map the System DLL */
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();
if (Process != CurrentProcess)
{
DPRINT("Attaching to Process\n");
KeAttachProcess(&Process->Pcb);
NTSTATUS
STDCALL
LdrpInitializeSystemDll(VOID)
{
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;
}
/*
* retrieve ntdll's startup address
*/
if (SystemDllEntryPoint == NULL)
{
RtlInitAnsiString (&ProcedureName,
"LdrInitializeThunk");
Status = LdrGetProcedureAddress ((PVOID)ImageBase,
&ProcedureName,
0,
&SystemDllEntryPoint);
if (!NT_SUCCESS(Status))
{
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
if (Process != CurrentProcess)
{
KeDetachProcess();
}
ObDereferenceObject(Process);
ZwClose(NTDllSectionHandle);
return (Status);
}
*LdrStartupAddr = SystemDllEntryPoint;
}
/*
* Retrieve the offset of the APC dispatcher from NTDLL
*/
if (SystemDllApcDispatcher == NULL)
{
RtlInitAnsiString (&ProcedureName,
"KiUserApcDispatcher");
Status = LdrGetProcedureAddress ((PVOID)ImageBase,
&ProcedureName,
0,
&SystemDllApcDispatcher);
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 exception dispatcher from NTDLL
*/
if (SystemDllExceptionDispatcher == NULL)
{
RtlInitAnsiString (&ProcedureName,
"KiUserExceptionDispatcher");
Status = LdrGetProcedureAddress ((PVOID)ImageBase,
&ProcedureName,
0,
&SystemDllExceptionDispatcher);
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 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);
/* Load NTDLL is valid */
DPRINT("Reading NTDLL\n");
Status = ZwReadFile(FileHandle,
0,
0,
0,
&Iosb,
BlockBuffer,
sizeof(BlockBuffer),
0,
0);
if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer)) {
DPRINT1("NTDLL header read failed (Status %x)\n", Status);
ZwClose(FileHandle);
return Status;
}
/* Check if it's valid */
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);
}
/* 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);
/* Reference the Section */
DPRINT("ObReferenceObjectByHandle section: %d\n", NTDllSectionHandle);
Status = ObReferenceObjectByHandle(NTDllSectionHandle,
SECTION_ALL_ACCESS,
MmSectionObjectType,
KernelMode,
(PVOID*)&LdrpSystemDllSection,
NULL);
if (!NT_SUCCESS(Status)) {
DPRINT1("NTDLL section reference failed (Status %x)\n", Status);
return(Status);
}
/* Map it */
LdrpMapSystemDll(PsGetCurrentProcess(), &LdrpSystemDllBase);
DPRINT("LdrpSystemDllBase: %x\n", LdrpSystemDllBase);
/* Now get the Entrypoints */
LdrpGetSystemDllEntryPoints();
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -319,9 +319,12 @@ NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process)
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;
ULONG i, j;
PFN_TYPE Pfn[7];
@ -389,8 +392,9 @@ NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest)
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);
}

View file

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

View file

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

View file

@ -473,7 +473,6 @@ NtCreateThread (
UserMode,
NULL );
KeInsertQueueApc(LdrInitApc, NULL, NULL, IO_NO_INCREMENT);
/*
* 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,

View file

@ -41,8 +41,7 @@ static PCREATE_PROCESS_NOTIFY_ROUTINE
PiProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
static PLOAD_IMAGE_NOTIFY_ROUTINE
PiLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT];
/* FUNCTIONS *****************************************************************/
PEPROCESS
@ -113,8 +112,7 @@ PiKillMostProcesses(VOID)
PLIST_ENTRY current_entry;
PEPROCESS current;
ExAcquireFastMutex(&PspActiveProcessMutex);
ExAcquireFastMutex(&PspActiveProcessMutex);
current_entry = PsActiveProcessHead.Flink;
while (current_entry != &PsActiveProcessHead)
{
@ -271,8 +269,16 @@ PsInitProcessManagment(VOID)
InsertHeadList(&PsActiveProcessHead,
&PsInitialSystemProcess->ProcessListEntry);
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
@ -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
KeGetCurrentProcess(VOID)
/*
@ -445,472 +358,276 @@ IoGetCurrentProcess(VOID)
}
NTSTATUS
STDCALL
PspCreateProcess(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess OPTIONAL,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL)
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess OPTIONAL,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL)
{
HANDLE hProcess;
PEPROCESS Process;
PEPROCESS pParentProcess;
PKPROCESS KProcess;
PVOID LdrStartupAddr;
PVOID BaseAddress;
PMEMORY_AREA MemoryArea;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
KPROCESSOR_MODE PreviousMode;
PVOID ImageBase = NULL;
PEPORT pDebugPort = NULL;
PEPORT pExceptionPort = NULL;
PSECTION_OBJECT SectionObject = NULL;
NTSTATUS Status = STATUS_SUCCESS;
HANDLE hProcess;
PEPROCESS Process;
PEPROCESS pParentProcess;
PEPORT pDebugPort = NULL;
PEPORT pExceptionPort = NULL;
PSECTION_OBJECT SectionObject = NULL;
NTSTATUS Status = STATUS_SUCCESS;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PHYSICAL_ADDRESS DirectoryTableBase;
KAFFINITY Affinity;
DirectoryTableBase.QuadPart = (ULONGLONG)0;
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;
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);
}
}
else
{
pParentProcess = NULL;
}
/* Add the debug port */
if (DebugPort != NULL)
{
Status = ObReferenceObjectByHandle(DebugPort,
PORT_ALL_ACCESS,
LpcPortObjectType,
PreviousMode,
(PVOID*)&pDebugPort,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference the debug port: Status: 0x%x\n", Status);
goto exitdereferenceobjects;
}
}
/*
* Add the debug port
*/
if (DebugPort != NULL)
{
Status = ObReferenceObjectByHandle(DebugPort,
PORT_ALL_ACCESS,
LpcPortObjectType,
PreviousMode,
(PVOID*)&pDebugPort,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference the debug port: Status: 0x%x\n", Status);
goto exitdereferenceobjects;
}
}
/* Add the exception port */
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;
}
}
/*
* Add the exception port
*/
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)
{
/* Add the Section */
if (SectionHandle != NULL)
{
Status = ObReferenceObjectByHandle(SectionHandle,
0,
MmSectionObjectType,
PreviousMode,
(PVOID*)&SectionObject,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference process image section: Status: 0x%x\n", Status);
goto exitdereferenceobjects;
}
}
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference process image section: Status: 0x%x\n", Status);
goto exitdereferenceobjects;
}
}
Status = ObCreateObject(PreviousMode,
PsProcessType,
ObjectAttributes,
PreviousMode,
NULL,
sizeof(EPROCESS),
0,
0,
(PVOID*)&Process);
if (!NT_SUCCESS(Status))
{
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!
*/
/* Create the Object */
DPRINT("Creating Process Object\n");
Status = ObCreateObject(PreviousMode,
PsProcessType,
ObjectAttributes,
PreviousMode,
NULL,
sizeof(EPROCESS),
0,
0,
(PVOID*)&Process);
ObDereferenceObject(Process);
if(pParentProcess != NULL)
ObDereferenceObject(pParentProcess);
if (!NT_SUCCESS(Status))
{
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;
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
#include <internal/debug.h>
/* GLOBALS ******************************************************************/
/* FUNCTIONS *****************************************************************/
/*
@ -144,6 +142,66 @@ PsOpenTokenOfProcess(HANDLE ProcessHandle,
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
STDCALL
PspAssignPrimaryToken(PEPROCESS Process,

View file

@ -169,6 +169,7 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token,
NTSTATUS
STDCALL
SepDuplicateToken(PTOKEN Token,
POBJECT_ATTRIBUTES ObjectAttributes,
BOOLEAN EffectiveOnly,
@ -300,39 +301,6 @@ SepDuplicateToken(PTOKEN Token,
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
*/
@ -1800,9 +1768,9 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
return Status;
}
NTSTATUS
SepCreateSystemProcessToken(struct _EPROCESS* Process)
PTOKEN
STDCALL
SepCreateSystemProcessToken(VOID)
{
NTSTATUS Status;
ULONG uSize;
@ -1833,28 +1801,28 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
(PVOID*)&AccessToken);
if (!NT_SUCCESS(Status))
{
return(Status);
return NULL;
}
Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(AccessToken);
return(Status);
return NULL;
}
Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(AccessToken);
return(Status);
return NULL;
}
Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(AccessToken);
return Status;
return NULL;
}
AccessToken->TokenLock = &SepTokenLock;
@ -2002,11 +1970,10 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
if ( ! NT_SUCCESS(Status) )
{
ObDereferenceObject(AccessToken);
return Status;
return NULL;
}
Process->Token = AccessToken;
return(STATUS_SUCCESS);
return AccessToken;
}