mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
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:
parent
a9920ccd9d
commit
7740536c18
20 changed files with 663 additions and 883 deletions
|
@ -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 \
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -111,7 +111,7 @@ NtWaitForMultipleObjects(IN ULONG ObjectCount,
|
|||
UserRequest,
|
||||
PreviousMode,
|
||||
Alertable,
|
||||
TimeOut,
|
||||
TimeOut,
|
||||
WaitBlockArray);
|
||||
|
||||
/* dereference all objects */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue