mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +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/pool.o \
|
||||||
mm/ppool.o \
|
mm/ppool.o \
|
||||||
mm/physical.o \
|
mm/physical.o \
|
||||||
|
mm/process.o \
|
||||||
mm/region.o \
|
mm/region.o \
|
||||||
mm/rmap.o \
|
mm/rmap.o \
|
||||||
mm/section.o \
|
mm/section.o \
|
||||||
|
|
|
@ -494,7 +494,7 @@ ExpInitializeExecutive(VOID)
|
||||||
|
|
||||||
/* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
|
/* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
|
||||||
IoInit();
|
IoInit();
|
||||||
|
|
||||||
/* TBD */
|
/* TBD */
|
||||||
PoInit((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock, ForceAcpiDisable);
|
PoInit((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock, ForceAcpiDisable);
|
||||||
|
|
||||||
|
@ -562,6 +562,9 @@ ExpInitializeExecutive(VOID)
|
||||||
|
|
||||||
/* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
|
/* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
|
||||||
IoInit3();
|
IoInit3();
|
||||||
|
|
||||||
|
/* Load the System DLL and its Entrypoints */
|
||||||
|
LdrpInitializeSystemDll();
|
||||||
|
|
||||||
/* Initialize the Default Locale */
|
/* Initialize the Default Locale */
|
||||||
PiInitDefaultLocale();
|
PiInitDefaultLocale();
|
||||||
|
|
|
@ -259,7 +259,14 @@ FASTCALL
|
||||||
KiAbortWaitThread(PKTHREAD Thread,
|
KiAbortWaitThread(PKTHREAD Thread,
|
||||||
NTSTATUS WaitStatus,
|
NTSTATUS WaitStatus,
|
||||||
KPRIORITY Increment);
|
KPRIORITY Increment);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
KeInitializeProcess(struct _KPROCESS *Process,
|
||||||
|
KPRIORITY Priority,
|
||||||
|
KAFFINITY Affinity,
|
||||||
|
LARGE_INTEGER DirectoryTableBase);
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
STDCALL
|
STDCALL
|
||||||
KeForceResumeThread(IN PKTHREAD Thread);
|
KeForceResumeThread(IN PKTHREAD Thread);
|
||||||
|
|
|
@ -34,10 +34,18 @@ LdrInitModuleManagement (
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
LdrpMapSystemDll (
|
STDCALL
|
||||||
HANDLE ProcessHandle,
|
LdrpMapSystemDll(PEPROCESS Process,
|
||||||
PVOID * LdrStartupAddress
|
PVOID *DllBase);
|
||||||
);
|
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
LdrpInitializeSystemDll(VOID);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
LdrpGetSystemDllEntryPoints(VOID);
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
LdrpGetSystemDllEntryPoint (VOID);
|
LdrpGetSystemDllEntryPoint (VOID);
|
||||||
PVOID
|
PVOID
|
||||||
|
|
|
@ -37,6 +37,7 @@ typedef ULONG PFN_TYPE, *PPFN_TYPE;
|
||||||
#define MEMORY_AREA_KERNEL_STACK (11)
|
#define MEMORY_AREA_KERNEL_STACK (11)
|
||||||
#define MEMORY_AREA_PAGED_POOL (12)
|
#define MEMORY_AREA_PAGED_POOL (12)
|
||||||
#define MEMORY_AREA_NO_ACCESS (13)
|
#define MEMORY_AREA_NO_ACCESS (13)
|
||||||
|
#define MEMORY_AREA_PEB_OR_TEB (14)
|
||||||
|
|
||||||
#define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
|
#define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
|
||||||
((x) / (4*1024*1024))
|
((x) / (4*1024*1024))
|
||||||
|
@ -496,6 +497,17 @@ BOOLEAN MmIsAvailableSwapPage(VOID);
|
||||||
|
|
||||||
VOID MmShowOutOfSpaceMessagePagingFile(VOID);
|
VOID MmShowOutOfSpaceMessagePagingFile(VOID);
|
||||||
|
|
||||||
|
/* process.c ****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
MmCreateProcessAddressSpace(IN struct _EPROCESS* Process,
|
||||||
|
IN PSECTION_OBJECT Section OPTIONAL);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
MmCreatePeb(PEPROCESS Process);
|
||||||
|
|
||||||
/* i386/pfault.c *************************************************************/
|
/* i386/pfault.c *************************************************************/
|
||||||
|
|
||||||
NTSTATUS MmPageFault(ULONG Cs,
|
NTSTATUS MmPageFault(ULONG Cs,
|
||||||
|
@ -579,6 +591,17 @@ MmCheckForPageOp(PMEMORY_AREA MArea, HANDLE Pid, PVOID Address,
|
||||||
VOID
|
VOID
|
||||||
MmInitializePageOp(VOID);
|
MmInitializePageOp(VOID);
|
||||||
|
|
||||||
|
/* process.c *****************************************************************/
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
STDCALL
|
||||||
|
MmCreateKernelStack(BOOLEAN GuiStack);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
MmDeleteKernelStack(PVOID Stack,
|
||||||
|
BOOLEAN GuiStack);
|
||||||
|
|
||||||
/* balace.c ******************************************************************/
|
/* balace.c ******************************************************************/
|
||||||
|
|
||||||
VOID MmInitializeMemoryConsumer(ULONG Consumer,
|
VOID MmInitializeMemoryConsumer(ULONG Consumer,
|
||||||
|
@ -737,7 +760,11 @@ VOID MmDeletePageTable(struct _EPROCESS* Process, PVOID Address);
|
||||||
|
|
||||||
PFN_TYPE MmGetPfnForProcess(struct _EPROCESS* Process, PVOID Address);
|
PFN_TYPE MmGetPfnForProcess(struct _EPROCESS* Process, PVOID Address);
|
||||||
|
|
||||||
NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src, struct _EPROCESS* Dest);
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
MmCopyMmInfo(struct _EPROCESS* Src,
|
||||||
|
struct _EPROCESS* Dest,
|
||||||
|
PPHYSICAL_ADDRESS DirectoryTableBase);
|
||||||
|
|
||||||
NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
|
NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
|
||||||
|
|
||||||
|
|
|
@ -492,6 +492,11 @@ VOID STDCALL PsExitSpecialApc(PKAPC Apc,
|
||||||
PVOID *NormalContext,
|
PVOID *NormalContext,
|
||||||
PVOID *SystemArgument1,
|
PVOID *SystemArgument1,
|
||||||
PVOID *SystemArgument2);
|
PVOID *SystemArgument2);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
PspInitializeProcessSecurity(PEPROCESS Process,
|
||||||
|
PEPROCESS Parent OPTIONAL);
|
||||||
|
|
||||||
#define THREAD_STATE_INITIALIZED (0)
|
#define THREAD_STATE_INITIALIZED (0)
|
||||||
#define THREAD_STATE_READY (1)
|
#define THREAD_STATE_READY (1)
|
||||||
|
|
|
@ -117,9 +117,7 @@ SepCreateImpersonationTokenDacl(PTOKEN Token,
|
||||||
|
|
||||||
VOID SepInitializeTokenImplementation(VOID);
|
VOID SepInitializeTokenImplementation(VOID);
|
||||||
|
|
||||||
NTSTATUS SepCreateSystemProcessToken(struct _EPROCESS* Process);
|
PTOKEN STDCALL SepCreateSystemProcessToken(VOID);
|
||||||
NTSTATUS SepInitializeNewProcess(struct _EPROCESS* NewProcess,
|
|
||||||
struct _EPROCESS* ParentProcess);
|
|
||||||
|
|
||||||
NTSTATUS SeExchangePrimaryToken(struct _EPROCESS* Process,
|
NTSTATUS SeExchangePrimaryToken(struct _EPROCESS* Process,
|
||||||
PACCESS_TOKEN NewToken,
|
PACCESS_TOKEN NewToken,
|
||||||
|
@ -148,6 +146,16 @@ SepPrivilegeCheck(PTOKEN Token,
|
||||||
ULONG PrivilegeControl,
|
ULONG PrivilegeControl,
|
||||||
KPROCESSOR_MODE PreviousMode);
|
KPROCESSOR_MODE PreviousMode);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
SepDuplicateToken(PTOKEN Token,
|
||||||
|
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
BOOLEAN EffectiveOnly,
|
||||||
|
TOKEN_TYPE TokenType,
|
||||||
|
SECURITY_IMPERSONATION_LEVEL Level,
|
||||||
|
KPROCESSOR_MODE PreviousMode,
|
||||||
|
PTOKEN* NewAccessToken);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||||
IN KPROCESSOR_MODE AccessMode,
|
IN KPROCESSOR_MODE AccessMode,
|
||||||
|
|
|
@ -756,6 +756,7 @@ KiInitializeUserApc(IN PVOID Reserved,
|
||||||
Esp[4] = (ULONG)SystemArgument2;
|
Esp[4] = (ULONG)SystemArgument2;
|
||||||
Esp[5] = (ULONG)Context;
|
Esp[5] = (ULONG)Context;
|
||||||
TrapFrame->Eip = (ULONG)LdrpGetSystemDllApcDispatcher();
|
TrapFrame->Eip = (ULONG)LdrpGetSystemDllApcDispatcher();
|
||||||
|
DPRINT("TrapFrame->Eip: %x\n", TrapFrame->Eip);
|
||||||
TrapFrame->Esp = (ULONG)Esp;
|
TrapFrame->Esp = (ULONG)Esp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,13 +205,14 @@ KiBlockThread(PNTSTATUS Status,
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Set the Thread Data as Requested */
|
/* Set the Thread Data as Requested */
|
||||||
DPRINT("Dispatching Thread as blocked\n");
|
DPRINT("Dispatching Thread as blocked: %d\n", Thread->WaitStatus);
|
||||||
Thread->Alertable = Alertable;
|
Thread->Alertable = Alertable;
|
||||||
Thread->WaitMode = (UCHAR)WaitMode;
|
Thread->WaitMode = (UCHAR)WaitMode;
|
||||||
Thread->WaitReason = WaitReason;
|
Thread->WaitReason = WaitReason;
|
||||||
|
|
||||||
/* Dispatch it and return status */
|
/* Dispatch it and return status */
|
||||||
KiDispatchThreadNoLock(THREAD_STATE_BLOCKED);
|
KiDispatchThreadNoLock(THREAD_STATE_BLOCKED);
|
||||||
|
DPRINT("Dispatching Thread as blocked: %d\n", Thread->WaitStatus);
|
||||||
if (Status != NULL) *Status = Thread->WaitStatus;
|
if (Status != NULL) *Status = Thread->WaitStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
|
#define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
|
||||||
|
|
||||||
|
|
||||||
ULONG NtMajorVersion = 4;
|
ULONG NtMajorVersion = 5;
|
||||||
ULONG NtMinorVersion = 0;
|
ULONG NtMinorVersion = 0;
|
||||||
ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(6, 0);
|
ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(6, 0);
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
|
@ -53,6 +53,35 @@ UpdatePageDirs(PKTHREAD Thread, PKPROCESS Process)
|
||||||
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
|
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
STDCALL
|
||||||
|
KeInitializeProcess(PKPROCESS Process,
|
||||||
|
KPRIORITY Priority,
|
||||||
|
KAFFINITY Affinity,
|
||||||
|
LARGE_INTEGER DirectoryTableBase)
|
||||||
|
{
|
||||||
|
DPRINT1("KeInitializeProcess. Process: %x, DirectoryTableBase: %x\n", Process, DirectoryTableBase);
|
||||||
|
|
||||||
|
/* Initialize the Dispatcher Header */
|
||||||
|
KeInitializeDispatcherHeader(&Process->DispatcherHeader,
|
||||||
|
ProcessObject,
|
||||||
|
sizeof(KPROCESS),
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
/* Initialize Scheduler Data, Disable Alignment Faults and Set the PDE */
|
||||||
|
Process->Affinity = Affinity;
|
||||||
|
Process->BasePriority = Priority;
|
||||||
|
Process->ThreadQuantum = 6;
|
||||||
|
Process->DirectoryTableBase = DirectoryTableBase;
|
||||||
|
Process->AutoAlignment = TRUE;
|
||||||
|
Process->IopmOffset = 0xFFFF;
|
||||||
|
Process->State = PROCESS_STATE_ACTIVE;
|
||||||
|
|
||||||
|
/* Initialize the Thread List */
|
||||||
|
InitializeListHead(&Process->ThreadListHead);
|
||||||
|
DPRINT1("The Process has now been initalized with the Kernel\n");
|
||||||
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
STDCALL
|
STDCALL
|
||||||
KeSetProcess(PKPROCESS Process,
|
KeSetProcess(PKPROCESS Process,
|
||||||
|
@ -148,6 +177,7 @@ KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Swap the Processes */
|
/* Swap the Processes */
|
||||||
|
DPRINT("Swapping\n");
|
||||||
KiSwapProcess(Process, SavedApcState->Process);
|
KiSwapProcess(Process, SavedApcState->Process);
|
||||||
|
|
||||||
/* Return to old IRQL*/
|
/* Return to old IRQL*/
|
||||||
|
|
|
@ -445,7 +445,6 @@ KeWaitForMultipleObjects(ULONG Count,
|
||||||
*/
|
*/
|
||||||
if (CurrentObject->Type == IO_TYPE_FILE) {
|
if (CurrentObject->Type == IO_TYPE_FILE) {
|
||||||
|
|
||||||
DPRINT1("Hack used: %x\n", &((PFILE_OBJECT)CurrentObject)->Event);
|
|
||||||
CurrentObject = (PDISPATCHER_HEADER)(&((PFILE_OBJECT)CurrentObject)->Event);
|
CurrentObject = (PDISPATCHER_HEADER)(&((PFILE_OBJECT)CurrentObject)->Event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +570,7 @@ KeWaitForMultipleObjects(ULONG Count,
|
||||||
DPRINT("Waking Queue\n");
|
DPRINT("Waking Queue\n");
|
||||||
KiWakeQueue(CurrentThread->Queue);
|
KiWakeQueue(CurrentThread->Queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Block the Thread */
|
/* Block the Thread */
|
||||||
DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode, WaitReason, KeGetCurrentThread());
|
DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode, WaitReason, KeGetCurrentThread());
|
||||||
KiBlockThread(&Status,
|
KiBlockThread(&Status,
|
||||||
|
|
|
@ -24,6 +24,9 @@ PVOID SystemDllCallbackDispatcher = NULL;
|
||||||
PVOID SystemDllExceptionDispatcher = NULL;
|
PVOID SystemDllExceptionDispatcher = NULL;
|
||||||
PVOID SystemDllRaiseExceptionDispatcher = NULL;
|
PVOID SystemDllRaiseExceptionDispatcher = NULL;
|
||||||
|
|
||||||
|
PVOID LdrpSystemDllBase = NULL;
|
||||||
|
PVOID LdrpSystemDllSection = NULL;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
PVOID LdrpGetSystemDllExceptionDispatcher(VOID)
|
PVOID LdrpGetSystemDllExceptionDispatcher(VOID)
|
||||||
|
@ -51,282 +54,223 @@ PVOID LdrpGetSystemDllRaiseExceptionDispatcher(VOID)
|
||||||
return(SystemDllRaiseExceptionDispatcher);
|
return(SystemDllRaiseExceptionDispatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS LdrpMapSystemDll(HANDLE ProcessHandle,
|
NTSTATUS
|
||||||
PVOID* LdrStartupAddr)
|
STDCALL
|
||||||
/*
|
LdrpGetSystemDllEntryPoints(VOID)
|
||||||
* FUNCTION: LdrpMapSystemDll maps the system dll into the specified process
|
|
||||||
* address space and returns its startup address.
|
|
||||||
* PARAMETERS:
|
|
||||||
* ProcessHandle
|
|
||||||
* Points to the process to map the system dll into
|
|
||||||
*
|
|
||||||
* LdrStartupAddress
|
|
||||||
* Receives the startup address of the system dll on function
|
|
||||||
* completion
|
|
||||||
*
|
|
||||||
* RETURNS: Status
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
CHAR BlockBuffer [1024];
|
ANSI_STRING ProcedureName;
|
||||||
DWORD ImageBase;
|
NTSTATUS Status;
|
||||||
ULONG ImageSize;
|
|
||||||
NTSTATUS Status;
|
/* Retrieve ntdll's startup address */
|
||||||
OBJECT_ATTRIBUTES FileObjectAttributes;
|
DPRINT("Getting Entrypoint: %p\n", LdrpSystemDllBase);
|
||||||
HANDLE FileHandle;
|
RtlInitAnsiString(&ProcedureName, "LdrInitializeThunk");
|
||||||
HANDLE NTDllSectionHandle;
|
Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
|
||||||
UNICODE_STRING DllPathname = ROS_STRING_INITIALIZER(L"\\SystemRoot\\system32\\ntdll.dll");
|
&ProcedureName,
|
||||||
PIMAGE_DOS_HEADER DosHeader;
|
0,
|
||||||
PIMAGE_NT_HEADERS NTHeaders;
|
&SystemDllEntryPoint);
|
||||||
PEPROCESS Process, CurrentProcess;
|
|
||||||
ANSI_STRING ProcedureName;
|
if (!NT_SUCCESS(Status)) {
|
||||||
ULONG ViewSize;
|
|
||||||
IO_STATUS_BLOCK Iosb;
|
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
||||||
|
return (Status);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/* Get User APC Dispatcher */
|
||||||
* Locate and open NTDLL to determine ImageBase
|
DPRINT("Getting Entrypoint\n");
|
||||||
* and LdrStartup
|
RtlInitAnsiString(&ProcedureName, "KiUserApcDispatcher");
|
||||||
*/
|
Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
|
||||||
InitializeObjectAttributes(&FileObjectAttributes,
|
&ProcedureName,
|
||||||
&DllPathname,
|
0,
|
||||||
0,
|
&SystemDllApcDispatcher);
|
||||||
NULL,
|
|
||||||
NULL);
|
if (!NT_SUCCESS(Status)) {
|
||||||
DPRINT("Opening NTDLL\n");
|
|
||||||
Status = ZwOpenFile(&FileHandle,
|
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
||||||
FILE_READ_ACCESS,
|
return (Status);
|
||||||
&FileObjectAttributes,
|
}
|
||||||
&Iosb,
|
|
||||||
FILE_SHARE_READ,
|
/* Get Exception Dispatcher */
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
DPRINT("Getting Entrypoint\n");
|
||||||
if (!NT_SUCCESS(Status))
|
RtlInitAnsiString(&ProcedureName, "KiUserExceptionDispatcher");
|
||||||
{
|
Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
|
||||||
DPRINT1("NTDLL open failed (Status %x)\n", Status);
|
&ProcedureName,
|
||||||
return Status;
|
0,
|
||||||
}
|
&SystemDllExceptionDispatcher);
|
||||||
Status = ZwReadFile(FileHandle,
|
|
||||||
0,
|
if (!NT_SUCCESS(Status)) {
|
||||||
0,
|
|
||||||
0,
|
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
||||||
&Iosb,
|
return (Status);
|
||||||
BlockBuffer,
|
}
|
||||||
sizeof(BlockBuffer),
|
|
||||||
0,
|
/* Get Callback Dispatcher */
|
||||||
0);
|
DPRINT("Getting Entrypoint\n");
|
||||||
if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer))
|
RtlInitAnsiString(&ProcedureName, "KiUserCallbackDispatcher");
|
||||||
{
|
Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
|
||||||
DPRINT1("NTDLL header read failed (Status %x)\n", Status);
|
&ProcedureName,
|
||||||
ZwClose(FileHandle);
|
0,
|
||||||
return Status;
|
&SystemDllCallbackDispatcher);
|
||||||
}
|
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
|
||||||
|
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
||||||
|
return (Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Raise Exception Dispatcher */
|
||||||
|
DPRINT("Getting Entrypoint\n");
|
||||||
|
RtlInitAnsiString(&ProcedureName, "KiRaiseUserExceptionDispatcher");
|
||||||
|
Status = LdrGetProcedureAddress((PVOID)LdrpSystemDllBase,
|
||||||
|
&ProcedureName,
|
||||||
|
0,
|
||||||
|
&SystemDllRaiseExceptionDispatcher);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
|
||||||
|
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
||||||
|
return (Status);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/* Return success */
|
||||||
* FIXME: this will fail if the NT headers are
|
return(STATUS_SUCCESS);
|
||||||
* more than 1024 bytes from start.
|
}
|
||||||
*/
|
|
||||||
DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
|
|
||||||
NTHeaders = (PIMAGE_NT_HEADERS) (BlockBuffer + DosHeader->e_lfanew);
|
|
||||||
if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
|
||||||
|| (DosHeader->e_lfanew == 0L)
|
|
||||||
|| (*(PULONG) NTHeaders != IMAGE_NT_SIGNATURE))
|
|
||||||
{
|
|
||||||
DPRINT1("NTDLL format invalid\n");
|
|
||||||
ZwClose(FileHandle);
|
|
||||||
return(STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
ImageBase = NTHeaders->OptionalHeader.ImageBase;
|
|
||||||
ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a section for NTDLL
|
|
||||||
*/
|
|
||||||
DPRINT("Creating section\n");
|
|
||||||
Status = ZwCreateSection(&NTDllSectionHandle,
|
|
||||||
SECTION_ALL_ACCESS,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
PAGE_READONLY,
|
|
||||||
SEC_IMAGE | SEC_COMMIT,
|
|
||||||
FileHandle);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("NTDLL create section failed (Status %x)\n", Status);
|
|
||||||
ZwClose(FileHandle);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
ZwClose(FileHandle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map the NTDLL into the process
|
|
||||||
*/
|
|
||||||
ViewSize = 0;
|
|
||||||
ImageBase = 0;
|
|
||||||
Status = ZwMapViewOfSection(NTDllSectionHandle,
|
|
||||||
ProcessHandle,
|
|
||||||
(PVOID*)&ImageBase,
|
|
||||||
0,
|
|
||||||
ViewSize,
|
|
||||||
NULL,
|
|
||||||
&ViewSize,
|
|
||||||
0,
|
|
||||||
MEM_COMMIT,
|
|
||||||
PAGE_READWRITE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("NTDLL map view of secion failed (Status %x)", Status);
|
|
||||||
ZwClose(NTDllSectionHandle);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Referencing process\n");
|
NTSTATUS
|
||||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
STDCALL
|
||||||
PROCESS_ALL_ACCESS,
|
LdrpMapSystemDll(PEPROCESS Process,
|
||||||
PsProcessType,
|
PVOID *DllBase)
|
||||||
KernelMode,
|
{
|
||||||
(PVOID*)&Process,
|
NTSTATUS Status;
|
||||||
NULL);
|
ULONG ViewSize = 0;
|
||||||
if (!NT_SUCCESS(Status))
|
PVOID ImageBase = 0;
|
||||||
{
|
|
||||||
DPRINT1("ObReferenceObjectByProcess() failed (Status %x)\n", Status);
|
/* Map the System DLL */
|
||||||
return(Status);
|
DPRINT("Mapping System DLL\n");
|
||||||
}
|
Status = MmMapViewOfSection(LdrpSystemDllSection,
|
||||||
|
Process,
|
||||||
|
(PVOID*)&ImageBase,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&ViewSize,
|
||||||
|
0,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
|
||||||
|
DPRINT1("Failed to map System DLL Into Process\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DllBase) *DllBase = ImageBase;
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
CurrentProcess = PsGetCurrentProcess();
|
NTSTATUS
|
||||||
if (Process != CurrentProcess)
|
STDCALL
|
||||||
{
|
LdrpInitializeSystemDll(VOID)
|
||||||
DPRINT("Attaching to Process\n");
|
{
|
||||||
KeAttachProcess(&Process->Pcb);
|
UNICODE_STRING DllPathname = ROS_STRING_INITIALIZER(L"\\SystemRoot\\system32\\ntdll.dll");
|
||||||
|
OBJECT_ATTRIBUTES FileObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK Iosb;
|
||||||
|
HANDLE FileHandle;
|
||||||
|
HANDLE NTDllSectionHandle;
|
||||||
|
NTSTATUS Status;
|
||||||
|
CHAR BlockBuffer[1024];
|
||||||
|
PIMAGE_DOS_HEADER DosHeader;
|
||||||
|
PIMAGE_NT_HEADERS NTHeaders;
|
||||||
|
|
||||||
|
/* Locate and open NTDLL to determine ImageBase and LdrStartup */
|
||||||
|
InitializeObjectAttributes(&FileObjectAttributes,
|
||||||
|
&DllPathname,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
DPRINT("Opening NTDLL\n");
|
||||||
|
Status = ZwOpenFile(&FileHandle,
|
||||||
|
FILE_READ_ACCESS,
|
||||||
|
&FileObjectAttributes,
|
||||||
|
&Iosb,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
DPRINT1("NTDLL open failed (Status %x)\n", Status);
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Load NTDLL is valid */
|
||||||
* retrieve ntdll's startup address
|
DPRINT("Reading NTDLL\n");
|
||||||
*/
|
Status = ZwReadFile(FileHandle,
|
||||||
if (SystemDllEntryPoint == NULL)
|
0,
|
||||||
{
|
0,
|
||||||
RtlInitAnsiString (&ProcedureName,
|
0,
|
||||||
"LdrInitializeThunk");
|
&Iosb,
|
||||||
Status = LdrGetProcedureAddress ((PVOID)ImageBase,
|
BlockBuffer,
|
||||||
&ProcedureName,
|
sizeof(BlockBuffer),
|
||||||
0,
|
0,
|
||||||
&SystemDllEntryPoint);
|
0);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer)) {
|
||||||
{
|
|
||||||
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
DPRINT1("NTDLL header read failed (Status %x)\n", Status);
|
||||||
if (Process != CurrentProcess)
|
ZwClose(FileHandle);
|
||||||
{
|
return Status;
|
||||||
KeDetachProcess();
|
}
|
||||||
}
|
|
||||||
ObDereferenceObject(Process);
|
/* Check if it's valid */
|
||||||
ZwClose(NTDllSectionHandle);
|
DosHeader = (PIMAGE_DOS_HEADER)BlockBuffer;
|
||||||
return (Status);
|
NTHeaders = (PIMAGE_NT_HEADERS)(BlockBuffer + DosHeader->e_lfanew);
|
||||||
}
|
|
||||||
*LdrStartupAddr = SystemDllEntryPoint;
|
if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE) ||
|
||||||
}
|
(DosHeader->e_lfanew == 0L) ||
|
||||||
|
(*(PULONG) NTHeaders != IMAGE_NT_SIGNATURE)) {
|
||||||
/*
|
|
||||||
* Retrieve the offset of the APC dispatcher from NTDLL
|
DPRINT1("NTDLL format invalid\n");
|
||||||
*/
|
ZwClose(FileHandle);
|
||||||
if (SystemDllApcDispatcher == NULL)
|
return(STATUS_UNSUCCESSFUL);
|
||||||
{
|
}
|
||||||
RtlInitAnsiString (&ProcedureName,
|
|
||||||
"KiUserApcDispatcher");
|
/* Create a section for NTDLL */
|
||||||
Status = LdrGetProcedureAddress ((PVOID)ImageBase,
|
DPRINT("Creating section\n");
|
||||||
&ProcedureName,
|
Status = ZwCreateSection(&NTDllSectionHandle,
|
||||||
0,
|
SECTION_ALL_ACCESS,
|
||||||
&SystemDllApcDispatcher);
|
NULL,
|
||||||
if (!NT_SUCCESS(Status))
|
NULL,
|
||||||
{
|
PAGE_READONLY,
|
||||||
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
SEC_IMAGE | SEC_COMMIT,
|
||||||
if (Process != CurrentProcess)
|
FileHandle);
|
||||||
{
|
if (!NT_SUCCESS(Status)) {
|
||||||
KeDetachProcess();
|
|
||||||
}
|
DPRINT1("NTDLL create section failed (Status %x)\n", Status);
|
||||||
ObDereferenceObject(Process);
|
ZwClose(FileHandle);
|
||||||
ZwClose(NTDllSectionHandle);
|
return(Status);
|
||||||
return (Status);
|
}
|
||||||
}
|
ZwClose(FileHandle);
|
||||||
}
|
|
||||||
|
/* Reference the Section */
|
||||||
/*
|
DPRINT("ObReferenceObjectByHandle section: %d\n", NTDllSectionHandle);
|
||||||
* Retrieve the offset of the exception dispatcher from NTDLL
|
Status = ObReferenceObjectByHandle(NTDllSectionHandle,
|
||||||
*/
|
SECTION_ALL_ACCESS,
|
||||||
if (SystemDllExceptionDispatcher == NULL)
|
MmSectionObjectType,
|
||||||
{
|
KernelMode,
|
||||||
RtlInitAnsiString (&ProcedureName,
|
(PVOID*)&LdrpSystemDllSection,
|
||||||
"KiUserExceptionDispatcher");
|
NULL);
|
||||||
Status = LdrGetProcedureAddress ((PVOID)ImageBase,
|
if (!NT_SUCCESS(Status)) {
|
||||||
&ProcedureName,
|
|
||||||
0,
|
DPRINT1("NTDLL section reference failed (Status %x)\n", Status);
|
||||||
&SystemDllExceptionDispatcher);
|
return(Status);
|
||||||
if (!NT_SUCCESS(Status))
|
}
|
||||||
{
|
|
||||||
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
/* Map it */
|
||||||
if (Process != CurrentProcess)
|
LdrpMapSystemDll(PsGetCurrentProcess(), &LdrpSystemDllBase);
|
||||||
{
|
DPRINT("LdrpSystemDllBase: %x\n", LdrpSystemDllBase);
|
||||||
KeDetachProcess();
|
|
||||||
}
|
/* Now get the Entrypoints */
|
||||||
ObDereferenceObject(Process);
|
LdrpGetSystemDllEntryPoints();
|
||||||
ZwClose(NTDllSectionHandle);
|
|
||||||
return (Status);
|
return STATUS_SUCCESS;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Retrieve the offset of the callback dispatcher from NTDLL
|
|
||||||
*/
|
|
||||||
if (SystemDllCallbackDispatcher == NULL)
|
|
||||||
{
|
|
||||||
RtlInitAnsiString (&ProcedureName,
|
|
||||||
"KiUserCallbackDispatcher");
|
|
||||||
Status = LdrGetProcedureAddress ((PVOID)ImageBase,
|
|
||||||
&ProcedureName,
|
|
||||||
0,
|
|
||||||
&SystemDllCallbackDispatcher);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
|
||||||
if (Process != CurrentProcess)
|
|
||||||
{
|
|
||||||
KeDetachProcess();
|
|
||||||
}
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
ZwClose(NTDllSectionHandle);
|
|
||||||
return (Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Retrieve the offset of the raise exception dispatcher from NTDLL
|
|
||||||
*/
|
|
||||||
if (SystemDllRaiseExceptionDispatcher == NULL)
|
|
||||||
{
|
|
||||||
RtlInitAnsiString (&ProcedureName,
|
|
||||||
"KiRaiseUserExceptionDispatcher");
|
|
||||||
Status = LdrGetProcedureAddress ((PVOID)ImageBase,
|
|
||||||
&ProcedureName,
|
|
||||||
0,
|
|
||||||
&SystemDllRaiseExceptionDispatcher);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
|
||||||
if (Process != CurrentProcess)
|
|
||||||
{
|
|
||||||
KeDetachProcess();
|
|
||||||
}
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
ZwClose(NTDllSectionHandle);
|
|
||||||
return (Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Process != CurrentProcess)
|
|
||||||
{
|
|
||||||
KeDetachProcess();
|
|
||||||
}
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
|
|
||||||
ZwClose(NTDllSectionHandle);
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -319,9 +319,12 @@ NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process)
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest)
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
MmCopyMmInfo(PEPROCESS Src,
|
||||||
|
PEPROCESS Dest,
|
||||||
|
PPHYSICAL_ADDRESS DirectoryTableBase)
|
||||||
{
|
{
|
||||||
PKPROCESS KProcess = &Dest->Pcb;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG i, j;
|
ULONG i, j;
|
||||||
PFN_TYPE Pfn[7];
|
PFN_TYPE Pfn[7];
|
||||||
|
@ -389,8 +392,9 @@ NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest)
|
||||||
|
|
||||||
MmDeleteHyperspaceMapping(PageDirectory);
|
MmDeleteHyperspaceMapping(PageDirectory);
|
||||||
}
|
}
|
||||||
KProcess->DirectoryTableBase.QuadPart = PFN_TO_PTE(Pfn[0]);
|
|
||||||
DPRINT("Finished MmCopyMmInfo()\n");
|
DirectoryTableBase->QuadPart = PFN_TO_PTE(Pfn[0]);
|
||||||
|
DPRINT("Finished MmCopyMmInfo(): %I64x\n", DirectoryTableBase->QuadPart);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -384,6 +384,7 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEMORY_AREA_VIRTUAL_MEMORY:
|
case MEMORY_AREA_VIRTUAL_MEMORY:
|
||||||
|
case MEMORY_AREA_PEB_OR_TEB:
|
||||||
Status = MmNotPresentFaultVirtualMemory(AddressSpace,
|
Status = MmNotPresentFaultVirtualMemory(AddressSpace,
|
||||||
MemoryArea,
|
MemoryArea,
|
||||||
(PVOID)Address,
|
(PVOID)Address,
|
||||||
|
|
|
@ -111,7 +111,7 @@ NtWaitForMultipleObjects(IN ULONG ObjectCount,
|
||||||
UserRequest,
|
UserRequest,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
Alertable,
|
Alertable,
|
||||||
TimeOut,
|
TimeOut,
|
||||||
WaitBlockArray);
|
WaitBlockArray);
|
||||||
|
|
||||||
/* dereference all objects */
|
/* dereference all objects */
|
||||||
|
|
|
@ -473,7 +473,6 @@ NtCreateThread (
|
||||||
UserMode,
|
UserMode,
|
||||||
NULL );
|
NULL );
|
||||||
KeInsertQueueApc(LdrInitApc, NULL, NULL, IO_NO_INCREMENT);
|
KeInsertQueueApc(LdrInitApc, NULL, NULL, IO_NO_INCREMENT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The thread is non-alertable, so the APC we added did not set UserApcPending to TRUE.
|
* The thread is non-alertable, so the APC we added did not set UserApcPending to TRUE.
|
||||||
* We must do this manually. Do NOT attempt to set the Thread to Alertable before the call,
|
* We must do this manually. Do NOT attempt to set the Thread to Alertable before the call,
|
||||||
|
|
|
@ -41,8 +41,7 @@ static PCREATE_PROCESS_NOTIFY_ROUTINE
|
||||||
PiProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
|
PiProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
|
||||||
static PLOAD_IMAGE_NOTIFY_ROUTINE
|
static PLOAD_IMAGE_NOTIFY_ROUTINE
|
||||||
PiLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT];
|
PiLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT];
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
PEPROCESS
|
PEPROCESS
|
||||||
|
@ -113,8 +112,7 @@ PiKillMostProcesses(VOID)
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PEPROCESS current;
|
PEPROCESS current;
|
||||||
|
|
||||||
ExAcquireFastMutex(&PspActiveProcessMutex);
|
ExAcquireFastMutex(&PspActiveProcessMutex);
|
||||||
|
|
||||||
current_entry = PsActiveProcessHead.Flink;
|
current_entry = PsActiveProcessHead.Flink;
|
||||||
while (current_entry != &PsActiveProcessHead)
|
while (current_entry != &PsActiveProcessHead)
|
||||||
{
|
{
|
||||||
|
@ -271,8 +269,16 @@ PsInitProcessManagment(VOID)
|
||||||
InsertHeadList(&PsActiveProcessHead,
|
InsertHeadList(&PsActiveProcessHead,
|
||||||
&PsInitialSystemProcess->ProcessListEntry);
|
&PsInitialSystemProcess->ProcessListEntry);
|
||||||
InitializeListHead(&PsInitialSystemProcess->ThreadListHead);
|
InitializeListHead(&PsInitialSystemProcess->ThreadListHead);
|
||||||
|
|
||||||
SepCreateSystemProcessToken(PsInitialSystemProcess);
|
#ifndef SCHED_REWRITE
|
||||||
|
PTOKEN BootToken;
|
||||||
|
|
||||||
|
/* No parent, this is the Initial System Process. Assign Boot Token */
|
||||||
|
BootToken = SepCreateSystemProcessToken();
|
||||||
|
BootToken->TokenInUse = TRUE;
|
||||||
|
PsInitialSystemProcess->Token = BootToken;
|
||||||
|
ObReferenceObject(BootToken);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -298,99 +304,6 @@ PspPostInitSystemProcess(VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
|
||||||
PsCreatePeb(HANDLE ProcessHandle,
|
|
||||||
PEPROCESS Process,
|
|
||||||
PVOID ImageBase)
|
|
||||||
{
|
|
||||||
ULONG AllocSize;
|
|
||||||
ULONG PebSize;
|
|
||||||
PPEB Peb;
|
|
||||||
LARGE_INTEGER SectionOffset;
|
|
||||||
ULONG ViewSize;
|
|
||||||
PVOID TableBase;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
/* Allocate the Process Environment Block (PEB) */
|
|
||||||
Process->TebBlock = (PVOID) MM_ROUND_DOWN(PEB_BASE, MM_VIRTMEM_GRANULARITY);
|
|
||||||
AllocSize = MM_VIRTMEM_GRANULARITY;
|
|
||||||
Status = NtAllocateVirtualMemory(ProcessHandle,
|
|
||||||
&Process->TebBlock,
|
|
||||||
0,
|
|
||||||
&AllocSize,
|
|
||||||
MEM_RESERVE,
|
|
||||||
PAGE_READWRITE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
ASSERT((ULONG_PTR) Process->TebBlock <= PEB_BASE &&
|
|
||||||
PEB_BASE + PAGE_SIZE <= (ULONG_PTR) Process->TebBlock + AllocSize);
|
|
||||||
Peb = (PPEB)PEB_BASE;
|
|
||||||
PebSize = PAGE_SIZE;
|
|
||||||
Status = NtAllocateVirtualMemory(ProcessHandle,
|
|
||||||
(PVOID*)&Peb,
|
|
||||||
0,
|
|
||||||
&PebSize,
|
|
||||||
MEM_COMMIT,
|
|
||||||
PAGE_READWRITE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
DPRINT("Peb %p PebSize %lu\n", Peb, PebSize);
|
|
||||||
ASSERT((PPEB) PEB_BASE == Peb && PAGE_SIZE <= PebSize);
|
|
||||||
Process->TebLastAllocated = (PVOID) Peb;
|
|
||||||
|
|
||||||
ViewSize = 0;
|
|
||||||
SectionOffset.QuadPart = (ULONGLONG)0;
|
|
||||||
TableBase = NULL;
|
|
||||||
Status = MmMapViewOfSection(NlsSectionObject,
|
|
||||||
Process,
|
|
||||||
&TableBase,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
&SectionOffset,
|
|
||||||
&ViewSize,
|
|
||||||
ViewShare,
|
|
||||||
MEM_TOP_DOWN,
|
|
||||||
PAGE_READONLY);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
DPRINT("TableBase %p ViewSize %lx\n", TableBase, ViewSize);
|
|
||||||
|
|
||||||
KeAttachProcess(&Process->Pcb);
|
|
||||||
|
|
||||||
/* Initialize the PEB */
|
|
||||||
RtlZeroMemory(Peb, sizeof(PEB));
|
|
||||||
Peb->ImageBaseAddress = ImageBase;
|
|
||||||
|
|
||||||
Peb->OSMajorVersion = 4;
|
|
||||||
Peb->OSMinorVersion = 0;
|
|
||||||
Peb->OSBuildNumber = 1381;
|
|
||||||
Peb->OSPlatformId = 2; //VER_PLATFORM_WIN32_NT;
|
|
||||||
Peb->OSCSDVersion = 6 << 8;
|
|
||||||
|
|
||||||
Peb->AnsiCodePageData = (char*)TableBase + NlsAnsiTableOffset;
|
|
||||||
Peb->OemCodePageData = (char*)TableBase + NlsOemTableOffset;
|
|
||||||
Peb->UnicodeCaseTableData = (char*)TableBase + NlsUnicodeTableOffset;
|
|
||||||
|
|
||||||
Process->Peb = Peb;
|
|
||||||
KeDetachProcess();
|
|
||||||
|
|
||||||
DPRINT("PsCreatePeb: Peb created at %p\n", Peb);
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PKPROCESS
|
PKPROCESS
|
||||||
KeGetCurrentProcess(VOID)
|
KeGetCurrentProcess(VOID)
|
||||||
/*
|
/*
|
||||||
|
@ -445,472 +358,276 @@ IoGetCurrentProcess(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
PspCreateProcess(OUT PHANDLE ProcessHandle,
|
PspCreateProcess(OUT PHANDLE ProcessHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||||
IN HANDLE ParentProcess OPTIONAL,
|
IN HANDLE ParentProcess OPTIONAL,
|
||||||
IN BOOLEAN InheritObjectTable,
|
IN BOOLEAN InheritObjectTable,
|
||||||
IN HANDLE SectionHandle OPTIONAL,
|
IN HANDLE SectionHandle OPTIONAL,
|
||||||
IN HANDLE DebugPort OPTIONAL,
|
IN HANDLE DebugPort OPTIONAL,
|
||||||
IN HANDLE ExceptionPort OPTIONAL)
|
IN HANDLE ExceptionPort OPTIONAL)
|
||||||
{
|
{
|
||||||
HANDLE hProcess;
|
HANDLE hProcess;
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
PEPROCESS pParentProcess;
|
PEPROCESS pParentProcess;
|
||||||
PKPROCESS KProcess;
|
PEPORT pDebugPort = NULL;
|
||||||
PVOID LdrStartupAddr;
|
PEPORT pExceptionPort = NULL;
|
||||||
PVOID BaseAddress;
|
PSECTION_OBJECT SectionObject = NULL;
|
||||||
PMEMORY_AREA MemoryArea;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
KPROCESSOR_MODE PreviousMode;
|
PHYSICAL_ADDRESS DirectoryTableBase;
|
||||||
PVOID ImageBase = NULL;
|
KAFFINITY Affinity;
|
||||||
PEPORT pDebugPort = NULL;
|
DirectoryTableBase.QuadPart = (ULONGLONG)0;
|
||||||
PEPORT pExceptionPort = NULL;
|
|
||||||
PSECTION_OBJECT SectionObject = NULL;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
DPRINT("PspCreateProcess(ObjectAttributes %x)\n", ObjectAttributes);
|
DPRINT("PspCreateProcess(ObjectAttributes %x)\n", ObjectAttributes);
|
||||||
|
|
||||||
PreviousMode = ExGetPreviousMode();
|
/* Reference the Parent if there is one */
|
||||||
|
if(ParentProcess != NULL)
|
||||||
|
{
|
||||||
|
Status = ObReferenceObjectByHandle(ParentProcess,
|
||||||
|
PROCESS_CREATE_PROCESS,
|
||||||
|
PsProcessType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&pParentProcess,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to reference the parent process: Status: 0x%x\n", Status);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inherit Parent process's Affinity. */
|
||||||
|
Affinity = pParentProcess->Pcb.Affinity;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pParentProcess = NULL;
|
||||||
|
Affinity = KeActiveProcessors;
|
||||||
|
}
|
||||||
|
|
||||||
BoundaryAddressMultiple.QuadPart = 0;
|
/* Add the debug port */
|
||||||
|
if (DebugPort != NULL)
|
||||||
if(ParentProcess != NULL)
|
{
|
||||||
{
|
Status = ObReferenceObjectByHandle(DebugPort,
|
||||||
Status = ObReferenceObjectByHandle(ParentProcess,
|
PORT_ALL_ACCESS,
|
||||||
PROCESS_CREATE_PROCESS,
|
LpcPortObjectType,
|
||||||
PsProcessType,
|
PreviousMode,
|
||||||
PreviousMode,
|
(PVOID*)&pDebugPort,
|
||||||
(PVOID*)&pParentProcess,
|
NULL);
|
||||||
NULL);
|
if (!NT_SUCCESS(Status))
|
||||||
if (!NT_SUCCESS(Status))
|
{
|
||||||
{
|
DPRINT1("Failed to reference the debug port: Status: 0x%x\n", Status);
|
||||||
DPRINT1("Failed to reference the parent process: Status: 0x%x\n", Status);
|
goto exitdereferenceobjects;
|
||||||
return(Status);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pParentProcess = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/* Add the exception port */
|
||||||
* Add the debug port
|
if (ExceptionPort != NULL)
|
||||||
*/
|
{
|
||||||
if (DebugPort != NULL)
|
Status = ObReferenceObjectByHandle(ExceptionPort,
|
||||||
{
|
PORT_ALL_ACCESS,
|
||||||
Status = ObReferenceObjectByHandle(DebugPort,
|
LpcPortObjectType,
|
||||||
PORT_ALL_ACCESS,
|
PreviousMode,
|
||||||
LpcPortObjectType,
|
(PVOID*)&pExceptionPort,
|
||||||
PreviousMode,
|
NULL);
|
||||||
(PVOID*)&pDebugPort,
|
|
||||||
NULL);
|
if (!NT_SUCCESS(Status))
|
||||||
if (!NT_SUCCESS(Status))
|
{
|
||||||
{
|
DPRINT1("Failed to reference the exception port: Status: 0x%x\n", Status);
|
||||||
DPRINT1("Failed to reference the debug port: Status: 0x%x\n", Status);
|
goto exitdereferenceobjects;
|
||||||
goto exitdereferenceobjects;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/* Add the Section */
|
||||||
* Add the exception port
|
if (SectionHandle != NULL)
|
||||||
*/
|
{
|
||||||
if (ExceptionPort != NULL)
|
|
||||||
{
|
|
||||||
Status = ObReferenceObjectByHandle(ExceptionPort,
|
|
||||||
PORT_ALL_ACCESS,
|
|
||||||
LpcPortObjectType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&pExceptionPort,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to reference the exception port: Status: 0x%x\n", Status);
|
|
||||||
goto exitdereferenceobjects;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SectionHandle != NULL)
|
|
||||||
{
|
|
||||||
Status = ObReferenceObjectByHandle(SectionHandle,
|
Status = ObReferenceObjectByHandle(SectionHandle,
|
||||||
0,
|
0,
|
||||||
MmSectionObjectType,
|
MmSectionObjectType,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
(PVOID*)&SectionObject,
|
(PVOID*)&SectionObject,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to reference process image section: Status: 0x%x\n", Status);
|
DPRINT1("Failed to reference process image section: Status: 0x%x\n", Status);
|
||||||
goto exitdereferenceobjects;
|
goto exitdereferenceobjects;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObCreateObject(PreviousMode,
|
/* Create the Object */
|
||||||
PsProcessType,
|
DPRINT("Creating Process Object\n");
|
||||||
ObjectAttributes,
|
Status = ObCreateObject(PreviousMode,
|
||||||
PreviousMode,
|
PsProcessType,
|
||||||
NULL,
|
ObjectAttributes,
|
||||||
sizeof(EPROCESS),
|
PreviousMode,
|
||||||
0,
|
NULL,
|
||||||
0,
|
sizeof(EPROCESS),
|
||||||
(PVOID*)&Process);
|
0,
|
||||||
if (!NT_SUCCESS(Status))
|
0,
|
||||||
{
|
(PVOID*)&Process);
|
||||||
DPRINT1("Failed to create process object, Status: 0x%x\n", Status);
|
|
||||||
|
|
||||||
exitdereferenceobjects:
|
|
||||||
if(SectionObject != NULL)
|
|
||||||
ObDereferenceObject(SectionObject);
|
|
||||||
if(pExceptionPort != NULL)
|
|
||||||
ObDereferenceObject(pExceptionPort);
|
|
||||||
if(pDebugPort != NULL)
|
|
||||||
ObDereferenceObject(pDebugPort);
|
|
||||||
if(pParentProcess != NULL)
|
|
||||||
ObDereferenceObject(pParentProcess);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
KProcess = &Process->Pcb;
|
|
||||||
|
|
||||||
RtlZeroMemory(Process, sizeof(EPROCESS));
|
|
||||||
|
|
||||||
Status = PsCreateCidHandle(Process,
|
|
||||||
PsProcessType,
|
|
||||||
&Process->UniqueProcessId);
|
|
||||||
if(!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to create CID handle (unique process ID)! Status: 0x%x\n", Status);
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
goto exitdereferenceobjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
Process->DebugPort = pDebugPort;
|
|
||||||
Process->ExceptionPort = pExceptionPort;
|
|
||||||
|
|
||||||
if(SectionObject != NULL)
|
|
||||||
{
|
|
||||||
UNICODE_STRING FileName;
|
|
||||||
PWCHAR szSrc;
|
|
||||||
PCHAR szDest;
|
|
||||||
USHORT lnFName = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine the image file name and save it to the EPROCESS structure
|
|
||||||
*/
|
|
||||||
|
|
||||||
FileName = SectionObject->FileObject->FileName;
|
|
||||||
szSrc = (PWCHAR)(FileName.Buffer + (FileName.Length / sizeof(WCHAR)) - 1);
|
|
||||||
while(szSrc >= FileName.Buffer)
|
|
||||||
{
|
|
||||||
if(*szSrc == L'\\')
|
|
||||||
{
|
|
||||||
szSrc++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
szSrc--;
|
|
||||||
lnFName++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy the image file name to the process and truncate it to 15 characters
|
|
||||||
if necessary */
|
|
||||||
szDest = Process->ImageFileName;
|
|
||||||
lnFName = min(lnFName, sizeof(Process->ImageFileName) - 1);
|
|
||||||
while(lnFName-- > 0)
|
|
||||||
{
|
|
||||||
*(szDest++) = (UCHAR)*(szSrc++);
|
|
||||||
}
|
|
||||||
/* *szDest = '\0'; */
|
|
||||||
}
|
|
||||||
|
|
||||||
KeInitializeDispatcherHeader(&KProcess->DispatcherHeader,
|
|
||||||
ProcessObject,
|
|
||||||
sizeof(EPROCESS),
|
|
||||||
FALSE);
|
|
||||||
|
|
||||||
/* Inherit parent process's affinity. */
|
|
||||||
if(pParentProcess != NULL)
|
|
||||||
{
|
|
||||||
KProcess->Affinity = pParentProcess->Pcb.Affinity;
|
|
||||||
Process->InheritedFromUniqueProcessId = pParentProcess->UniqueProcessId;
|
|
||||||
Process->SessionId = pParentProcess->SessionId;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
KProcess->Affinity = KeActiveProcessors;
|
|
||||||
}
|
|
||||||
|
|
||||||
KProcess->BasePriority = PROCESS_PRIO_NORMAL;
|
|
||||||
KProcess->IopmOffset = 0xffff;
|
|
||||||
KProcess->LdtDescriptor[0] = 0;
|
|
||||||
KProcess->LdtDescriptor[1] = 0;
|
|
||||||
InitializeListHead(&KProcess->ThreadListHead);
|
|
||||||
KProcess->ThreadQuantum = 6;
|
|
||||||
KProcess->AutoAlignment = 0;
|
|
||||||
MmInitializeAddressSpace(Process,
|
|
||||||
&Process->AddressSpace);
|
|
||||||
|
|
||||||
ObCreateHandleTable(pParentProcess,
|
|
||||||
InheritObjectTable,
|
|
||||||
Process);
|
|
||||||
MmCopyMmInfo(pParentProcess ? pParentProcess : PsInitialSystemProcess, Process);
|
|
||||||
|
|
||||||
KeInitializeEvent(&Process->LockEvent, SynchronizationEvent, FALSE);
|
|
||||||
Process->LockCount = 0;
|
|
||||||
Process->LockOwner = NULL;
|
|
||||||
|
|
||||||
Process->Win32WindowStation = (HANDLE)0;
|
|
||||||
|
|
||||||
ExAcquireFastMutex(&PspActiveProcessMutex);
|
|
||||||
InsertTailList(&PsActiveProcessHead, &Process->ProcessListEntry);
|
|
||||||
InitializeListHead(&Process->ThreadListHead);
|
|
||||||
ExReleaseFastMutex(&PspActiveProcessMutex);
|
|
||||||
|
|
||||||
Process->Pcb.State = PROCESS_STATE_ACTIVE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now we have created the process proper
|
|
||||||
*/
|
|
||||||
|
|
||||||
MmLockAddressSpace(&Process->AddressSpace);
|
|
||||||
|
|
||||||
/* Protect the highest 64KB of the process address space */
|
|
||||||
BaseAddress = (PVOID)MmUserProbeAddress;
|
|
||||||
Status = MmCreateMemoryArea(Process,
|
|
||||||
&Process->AddressSpace,
|
|
||||||
MEMORY_AREA_NO_ACCESS,
|
|
||||||
&BaseAddress,
|
|
||||||
0x10000,
|
|
||||||
PAGE_NOACCESS,
|
|
||||||
&MemoryArea,
|
|
||||||
FALSE,
|
|
||||||
FALSE,
|
|
||||||
BoundaryAddressMultiple);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(&Process->AddressSpace);
|
|
||||||
DPRINT1("Failed to protect the highest 64KB of the process address space\n");
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
goto exitdereferenceobjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Protect the lowest 64KB of the process address space */
|
|
||||||
#if 0
|
|
||||||
BaseAddress = (PVOID)0x00000000;
|
|
||||||
Status = MmCreateMemoryArea(Process,
|
|
||||||
&Process->AddressSpace,
|
|
||||||
MEMORY_AREA_NO_ACCESS,
|
|
||||||
&BaseAddress,
|
|
||||||
0x10000,
|
|
||||||
PAGE_NOACCESS,
|
|
||||||
&MemoryArea,
|
|
||||||
FALSE,
|
|
||||||
FALSE,
|
|
||||||
BoundaryAddressMultiple);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(&Process->AddressSpace);
|
|
||||||
DPRINT1("Failed to protect the lowest 64KB of the process address space\n");
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
goto exitdereferenceobjects;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Protect the 60KB above the shared user page */
|
|
||||||
BaseAddress = (char*)USER_SHARED_DATA + PAGE_SIZE;
|
|
||||||
Status = MmCreateMemoryArea(Process,
|
|
||||||
&Process->AddressSpace,
|
|
||||||
MEMORY_AREA_NO_ACCESS,
|
|
||||||
&BaseAddress,
|
|
||||||
0x10000 - PAGE_SIZE,
|
|
||||||
PAGE_NOACCESS,
|
|
||||||
&MemoryArea,
|
|
||||||
FALSE,
|
|
||||||
FALSE,
|
|
||||||
BoundaryAddressMultiple);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(&Process->AddressSpace);
|
|
||||||
DPRINT1("Failed to protect the memory above the shared user page\n");
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
goto exitdereferenceobjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the shared data page */
|
|
||||||
BaseAddress = (PVOID)USER_SHARED_DATA;
|
|
||||||
Status = MmCreateMemoryArea(Process,
|
|
||||||
&Process->AddressSpace,
|
|
||||||
MEMORY_AREA_SHARED_DATA,
|
|
||||||
&BaseAddress,
|
|
||||||
PAGE_SIZE,
|
|
||||||
PAGE_READONLY,
|
|
||||||
&MemoryArea,
|
|
||||||
FALSE,
|
|
||||||
FALSE,
|
|
||||||
BoundaryAddressMultiple);
|
|
||||||
MmUnlockAddressSpace(&Process->AddressSpace);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to create shared data page\n");
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
goto exitdereferenceobjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
/*
|
|
||||||
* FIXME - the handle should be created after all things are initialized, NOT HERE!
|
|
||||||
*/
|
|
||||||
Status = ObInsertObject ((PVOID)Process,
|
|
||||||
NULL,
|
|
||||||
DesiredAccess,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
&hProcess);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to create a handle for the process\n");
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
goto exitdereferenceobjects;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME - Map ntdll
|
|
||||||
*/
|
|
||||||
Status = LdrpMapSystemDll(hProcess, /* FIXME - hProcess shouldn't be available at this point! */
|
|
||||||
&LdrStartupAddr);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DbgPrint("LdrpMapSystemDll failed (Status %x)\n", Status);
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
goto exitdereferenceobjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map the process image
|
|
||||||
*/
|
|
||||||
if (SectionObject != NULL)
|
|
||||||
{
|
|
||||||
ULONG ViewSize = 0;
|
|
||||||
DPRINT("Mapping process image\n");
|
|
||||||
Status = MmMapViewOfSection(SectionObject,
|
|
||||||
Process,
|
|
||||||
(PVOID*)&ImageBase,
|
|
||||||
0,
|
|
||||||
ViewSize,
|
|
||||||
NULL,
|
|
||||||
&ViewSize,
|
|
||||||
0,
|
|
||||||
MEM_COMMIT,
|
|
||||||
PAGE_READWRITE);
|
|
||||||
ObDereferenceObject(SectionObject);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DbgPrint("Failed to map the process section (Status %x)\n", Status);
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
goto exitdereferenceobjects;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pParentProcess != NULL)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Duplicate the token
|
|
||||||
*/
|
|
||||||
Status = SepInitializeNewProcess(Process, pParentProcess);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DbgPrint("SepInitializeNewProcess failed (Status %x)\n", Status);
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
goto exitdereferenceobjects;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* FIXME */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME - Create PEB
|
|
||||||
*/
|
|
||||||
DPRINT("Creating PEB\n");
|
|
||||||
Status = PsCreatePeb(hProcess, /* FIXME - hProcess shouldn't be available at this point! */
|
|
||||||
Process,
|
|
||||||
ImageBase);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status);
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
goto exitdereferenceobjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Maybe send a message to the creator process's debugger
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
if (pParentProcess->DebugPort != NULL)
|
|
||||||
{
|
|
||||||
LPC_DBG_MESSAGE Message;
|
|
||||||
HANDLE FileHandle;
|
|
||||||
|
|
||||||
ObCreateHandle(NULL, // Debugger Process
|
|
||||||
NULL, // SectionHandle
|
|
||||||
FILE_ALL_ACCESS,
|
|
||||||
FALSE,
|
|
||||||
&FileHandle);
|
|
||||||
|
|
||||||
Message.Header.MessageSize = sizeof(LPC_DBG_MESSAGE);
|
|
||||||
Message.Header.DataSize = sizeof(LPC_DBG_MESSAGE) -
|
|
||||||
sizeof(LPC_MESSAGE);
|
|
||||||
Message.Type = DBG_EVENT_CREATE_PROCESS;
|
|
||||||
Message.Data.CreateProcess.FileHandle = FileHandle;
|
|
||||||
Message.Data.CreateProcess.Base = ImageBase;
|
|
||||||
Message.Data.CreateProcess.EntryPoint = NULL; //
|
|
||||||
|
|
||||||
Status = LpcSendDebugMessagePort(pParentProcess->DebugPort,
|
|
||||||
&Message);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PspRunCreateProcessNotifyRoutines(Process, TRUE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME - the handle should be created not before this point!
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
Status = ObInsertObject ((PVOID)Process,
|
|
||||||
NULL,
|
|
||||||
DesiredAccess,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
&hProcess);
|
|
||||||
#endif
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
*ProcessHandle = hProcess;
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* don't dereference the debug port, exception port and section object even
|
|
||||||
* if ObInsertObject() failed, the process is alive! We just couldn't return
|
|
||||||
* the handle to the caller!
|
|
||||||
*/
|
|
||||||
|
|
||||||
ObDereferenceObject(Process);
|
if (!NT_SUCCESS(Status))
|
||||||
if(pParentProcess != NULL)
|
{
|
||||||
ObDereferenceObject(pParentProcess);
|
DPRINT1("Failed to create process object, Status: 0x%x\n", Status);
|
||||||
|
goto exitdereferenceobjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up the Object */
|
||||||
|
DPRINT("Cleaning Process Object\n");
|
||||||
|
RtlZeroMemory(Process, sizeof(EPROCESS));
|
||||||
|
|
||||||
|
/* Inherit stuff from the Parent since we now have the object created */
|
||||||
|
if (pParentProcess)
|
||||||
|
{
|
||||||
|
Process->InheritedFromUniqueProcessId = pParentProcess->UniqueProcessId;
|
||||||
|
Process->SessionId = pParentProcess->SessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Set up the Quota Block from the Parent
|
||||||
|
PspInheritQuota(Parent, Process); */
|
||||||
|
|
||||||
|
/* FIXME: Set up Dos Device Map from the Parent
|
||||||
|
ObInheritDeviceMap(Parent, Process) */
|
||||||
|
|
||||||
|
/* Set the Process' LPC Ports */
|
||||||
|
Process->DebugPort = pDebugPort;
|
||||||
|
Process->ExceptionPort = pExceptionPort;
|
||||||
|
|
||||||
|
/* Setup the Lock Event */
|
||||||
|
DPRINT("Initialzing Process Lock\n");
|
||||||
|
KeInitializeEvent(&Process->LockEvent, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
|
/* Setup the Thread List Head */
|
||||||
|
DPRINT("Initialzing Process ThreadListHead\n");
|
||||||
|
InitializeListHead(&Process->ThreadListHead);
|
||||||
|
|
||||||
|
/* Create or Clone the Handle Table */
|
||||||
|
DPRINT("Initialzing Process Handle Table\n");
|
||||||
|
ObCreateHandleTable(pParentProcess, InheritObjectTable, Process);
|
||||||
|
DPRINT("Handle Table: %x\n", Process->ObjectTable);
|
||||||
|
|
||||||
|
/* Set Process's Directory Base */
|
||||||
|
DPRINT("Initialzing Process Directory Base\n");
|
||||||
|
MmCopyMmInfo(pParentProcess ? pParentProcess : PsInitialSystemProcess,
|
||||||
|
Process,
|
||||||
|
&DirectoryTableBase);
|
||||||
|
|
||||||
|
/* Now initialize the Kernel Process */
|
||||||
|
DPRINT("Initialzing Kernel Process\n");
|
||||||
|
KeInitializeProcess(&Process->Pcb,
|
||||||
|
PROCESS_PRIO_NORMAL,
|
||||||
|
Affinity,
|
||||||
|
DirectoryTableBase);
|
||||||
|
|
||||||
|
/* Duplicate Parent Token */
|
||||||
|
DPRINT("Initialzing Process Token\n");
|
||||||
|
Status = PspInitializeProcessSecurity(Process, pParentProcess);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("PspInitializeProcessSecurity failed (Status %x)\n", Status);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
goto exitdereferenceobjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the Process' Address Space */
|
||||||
|
DPRINT("Initialzing Process Address Space\n");
|
||||||
|
Status = MmCreateProcessAddressSpace(Process, SectionObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create Address Space\n");
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
goto exitdereferenceobjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SectionObject)
|
||||||
|
{
|
||||||
|
/* Map the System Dll */
|
||||||
|
DPRINT("Mapping System DLL\n");
|
||||||
|
LdrpMapSystemDll(Process, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a handle for the Process */
|
||||||
|
DPRINT("Initialzing Process CID Handle\n");
|
||||||
|
Status = PsCreateCidHandle(Process,
|
||||||
|
PsProcessType,
|
||||||
|
&Process->UniqueProcessId);
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create CID handle (unique process ID)! Status: 0x%x\n", Status);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
goto exitdereferenceobjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Insert into Job Object */
|
||||||
|
|
||||||
|
/* Create PEB only for User-Mode Processes */
|
||||||
|
if (pParentProcess)
|
||||||
|
{
|
||||||
|
DPRINT("Creating PEB\n");
|
||||||
|
Status = MmCreatePeb(Process);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status);
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
goto exitdereferenceobjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let's take advantage of this time to kill the reference too */
|
||||||
|
ObDereferenceObject(pParentProcess);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* W00T! The process can now be activated */
|
||||||
|
DPRINT("Inserting into Active Process List\n");
|
||||||
|
ExAcquireFastMutex(&PspActiveProcessMutex);
|
||||||
|
InsertTailList(&PsActiveProcessHead, &Process->ProcessListEntry);
|
||||||
|
ExReleaseFastMutex(&PspActiveProcessMutex);
|
||||||
|
|
||||||
|
/* FIXME: SeCreateAccessStateEx */
|
||||||
|
|
||||||
|
/* Insert the Process into the Object Directory */
|
||||||
|
DPRINT("Inserting Process Object\n");
|
||||||
|
Status = ObInsertObject(Process,
|
||||||
|
NULL,
|
||||||
|
DesiredAccess,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&hProcess);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Could not get a handle to the Process Object\n");
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
goto exitdereferenceobjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("Done. Returning handle: %x\n", hProcess);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
*ProcessHandle = hProcess;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
} _SEH_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: ObGetObjectSecurity(Process, &SecurityDescriptor)
|
||||||
|
SeAccessCheck
|
||||||
|
*/
|
||||||
|
ObReferenceObject(Process);
|
||||||
|
ObReferenceObject(Process);
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
|
exitdereferenceobjects:
|
||||||
|
if(SectionObject != NULL) ObDereferenceObject(SectionObject);
|
||||||
|
if(pExceptionPort != NULL) ObDereferenceObject(pExceptionPort);
|
||||||
|
if(pDebugPort != NULL) ObDereferenceObject(pDebugPort);
|
||||||
|
if(pParentProcess != NULL) ObDereferenceObject(pParentProcess);
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -144,6 +142,66 @@ PsOpenTokenOfProcess(HANDLE ProcessHandle,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
PspInitializeProcessSecurity(PEPROCESS Process,
|
||||||
|
PEPROCESS Parent OPTIONAL)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* If we have a parent, then duplicate the Token */
|
||||||
|
if (Parent) {
|
||||||
|
|
||||||
|
PTOKEN pNewToken;
|
||||||
|
PTOKEN pParentToken;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
|
||||||
|
pParentToken = (PACCESS_TOKEN)Parent->Token;
|
||||||
|
|
||||||
|
/* Initialize the Object Attributes */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Duplicate the Token */
|
||||||
|
Status = SepDuplicateToken(pParentToken,
|
||||||
|
&ObjectAttributes,
|
||||||
|
FALSE,
|
||||||
|
TokenPrimary,
|
||||||
|
pParentToken->ImpersonationLevel,
|
||||||
|
KernelMode,
|
||||||
|
&pNewToken);
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status)) {
|
||||||
|
|
||||||
|
DPRINT1("Failed to Duplicate Token\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Process->Token = pNewToken;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
#ifdef SCHED_REWRITE
|
||||||
|
PTOKEN BootToken;
|
||||||
|
|
||||||
|
/* No parent, this is the Initial System Process. Assign Boot Token */
|
||||||
|
BootToken = SepCreateSystemProcessToken();
|
||||||
|
BootToken->TokenInUse = TRUE;
|
||||||
|
Process->Token = BootToken;
|
||||||
|
ObReferenceObject(BootToken);
|
||||||
|
#else
|
||||||
|
DPRINT1("PspInitializeProcessSecurity called with no parent.\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return to caller */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
PspAssignPrimaryToken(PEPROCESS Process,
|
PspAssignPrimaryToken(PEPROCESS Process,
|
||||||
|
|
|
@ -169,6 +169,7 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token,
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
SepDuplicateToken(PTOKEN Token,
|
SepDuplicateToken(PTOKEN Token,
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
BOOLEAN EffectiveOnly,
|
BOOLEAN EffectiveOnly,
|
||||||
|
@ -300,39 +301,6 @@ SepDuplicateToken(PTOKEN Token,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
SepInitializeNewProcess(struct _EPROCESS* NewProcess,
|
|
||||||
struct _EPROCESS* ParentProcess)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
PTOKEN pNewToken;
|
|
||||||
PTOKEN pParentToken;
|
|
||||||
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
|
|
||||||
pParentToken = (PACCESS_TOKEN) ParentProcess->Token;
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Status = SepDuplicateToken(pParentToken,
|
|
||||||
&ObjectAttributes,
|
|
||||||
FALSE,
|
|
||||||
TokenPrimary,
|
|
||||||
pParentToken->ImpersonationLevel,
|
|
||||||
KernelMode,
|
|
||||||
&pNewToken);
|
|
||||||
if ( ! NT_SUCCESS(Status) )
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
NewProcess->Token = pNewToken;
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
@ -1800,9 +1768,9 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PTOKEN
|
||||||
NTSTATUS
|
STDCALL
|
||||||
SepCreateSystemProcessToken(struct _EPROCESS* Process)
|
SepCreateSystemProcessToken(VOID)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG uSize;
|
ULONG uSize;
|
||||||
|
@ -1833,28 +1801,28 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
|
||||||
(PVOID*)&AccessToken);
|
(PVOID*)&AccessToken);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId);
|
Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObDereferenceObject(AccessToken);
|
ObDereferenceObject(AccessToken);
|
||||||
return(Status);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId);
|
Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObDereferenceObject(AccessToken);
|
ObDereferenceObject(AccessToken);
|
||||||
return(Status);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId);
|
Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObDereferenceObject(AccessToken);
|
ObDereferenceObject(AccessToken);
|
||||||
return Status;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessToken->TokenLock = &SepTokenLock;
|
AccessToken->TokenLock = &SepTokenLock;
|
||||||
|
@ -2002,11 +1970,10 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
|
||||||
if ( ! NT_SUCCESS(Status) )
|
if ( ! NT_SUCCESS(Status) )
|
||||||
{
|
{
|
||||||
ObDereferenceObject(AccessToken);
|
ObDereferenceObject(AccessToken);
|
||||||
return Status;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process->Token = AccessToken;
|
return AccessToken;
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue