pointer to PEB becomes first parameter in call to NtProcessStartup

svn path=/trunk/; revision=838
This commit is contained in:
Eric Kohl 1999-12-08 12:59:35 +00:00
parent 904da6e474
commit 9d84d82bd7
5 changed files with 200 additions and 133 deletions

View file

@ -1,4 +1,4 @@
typedef NTSTATUS (*PEPFUNC)(VOID); typedef NTSTATUS (*PEPFUNC)(PPEB);
typedef struct _DLL typedef struct _DLL
{ {

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.14 1999/12/06 00:23:40 ekohl Exp $ /* $Id: create.c,v 1.15 1999/12/08 12:58:44 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -93,10 +93,9 @@ HANDLE STDCALL CreateFirstThread(HANDLE ProcessHandle,
LPSECURITY_ATTRIBUTES lpThreadAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize, DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress, LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter, PPEB Peb,
DWORD dwCreationFlags, DWORD dwCreationFlags,
LPDWORD lpThreadId, LPDWORD lpThreadId,
PWSTR lpCommandLine,
HANDLE NTDllSectionHandle, HANDLE NTDllSectionHandle,
HANDLE SectionHandle, HANDLE SectionHandle,
PVOID ImageBase) PVOID ImageBase)
@ -151,7 +150,7 @@ HANDLE STDCALL CreateFirstThread(HANDLE ProcessHandle,
ThreadContext.SegDs = USER_DS; ThreadContext.SegDs = USER_DS;
ThreadContext.SegCs = USER_CS; ThreadContext.SegCs = USER_CS;
ThreadContext.SegSs = USER_DS; ThreadContext.SegSs = USER_DS;
ThreadContext.Esp = STACK_TOP - 16; ThreadContext.Esp = STACK_TOP - 20;
ThreadContext.EFlags = (1<<1) + (1<<9); ThreadContext.EFlags = (1<<1) + (1<<9);
DPRINT("ThreadContext.Eip %x\n",ThreadContext.Eip); DPRINT("ThreadContext.Eip %x\n",ThreadContext.Eip);
@ -186,6 +185,11 @@ HANDLE STDCALL CreateFirstThread(HANDLE ProcessHandle,
&DupSectionHandle, &DupSectionHandle,
sizeof(DupSectionHandle), sizeof(DupSectionHandle),
&BytesWritten); &BytesWritten);
NtWriteVirtualMemory(ProcessHandle,
(PVOID)(STACK_TOP - 16),
&Peb,
sizeof(PPEB),
&BytesWritten);
Status = NtCreateThread(&ThreadHandle, Status = NtCreateThread(&ThreadHandle,
@ -343,6 +347,7 @@ HANDLE KERNEL32_MapFile(LPCWSTR lpApplicationName,
static NTSTATUS static NTSTATUS
CreatePeb ( CreatePeb (
PPEB *PebPtr,
HANDLE ProcessHandle, HANDLE ProcessHandle,
PPPB Ppb) PPPB Ppb)
{ {
@ -391,6 +396,8 @@ CreatePeb (
Ppb->TotalSize, Ppb->TotalSize,
&BytesWritten); &BytesWritten);
*PebPtr = (PPEB)PebBase;
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -412,7 +419,6 @@ CreateProcessW (
HANDLE hSection, hProcess, hThread; HANDLE hSection, hProcess, hThread;
NTSTATUS Status; NTSTATUS Status;
LPTHREAD_START_ROUTINE lpStartAddress = NULL; LPTHREAD_START_ROUTINE lpStartAddress = NULL;
LPVOID lpParameter = NULL;
WCHAR TempCommandLine[256]; WCHAR TempCommandLine[256];
PVOID BaseAddress; PVOID BaseAddress;
LARGE_INTEGER SectionOffset; LARGE_INTEGER SectionOffset;
@ -425,6 +431,7 @@ CreateProcessW (
DWORD len = 0; DWORD len = 0;
PPPB Ppb; PPPB Ppb;
UNICODE_STRING CommandLine_U; UNICODE_STRING CommandLine_U;
PPEB Peb;
DPRINT("CreateProcessW(lpApplicationName '%w', lpCommandLine '%w')\n", DPRINT("CreateProcessW(lpApplicationName '%w', lpCommandLine '%w')\n",
lpApplicationName,lpCommandLine); lpApplicationName,lpCommandLine);
@ -519,7 +526,7 @@ CreateProcessW (
* Create Process Environment Block * Create Process Environment Block
*/ */
DPRINT("Creating peb\n"); DPRINT("Creating peb\n");
CreatePeb(hProcess, Ppb); CreatePeb(&Peb, hProcess, Ppb);
RtlDestroyProcessParameters (Ppb); RtlDestroyProcessParameters (Ppb);
@ -532,10 +539,9 @@ CreateProcessW (
lpThreadAttributes, lpThreadAttributes,
Headers.OptionalHeader.SizeOfStackReserve, Headers.OptionalHeader.SizeOfStackReserve,
lpStartAddress, lpStartAddress,
lpParameter, Peb,
dwCreationFlags, dwCreationFlags,
&lpProcessInformation->dwThreadId, &lpProcessInformation->dwThreadId,
TempCommandLine,
NTDllSection, NTDllSection,
hSection, hSection,
(PVOID)Headers.OptionalHeader.ImageBase); (PVOID)Headers.OptionalHeader.ImageBase);

View file

@ -1,4 +1,4 @@
/* $Id: startup.c,v 1.12 1999/11/25 10:47:55 dwelch Exp $ /* $Id: startup.c,v 1.13 1999/12/08 12:58:06 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -43,15 +43,15 @@ NTSTATUS LdrMapNTDllForProcess (HANDLE ProcessHandle,
NTSTATUS Status; NTSTATUS Status;
HANDLE NTDllSectionHandle; HANDLE NTDllSectionHandle;
PVOID ImageBase; PVOID ImageBase;
PIMAGE_NT_HEADERS NTHeaders; PIMAGE_NT_HEADERS NTHeaders;
PIMAGE_DOS_HEADER PEDosHeader; PIMAGE_DOS_HEADER PEDosHeader;
DPRINT("LdrMapNTDllForProcess(ProcessHandle %x)\n",ProcessHandle); DPRINT("LdrMapNTDllForProcess(ProcessHandle %x)\n",ProcessHandle);
PEDosHeader = (PIMAGE_DOS_HEADER)LdrDllListHead.BaseAddress; PEDosHeader = (PIMAGE_DOS_HEADER)LdrDllListHead.BaseAddress;
NTHeaders = (PIMAGE_NT_HEADERS)(LdrDllListHead.BaseAddress + NTHeaders = (PIMAGE_NT_HEADERS)(LdrDllListHead.BaseAddress +
PEDosHeader->e_lfanew); PEDosHeader->e_lfanew);
NTDllSectionHandle = LdrDllListHead.SectionHandle; NTDllSectionHandle = LdrDllListHead.SectionHandle;
InitialViewSize = PEDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS) InitialViewSize = PEDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
+ sizeof(IMAGE_SECTION_HEADER) * NTHeaders->FileHeader.NumberOfSections; + sizeof(IMAGE_SECTION_HEADER) * NTHeaders->FileHeader.NumberOfSections;
@ -81,7 +81,8 @@ NTSTATUS LdrMapNTDllForProcess (HANDLE ProcessHandle,
* ARGUMENTS: * ARGUMENTS:
* DWORD ImageBase The base address of the process image * DWORD ImageBase The base address of the process image
*/ */
VOID LdrStartup(HANDLE SectionHandle, VOID LdrStartup(PPEB Peb,
HANDLE SectionHandle,
DWORD ImageBase, DWORD ImageBase,
HANDLE NTDllSectionHandle) HANDLE NTDllSectionHandle)
{ {
@ -89,11 +90,11 @@ VOID LdrStartup(HANDLE SectionHandle,
PIMAGE_DOS_HEADER PEDosHeader; PIMAGE_DOS_HEADER PEDosHeader;
NTSTATUS Status; NTSTATUS Status;
PIMAGE_NT_HEADERS NTHeaders; PIMAGE_NT_HEADERS NTHeaders;
DPRINT("LdrStartup(ImageBase %x, SectionHandle %x, " DPRINT("LdrStartup(Peb %x SectionHandle %x, ImageBase %x, "
"NTDllSectionHandle %x)\n",ImageBase, "NTDllSectionHandle %x )\n",
SectionHandle, NTDllSectionHandle); Peb, SectionHandle, ImageBase, NTDllSectionHandle);
LdrDllListHead.BaseAddress = (PVOID)&_image_base__; LdrDllListHead.BaseAddress = (PVOID)&_image_base__;
LdrDllListHead.Prev = &LdrDllListHead; LdrDllListHead.Prev = &LdrDllListHead;
LdrDllListHead.Next = &LdrDllListHead; LdrDllListHead.Next = &LdrDllListHead;
@ -101,7 +102,7 @@ VOID LdrStartup(HANDLE SectionHandle,
PEDosHeader = (PIMAGE_DOS_HEADER)LdrDllListHead.BaseAddress; PEDosHeader = (PIMAGE_DOS_HEADER)LdrDllListHead.BaseAddress;
LdrDllListHead.Headers = (PIMAGE_NT_HEADERS)(LdrDllListHead.BaseAddress + LdrDllListHead.Headers = (PIMAGE_NT_HEADERS)(LdrDllListHead.BaseAddress +
PEDosHeader->e_lfanew); PEDosHeader->e_lfanew);
/* If MZ header exists */ /* If MZ header exists */
PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase; PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
@ -115,7 +116,7 @@ VOID LdrStartup(HANDLE SectionHandle,
NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew); NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew);
__ProcessHeap = RtlCreateHeap(0, __ProcessHeap = RtlCreateHeap(0,
(PVOID)HEAP_BASE, (PVOID)HEAP_BASE,
NTHeaders->OptionalHeader.SizeOfHeapCommit, NTHeaders->OptionalHeader.SizeOfHeapCommit,
NTHeaders->OptionalHeader.SizeOfHeapReserve, NTHeaders->OptionalHeader.SizeOfHeapReserve,
NULL, NULL,
NULL); NULL);
@ -126,11 +127,10 @@ VOID LdrStartup(HANDLE SectionHandle,
dprintf("Failed to initialize image\n"); dprintf("Failed to initialize image\n");
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
} }
// dprintf("Transferring control to image at %x\n",EntryPoint); // dprintf("Transferring control to image at %x\n",EntryPoint);
Status = EntryPoint(); Status = EntryPoint(Peb);
ZwTerminateProcess(NtCurrentProcess(),Status); ZwTerminateProcess(NtCurrentProcess(),Status);
} }
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: process.c,v 1.5 1999/12/06 00:22:43 ekohl Exp $ /* $Id: process.c,v 1.6 1999/12/08 12:58:26 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -35,10 +35,9 @@ RtlpCreateFirstThread(HANDLE ProcessHandle,
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
DWORD dwStackSize, DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress, LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter, PPEB Peb,
DWORD dwCreationFlags, DWORD dwCreationFlags,
LPDWORD lpThreadId, LPDWORD lpThreadId,
PWSTR lpCommandLine,
HANDLE NTDllSectionHandle, HANDLE NTDllSectionHandle,
HANDLE SectionHandle, HANDLE SectionHandle,
PVOID ImageBase) PVOID ImageBase)
@ -67,6 +66,7 @@ RtlpCreateFirstThread(HANDLE ProcessHandle,
else else
CreateSuspended = FALSE; CreateSuspended = FALSE;
/* create the process stack (first thead) */
BaseAddress = (PVOID)(STACK_TOP - dwStackSize); BaseAddress = (PVOID)(STACK_TOP - dwStackSize);
Status = NtAllocateVirtualMemory(ProcessHandle, Status = NtAllocateVirtualMemory(ProcessHandle,
&BaseAddress, &BaseAddress,
@ -88,7 +88,7 @@ RtlpCreateFirstThread(HANDLE ProcessHandle,
ThreadContext.SegDs = USER_DS; ThreadContext.SegDs = USER_DS;
ThreadContext.SegCs = USER_CS; ThreadContext.SegCs = USER_CS;
ThreadContext.SegSs = USER_DS; ThreadContext.SegSs = USER_DS;
ThreadContext.Esp = STACK_TOP - 16; ThreadContext.Esp = STACK_TOP - 20;
ThreadContext.EFlags = (1<<1) + (1<<9); ThreadContext.EFlags = (1<<1) + (1<<9);
DPRINT("ThreadContext.Eip %x\n",ThreadContext.Eip); DPRINT("ThreadContext.Eip %x\n",ThreadContext.Eip);
@ -123,6 +123,11 @@ RtlpCreateFirstThread(HANDLE ProcessHandle,
&DupSectionHandle, &DupSectionHandle,
sizeof(DupSectionHandle), sizeof(DupSectionHandle),
&BytesWritten); &BytesWritten);
NtWriteVirtualMemory(ProcessHandle,
(PVOID)(STACK_TOP - 16),
&Peb,
sizeof(PPEB),
&BytesWritten);
Status = NtCreateThread(&ThreadHandle, Status = NtCreateThread(&ThreadHandle,
THREAD_ALL_ACCESS, THREAD_ALL_ACCESS,
@ -221,7 +226,8 @@ RtlpMapFile(PUNICODE_STRING ApplicationName,
static NTSTATUS static NTSTATUS
RtlpCreatePeb ( RtlpCreatePpbAndPeb (
PPEB *PebPtr,
HANDLE ProcessHandle, HANDLE ProcessHandle,
PPPB Ppb) PPPB Ppb)
{ {
@ -233,9 +239,31 @@ RtlpCreatePeb (
PVOID PpbBase; PVOID PpbBase;
ULONG PpbSize; ULONG PpbSize;
PebBase = (PVOID)PEB_BASE; /* create the PPB */
PebSize = 0x1000; PpbBase = (PVOID)PEB_STARTUPINFO;
PpbSize = Ppb->TotalSize;
Status = NtAllocateVirtualMemory (
ProcessHandle,
&PpbBase,
0,
&PpbSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
return(Status);
DPRINT("Ppb size %x\n", PpbSize);
NtWriteVirtualMemory (
ProcessHandle,
PpbBase,
Ppb,
Ppb->TotalSize,
&BytesWritten);
/* create the PEB */
PebBase = (PVOID)PEB_BASE;
PebSize = 0x1000;
Status = NtAllocateVirtualMemory ( Status = NtAllocateVirtualMemory (
ProcessHandle, ProcessHandle,
&PebBase, &PebBase,
@ -244,34 +272,18 @@ RtlpCreatePeb (
MEM_COMMIT, MEM_COMMIT,
PAGE_READWRITE); PAGE_READWRITE);
memset(&Peb, 0, sizeof(Peb)); memset (&Peb, 0, sizeof(PEB));
Peb.Ppb = (PPPB)PEB_STARTUPINFO; Peb.Ppb = (PPPB)PpbBase;
NtWriteVirtualMemory(ProcessHandle,
(PVOID)PEB_BASE,
&Peb,
sizeof(Peb),
&BytesWritten);
PpbBase = (PVOID)PEB_STARTUPINFO;
PpbSize = Ppb->TotalSize;
Status = NtAllocateVirtualMemory(ProcessHandle,
&PpbBase,
0,
&PpbSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
return(Status);
DPRINT("Ppb size %x\n", PpbSize);
NtWriteVirtualMemory ( NtWriteVirtualMemory (
ProcessHandle, ProcessHandle,
(PVOID)PEB_STARTUPINFO, PebBase,
Ppb, &Peb,
Ppb->TotalSize, sizeof(PEB),
&BytesWritten); &BytesWritten);
*PebPtr = (PPEB)PebBase;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -293,8 +305,6 @@ RtlCreateUserProcess (
HANDLE hSection, hProcess, hThread; HANDLE hSection, hProcess, hThread;
NTSTATUS Status; NTSTATUS Status;
LPTHREAD_START_ROUTINE lpStartAddress = NULL; LPTHREAD_START_ROUTINE lpStartAddress = NULL;
LPVOID lpParameter = NULL;
WCHAR TempCommandLine[256];
PVOID BaseAddress; PVOID BaseAddress;
LARGE_INTEGER SectionOffset; LARGE_INTEGER SectionOffset;
IMAGE_NT_HEADERS Headers; IMAGE_NT_HEADERS Headers;
@ -304,6 +314,7 @@ RtlCreateUserProcess (
PROCESS_BASIC_INFORMATION ProcessBasicInfo; PROCESS_BASIC_INFORMATION ProcessBasicInfo;
CLIENT_ID LocalClientId; CLIENT_ID LocalClientId;
ULONG retlen; ULONG retlen;
PPEB Peb;
DPRINT ("RtlCreateUserProcess(CommandLine '%w')\n", DPRINT ("RtlCreateUserProcess(CommandLine '%w')\n",
CommandLine->Buffer); CommandLine->Buffer);
@ -358,8 +369,8 @@ RtlCreateUserProcess (
/* /*
* *
*/ */
DPRINT("Creating peb\n"); DPRINT("Creating PPB and PEB\n");
RtlpCreatePeb (hProcess, Ppb); RtlpCreatePpbAndPeb (&Peb, hProcess, Ppb);
DPRINT("Creating thread for process\n"); DPRINT("Creating thread for process\n");
lpStartAddress = (LPTHREAD_START_ROUTINE) lpStartAddress = (LPTHREAD_START_ROUTINE)
@ -371,10 +382,9 @@ RtlCreateUserProcess (
ThreadSd, ThreadSd,
Headers.OptionalHeader.SizeOfStackReserve, Headers.OptionalHeader.SizeOfStackReserve,
lpStartAddress, lpStartAddress,
lpParameter, Peb,
dwCreationFlags, dwCreationFlags,
&LocalClientId.UniqueThread, &LocalClientId.UniqueThread,
TempCommandLine,
NTDllSection, NTDllSection,
hSection, hSection,
(PVOID)Headers.OptionalHeader.ImageBase); (PVOID)Headers.OptionalHeader.ImageBase);

View file

@ -37,72 +37,21 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
/**********************************************************************
* NAME
* LdrLoadImage
*
* FUNCTION:
* Builds the initial environment for a process. Should be used
* to load the initial user process.
*
* ARGUMENTS:
* HANDLE ProcessHandle handle of the process to load the module into
* PUNICODE_STRING Filename name of the module to load
*
* RETURNS:
* NTSTATUS
*/
#define STACK_TOP (0xb0000000) #define STACK_TOP (0xb0000000)
static NTSTATUS LdrCreatePeb(HANDLE ProcessHandle) static NTSTATUS
LdrCreatePpb (
PPPB *PpbPtr,
HANDLE ProcessHandle
)
{ {
PVOID PebBase;
ULONG PebSize;
PEB Peb;
PVOID PpbBase; PVOID PpbBase;
ULONG PpbSize; ULONG PpbSize;
PPB Ppb; PPB Ppb;
ULONG BytesWritten; ULONG BytesWritten;
NTSTATUS Status; NTSTATUS Status;
PebBase = (PVOID)PEB_BASE;
PebSize = 0x1000;
memset(&Peb, 0, sizeof Peb);
Peb.Ppb = (PPPB)PEB_STARTUPINFO;
Status = ZwAllocateVirtualMemory (
ProcessHandle,
(PVOID*)&PebBase,
0,
&PebSize,
MEM_COMMIT,
PAGE_READWRITE
);
if (!NT_SUCCESS(Status))
{
DbgPrint ("Peb allocation failed \n");
DbgPrintErrorMessage (Status);
}
ZwWriteVirtualMemory (
ProcessHandle,
PebBase,
&Peb,
sizeof(Peb),
&BytesWritten);
/* write pointer to peb on the stack (parameter of NtProcessStartup) */
ZwWriteVirtualMemory(
ProcessHandle,
(PVOID) (STACK_TOP - 16),
&PebBase,
sizeof (PVOID),
& BytesWritten
);
/* Create process parameters block (PPB)*/ /* Create process parameters block (PPB)*/
PpbBase = (PVOID)PEB_STARTUPINFO; PpbBase = (PVOID)PEB_STARTUPINFO;
PpbSize = sizeof (PPB); PpbSize = sizeof (PPB);
@ -119,9 +68,11 @@ static NTSTATUS LdrCreatePeb(HANDLE ProcessHandle)
{ {
DbgPrint ("Ppb allocation failed \n"); DbgPrint ("Ppb allocation failed \n");
DbgPrintErrorMessage (Status); DbgPrintErrorMessage (Status);
return Status;
} }
memset(&Ppb, 0, sizeof(PPB)); /* initialize the ppb */
memset (&Ppb, 0, sizeof(PPB));
ZwWriteVirtualMemory ( ZwWriteVirtualMemory (
ProcessHandle, ProcessHandle,
@ -130,10 +81,75 @@ static NTSTATUS LdrCreatePeb(HANDLE ProcessHandle)
sizeof(PPB), sizeof(PPB),
&BytesWritten); &BytesWritten);
*PpbPtr = PpbBase;
return STATUS_SUCCESS;
}
static NTSTATUS
LdrCreatePeb (
PPEB *PebPtr,
HANDLE ProcessHandle,
PPPB Ppb
)
{
PPEB PebBase;
ULONG PebSize;
PEB Peb;
ULONG BytesWritten;
NTSTATUS Status;
PebBase = (PVOID)PEB_BASE;
PebSize = 0x1000;
Status = ZwAllocateVirtualMemory (
ProcessHandle,
(PVOID*)&PebBase,
0,
&PebSize,
MEM_COMMIT,
PAGE_READWRITE
);
if (!NT_SUCCESS(Status))
{
DbgPrint ("Peb allocation failed \n");
DbgPrintErrorMessage (Status);
}
/* initialize the peb */
memset(&Peb, 0, sizeof Peb);
Peb.Ppb = Ppb;
ZwWriteVirtualMemory (
ProcessHandle,
PebBase,
&Peb,
sizeof(Peb),
&BytesWritten);
*PebPtr = (PPEB)PebBase;
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
/**********************************************************************
* NAME
* LdrLoadImage
*
* FUNCTION:
* Builds the initial environment for a process. Should be used
* to load the initial user process.
*
* ARGUMENTS:
* HANDLE ProcessHandle handle of the process to load the module into
* PUNICODE_STRING Filename name of the module to load
*
* RETURNS:
* NTSTATUS
*/
NTSTATUS LdrLoadImage(HANDLE ProcessHandle, NTSTATUS LdrLoadImage(HANDLE ProcessHandle,
PUNICODE_STRING Filename) PUNICODE_STRING Filename)
{ {
@ -158,12 +174,15 @@ NTSTATUS LdrLoadImage(HANDLE ProcessHandle,
ULONG InitialViewSize; ULONG InitialViewSize;
ULONG i; ULONG i;
HANDLE DupSectionHandle; HANDLE DupSectionHandle;
WCHAR TmpNameBuffer [MAX_PATH]; WCHAR TmpNameBuffer [MAX_PATH];
PPPB Ppb;
PPEB Peb;
/* -- PART I -- */ /* -- PART I -- */
/* /*
* Locate and open NTDLL to determine ImageBase * Locate and open NTDLL to determine ImageBase
* and LdrStartup * and LdrStartup
@ -285,7 +304,7 @@ NTSTATUS LdrLoadImage(HANDLE ProcessHandle,
ULONG Base; ULONG Base;
Sections = (PIMAGE_SECTION_HEADER) SECHDROFFSET(BlockBuffer); Sections = (PIMAGE_SECTION_HEADER) SECHDROFFSET(BlockBuffer);
Base = Sections[i].VirtualAddress + ImageBase; Base = Sections[i].VirtualAddress + ImageBase;
Offset.u.LowPart = Sections[i].PointerToRawData; Offset.u.LowPart = Sections[i].PointerToRawData;
Offset.u.HighPart = 0; Offset.u.HighPart = 0;
Status = ZwMapViewOfSection(NTDllSectionHandle, Status = ZwMapViewOfSection(NTDllSectionHandle,
@ -440,6 +459,36 @@ NTSTATUS LdrLoadImage(HANDLE ProcessHandle,
/* -- PART III -- */ /* -- PART III -- */
/* Create the process parameter block (PPB) */
Status = LdrCreatePpb (&Ppb,
ProcessHandle);
if (!NT_SUCCESS(Status))
{
DPRINT("PPB creation failed ");
DbgPrintErrorMessage(Status);
/* FIXME: unmap the section here */
/* FIXME: destroy the section here */
return Status;
}
/* Create the process environment block (PEB) */
Status = LdrCreatePeb (&Peb,
ProcessHandle,
Ppb);
if (!NT_SUCCESS(Status))
{
DPRINT("PEB creation failed ");
DbgPrintErrorMessage(Status);
/* FIXME: unmap the section here */
/* FIXME: destroy the section here */
/* FIXME: free the PPB */
return Status;
}
/* /*
* Create page backed section for stack * Create page backed section for stack
*/ */
@ -449,6 +498,7 @@ NTSTATUS LdrLoadImage(HANDLE ProcessHandle,
); );
StackSize = StackSize =
NTHeaders->OptionalHeader.SizeOfStackReserve; NTHeaders->OptionalHeader.SizeOfStackReserve;
DbgPrint ("Stack size %x\n", StackSize);
Status = ZwAllocateVirtualMemory( Status = ZwAllocateVirtualMemory(
ProcessHandle, ProcessHandle,
@ -509,22 +559,23 @@ NTSTATUS LdrLoadImage(HANDLE ProcessHandle,
sizeof (DupSectionHandle), sizeof (DupSectionHandle),
& BytesWritten & BytesWritten
); );
/*
* Create a peb (grungy)
*/
Status = LdrCreatePeb(ProcessHandle);
if (!NT_SUCCESS(Status))
{
DbgPrint("LDR: Failed to create initial peb\n");
return (Status);
}
/* write pointer to peb on the stack (parameter of NtProcessStartup) */
ZwWriteVirtualMemory(
ProcessHandle,
(PVOID) (STACK_TOP - 16),
&Peb,
sizeof (ULONG),
&BytesWritten
);
DbgPrint ("NTOSKRNL: Peb = %x\n", Peb);
/* /*
* Initialize context to point to LdrStartup * Initialize context to point to LdrStartup
*/ */
memset(&Context,0,sizeof(CONTEXT)); memset(&Context,0,sizeof(CONTEXT));
Context.SegSs = USER_DS; Context.SegSs = USER_DS;
Context.Esp = STACK_TOP - 16; Context.Esp = STACK_TOP - 20;
Context.EFlags = 0x202; Context.EFlags = 0x202;
Context.SegCs = USER_CS; Context.SegCs = USER_CS;
Context.Eip = LdrStartupAddr; Context.Eip = LdrStartupAddr;