#include <internal/teb.h>
#include <ddk/ntddk.h>
-#define NDEBUG
+//#define NDEBUG
#include <internal/debug.h>
#include "syspath.h"
#define STACK_TOP (0xb0000000)
-static
-NTSTATUS
-LdrCreatePeb(HANDLE ProcessHandle)
+static NTSTATUS LdrCreatePeb(HANDLE ProcessHandle)
{
- NTSTATUS Status;
- PVOID PebBase;
- ULONG PebSize;
- NT_PEB Peb;
- ULONG BytesWritten;
-
-
- PebBase = (PVOID)PEB_BASE;
- PebSize = 0x1000;
- Status = ZwAllocateVirtualMemory(
- ProcessHandle,
- & PebBase,
- 0,
- & PebSize,
- MEM_COMMIT,
- PAGE_READWRITE
- );
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
+ NTSTATUS Status;
+ PVOID PebBase;
+ ULONG PebSize;
+ NT_PEB Peb;
+ ULONG BytesWritten;
- memset(
- & Peb,
- 0,
- sizeof Peb
- );
- Peb.StartupInfo = (PPROCESSINFOW) PEB_STARTUPINFO;
+ PebBase = (PVOID)PEB_BASE;
+ PebSize = 0x1000;
+ Status = ZwAllocateVirtualMemory(ProcessHandle,
+ &PebBase,
+ 0,
+ &PebSize,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+
+
+ memset(&Peb, 0, sizeof Peb);
+
+ Peb.StartupInfo = (PPROCESSINFOW) PEB_STARTUPINFO;
- ZwWriteVirtualMemory(
- ProcessHandle,
- (PVOID) PEB_BASE,
- & Peb,
- sizeof Peb,
- & BytesWritten
- );
+ ZwWriteVirtualMemory(ProcessHandle,
+ (PVOID)PEB_BASE,
+ &Peb,
+ sizeof(Peb),
+ &BytesWritten);
- return(STATUS_SUCCESS);
+ return(STATUS_SUCCESS);
}
-NTSTATUS
-LdrLoadImage (
- HANDLE ProcessHandle,
- PUNICODE_STRING Filename
- )
+NTSTATUS LdrLoadImage(HANDLE ProcessHandle,
+ PUNICODE_STRING Filename)
{
- CHAR BlockBuffer [1024];
- DWORD ImageBase;
- DWORD LdrStartupAddr;
- DWORD StackBase;
- ULONG ImageSize;
- ULONG StackSize;
- NTSTATUS Status;
- OBJECT_ATTRIBUTES FileObjectAttributes;
- HANDLE FileHandle;
- HANDLE SectionHandle;
- HANDLE NTDllSectionHandle;
- HANDLE ThreadHandle;
- HANDLE DupNTDllSectionHandle;
- CONTEXT Context;
- UNICODE_STRING DllPathname;
- PIMAGE_DOS_HEADER DosHeader;
- PIMAGE_NT_HEADERS NTHeaders;
- ULONG BytesWritten;
- ULONG InitialViewSize;
- ULONG i;
- HANDLE DupSectionHandle;
-
- WCHAR TmpNameBuffer [MAX_PATH];
-
-
+ CHAR BlockBuffer [1024];
+ DWORD ImageBase;
+ DWORD LdrStartupAddr;
+ DWORD StackBase;
+ ULONG ImageSize;
+ ULONG StackSize;
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES FileObjectAttributes;
+ HANDLE FileHandle;
+ HANDLE SectionHandle;
+ HANDLE NTDllSectionHandle;
+ HANDLE ThreadHandle;
+ HANDLE DupNTDllSectionHandle;
+ CONTEXT Context;
+ UNICODE_STRING DllPathname;
+ PIMAGE_DOS_HEADER DosHeader;
+ PIMAGE_NT_HEADERS NTHeaders;
+ ULONG BytesWritten;
+ ULONG InitialViewSize;
+ ULONG i;
+ HANDLE DupSectionHandle;
+
+ WCHAR TmpNameBuffer [MAX_PATH];
+
+
/* -- PART I -- */
- /*
- * Locate and open NTDLL to determine ImageBase
- * and LdrStartup
- */
- GetSystemDirectory(
- TmpNameBuffer,
- sizeof TmpNameBuffer
- );
- wcscat(
- TmpNameBuffer,
- L"\\ntdll.dll"
- );
- RtlInitUnicodeString(
- & DllPathname,
- TmpNameBuffer
- );
- InitializeObjectAttributes(
- & FileObjectAttributes,
- & DllPathname,
- 0,
- NULL,
- NULL
- );
- DPRINT("Opening NTDLL\n");
- Status = ZwOpenFile(
- & FileHandle,
- FILE_ALL_ACCESS,
- & FileObjectAttributes,
- NULL,
- 0,
- 0
- );
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NTDLL open failed ");
- DbgPrintErrorMessage(Status);
-
- return Status;
- }
- Status = ZwReadFile(
- FileHandle,
- 0,
- 0,
- 0,
- 0,
- BlockBuffer,
- sizeof BlockBuffer,
- 0,
- 0
- );
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NTDLL header read failed ");
- DbgPrintErrorMessage(Status);
- ZwClose(FileHandle);
-
- 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_MAGIC)
- || (DosHeader->e_lfanew == 0L)
- || (*(PULONG) NTHeaders != IMAGE_PE_MAGIC)
- )
- {
- DPRINT("NTDLL format invalid\n");
- ZwClose(FileHandle);
-
- return STATUS_UNSUCCESSFUL;
- }
- ImageBase = NTHeaders->OptionalHeader.ImageBase;
- ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
- /*
- * FIXME: retrieve the offset of LdrStartup from NTDLL
- */
- DPRINT("ImageBase %x\n",ImageBase);
- LdrStartupAddr =
- ImageBase
- + NTHeaders->OptionalHeader.AddressOfEntryPoint;
- /*
- * Create a section for NTDLL
- */
- Status = ZwCreateSection(
- & NTDllSectionHandle,
- SECTION_ALL_ACCESS,
- NULL,
- NULL,
- PAGE_READWRITE,
- MEM_COMMIT,
- FileHandle
- );
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NTDLL create section failed ");
- DbgPrintErrorMessage(Status);
- ZwClose(FileHandle);
-
- return Status;
- }
- /*
- * Map the NTDLL into the process
- */
- InitialViewSize =
- DosHeader->e_lfanew
- + sizeof (IMAGE_NT_HEADERS)
- + ( sizeof (IMAGE_SECTION_HEADER)
- * NTHeaders->FileHeader.NumberOfSections
- );
- Status = ZwMapViewOfSection(
- NTDllSectionHandle,
- ProcessHandle,
- (PVOID *) & ImageBase,
- 0,
- InitialViewSize,
- NULL,
- & InitialViewSize,
- 0,
- MEM_COMMIT,
- PAGE_READWRITE
- );
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NTDLL map view of secion failed ");
- DbgPrintErrorMessage(Status);
-
- /* FIXME: destroy the section here */
-
- ZwClose(FileHandle);
-
- return Status;
- }
- for ( i = 0;
- (i < NTHeaders->FileHeader.NumberOfSections);
- i++
- )
- {
- PIMAGE_SECTION_HEADER Sections;
- LARGE_INTEGER Offset;
- ULONG Base;
+ /*
+ * Locate and open NTDLL to determine ImageBase
+ * and LdrStartup
+ */
+ GetSystemDirectory(TmpNameBuffer, sizeof TmpNameBuffer);
+ wcscat(TmpNameBuffer, L"\\ntdll.dll");
+ RtlInitUnicodeString(&DllPathname, TmpNameBuffer);
+ InitializeObjectAttributes(&FileObjectAttributes,
+ &DllPathname,
+ 0,
+ NULL,
+ NULL);
+ DPRINT("Opening NTDLL\n");
+ Status = ZwOpenFile(&FileHandle,
+ FILE_ALL_ACCESS,
+ &FileObjectAttributes,
+ NULL,
+ 0,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("NTDLL open failed ");
+ DbgPrintErrorMessage(Status);
+ return Status;
+ }
+ Status = ZwReadFile(FileHandle,
+ 0,
+ 0,
+ 0,
+ 0,
+ BlockBuffer,
+ sizeof BlockBuffer,
+ 0,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NTDLL header read failed ");
+ DbgPrintErrorMessage(Status);
+ ZwClose(FileHandle);
+ 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_MAGIC)
+ || (DosHeader->e_lfanew == 0L)
+ || (*(PULONG) NTHeaders != IMAGE_PE_MAGIC))
+ {
+ DPRINT("NTDLL format invalid\n");
+ ZwClose(FileHandle);
+ return STATUS_UNSUCCESSFUL;
+ }
+ ImageBase = NTHeaders->OptionalHeader.ImageBase;
+ ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
+ /*
+ * FIXME: retrieve the offset of LdrStartup from NTDLL
+ */
+ DPRINT("ImageBase %x\n",ImageBase);
+ LdrStartupAddr = ImageBase + NTHeaders->OptionalHeader.AddressOfEntryPoint;
+ /*
+ * Create a section for NTDLL
+ */
+ Status = ZwCreateSection(&NTDllSectionHandle,
+ SECTION_ALL_ACCESS,
+ NULL,
+ NULL,
+ PAGE_READWRITE,
+ MEM_COMMIT,
+ FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NTDLL create section failed ");
+ DbgPrintErrorMessage(Status);
+ ZwClose(FileHandle);
+
+ return Status;
+ }
+
+ /*
+ * Map the NTDLL into the process
+ */
+ InitialViewSize = DosHeader->e_lfanew
+ + sizeof (IMAGE_NT_HEADERS)
+ + ( sizeof (IMAGE_SECTION_HEADER)
+ * NTHeaders->FileHeader.NumberOfSections
+ );
+ Status = ZwMapViewOfSection(NTDllSectionHandle,
+ ProcessHandle,
+ (PVOID *) & ImageBase,
+ 0,
+ InitialViewSize,
+ NULL,
+ &InitialViewSize,
+ 0,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NTDLL map view of secion failed ");
+ DbgPrintErrorMessage(Status);
+
+ /* FIXME: destroy the section here */
- Sections =
- (PIMAGE_SECTION_HEADER) SECHDROFFSET(BlockBuffer);
- Base =
- Sections[i].VirtualAddress
- + ImageBase;
- Offset.u.LowPart =
- Sections[i].PointerToRawData;
- Offset.u.HighPart =
- 0;
- Status = ZwMapViewOfSection(
- NTDllSectionHandle,
- ProcessHandle,
- (PVOID *) & Base,
- 0,
- Sections[i].Misc.VirtualSize,
- & Offset,
- (PULONG) & Sections[i].Misc.VirtualSize,
- 0,
- MEM_COMMIT,
- PAGE_READWRITE
- );
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NTDLL map view of secion failed ");
- DbgPrintErrorMessage(Status);
-
- /* FIXME: destroy the section here */
-
- ZwClose(FileHandle);
- return Status;
- }
- }
ZwClose(FileHandle);
-/* -- PART II -- */
+ return Status;
+ }
+
+ for (i = 0;
+ (i < NTHeaders->FileHeader.NumberOfSections);
+ i++)
+ {
+ PIMAGE_SECTION_HEADER Sections;
+ LARGE_INTEGER Offset;
+ ULONG Base;
+
+ Sections = (PIMAGE_SECTION_HEADER) SECHDROFFSET(BlockBuffer);
+ Base = Sections[i].VirtualAddress + ImageBase;
+ Offset.u.LowPart = Sections[i].PointerToRawData;
+ Offset.u.HighPart = 0;
+ Status = ZwMapViewOfSection(NTDllSectionHandle,
+ ProcessHandle,
+ (PVOID *) & Base,
+ 0,
+ Sections[i].Misc.VirtualSize,
+ &Offset,
+ (PULONG) & Sections[i].Misc.VirtualSize,
+ 0,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NTDLL map view of secion failed ");
+ DbgPrintErrorMessage(Status);
+
+ /* FIXME: destroy the section here */
+
+ ZwClose(FileHandle);
+ return Status;
+ }
+ }
+ ZwClose(FileHandle);
+
+ /* -- PART II -- */
/*
* Open process image to determine ImageBase
* FIXME: The location of the initial process should be configurable,
* from command line or registry
*/
-NTSTATUS
-LdrLoadInitialProcess (VOID)
+NTSTATUS LdrLoadInitialProcess (VOID)
{
- NTSTATUS Status;
- HANDLE ProcessHandle;
- UNICODE_STRING ProcessName;
- WCHAR TmpNameBuffer [MAX_PATH];
-
-
- Status = ZwCreateProcess(
- & ProcessHandle,
- PROCESS_ALL_ACCESS,
- NULL,
- SystemProcessHandle,
- FALSE,
- NULL,
- NULL,
- NULL
- );
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("Could not create process\n");
- return Status;
- }
- /*
- * Get the system directory's name (a DOS device
- * alias name which is in \\??\\).
- */
- GetSystemDirectory(
- TmpNameBuffer,
- sizeof TmpNameBuffer
- );
- wcscat(
- TmpNameBuffer,
- L"\\shell.exe" /* FIXME: should be smss.exe */
- );
- RtlInitUnicodeString(
- & ProcessName,
- TmpNameBuffer
- );
- Status = LdrLoadImage(
- ProcessHandle,
- & ProcessName
- );
+ NTSTATUS Status;
+ HANDLE ProcessHandle;
+ UNICODE_STRING ProcessName;
+ WCHAR TmpNameBuffer [MAX_PATH];
+
+ Status = ZwCreateProcess(&ProcessHandle,
+ PROCESS_ALL_ACCESS,
+ NULL,
+ SystemProcessHandle,
+ FALSE,
+ NULL,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("Could not create process\n");
return Status;
+ }
+
+ /*
+ * Get the system directory's name (a DOS device
+ * alias name which is in \\??\\).
+ */
+ GetSystemDirectory(TmpNameBuffer, sizeof TmpNameBuffer);
+ wcscat(TmpNameBuffer, L"\\shell.exe");
+ RtlInitUnicodeString(&ProcessName, TmpNameBuffer);
+ Status = LdrLoadImage(ProcessHandle, &ProcessName);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("Failed to load %W\n",&ProcessName);
+ }
+ return Status;
}
/* EOF */