mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Made process execution work again
svn path=/trunk/; revision=345
This commit is contained in:
parent
140b387c62
commit
fbcc7fb423
9 changed files with 542 additions and 369 deletions
447
reactos/lib/kernel32/process/create.c
Normal file
447
reactos/lib/kernel32/process/create.c
Normal file
|
@ -0,0 +1,447 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS system libraries
|
||||||
|
* FILE: lib/kernel32/proc/proc.c
|
||||||
|
* PURPOSE: Process functions
|
||||||
|
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* Created 01/11/98
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ****************************************************************/
|
||||||
|
|
||||||
|
#define WIN32_NO_PEHDR
|
||||||
|
#include <windows.h>
|
||||||
|
#include <kernel32/proc.h>
|
||||||
|
#include <kernel32/thread.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pe.h>
|
||||||
|
#include <internal/i386/segment.h>
|
||||||
|
#include <ntdll/ldr.h>
|
||||||
|
|
||||||
|
//#define NDEBUG
|
||||||
|
#include <kernel32/kernel32.h>
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
WINBOOL STDCALL CreateProcessA(LPCSTR lpApplicationName,
|
||||||
|
LPSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
WINBOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFO lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation)
|
||||||
|
/*
|
||||||
|
* FUNCTION: The CreateProcess function creates a new process and its
|
||||||
|
* primary thread. The new process executes the specified executable file
|
||||||
|
* ARGUMENTS:
|
||||||
|
*
|
||||||
|
* lpApplicationName = Pointer to name of executable module
|
||||||
|
* lpCommandLine = Pointer to command line string
|
||||||
|
* lpProcessAttributes = Process security attributes
|
||||||
|
* lpThreadAttributes = Thread security attributes
|
||||||
|
* bInheritHandles = Handle inheritance flag
|
||||||
|
* dwCreationFlags = Creation flags
|
||||||
|
* lpEnvironment = Pointer to new environment block
|
||||||
|
* lpCurrentDirectory = Pointer to current directory name
|
||||||
|
* lpStartupInfo = Pointer to startup info
|
||||||
|
* lpProcessInformation = Pointer to process information
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
WCHAR ApplicationNameW[MAX_PATH];
|
||||||
|
WCHAR CommandLineW[MAX_PATH];
|
||||||
|
WCHAR CurrentDirectoryW[MAX_PATH];
|
||||||
|
PWSTR PApplicationNameW;
|
||||||
|
PWSTR PCommandLineW;
|
||||||
|
PWSTR PCurrentDirectoryW;
|
||||||
|
|
||||||
|
DPRINT("CreateProcessA\n");
|
||||||
|
|
||||||
|
PApplicationNameW = InternalAnsiToUnicode(ApplicationNameW,
|
||||||
|
lpApplicationName,
|
||||||
|
MAX_PATH);
|
||||||
|
PCommandLineW = InternalAnsiToUnicode(CommandLineW,
|
||||||
|
lpCommandLine,
|
||||||
|
MAX_PATH);
|
||||||
|
PCurrentDirectoryW = InternalAnsiToUnicode(CurrentDirectoryW,
|
||||||
|
lpCurrentDirectory,
|
||||||
|
MAX_PATH);
|
||||||
|
return CreateProcessW(PApplicationNameW,
|
||||||
|
PCommandLineW,
|
||||||
|
lpProcessAttributes,
|
||||||
|
lpThreadAttributes,
|
||||||
|
bInheritHandles,
|
||||||
|
dwCreationFlags,
|
||||||
|
lpEnvironment,
|
||||||
|
PCurrentDirectoryW,
|
||||||
|
lpStartupInfo,
|
||||||
|
lpProcessInformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define STACK_TOP (0xb0000000)
|
||||||
|
|
||||||
|
HANDLE STDCALL CreateFirstThread(HANDLE ProcessHandle,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
DWORD dwStackSize,
|
||||||
|
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||||
|
LPVOID lpParameter,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPDWORD lpThreadId,
|
||||||
|
PWSTR lpCommandLine,
|
||||||
|
HANDLE NTDllSectionHandle,
|
||||||
|
HANDLE SectionHandle,
|
||||||
|
PVOID ImageBase)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
CONTEXT ThreadContext;
|
||||||
|
INITIAL_TEB InitialTeb;
|
||||||
|
BOOLEAN CreateSuspended = FALSE;
|
||||||
|
PVOID BaseAddress;
|
||||||
|
ULONG BytesWritten;
|
||||||
|
ULONG CommandLineLen;
|
||||||
|
HANDLE DupNTDllSectionHandle, DupSectionHandle;
|
||||||
|
|
||||||
|
if (lpCommandLine == NULL)
|
||||||
|
{
|
||||||
|
lpCommandLine = L"";
|
||||||
|
CommandLineLen = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CommandLineLen = wcslen(lpCommandLine) + 1;
|
||||||
|
}
|
||||||
|
CommandLineLen = CommandLineLen * sizeof(WCHAR);
|
||||||
|
CommandLineLen = (CommandLineLen & (~0x3)) + 4;
|
||||||
|
DPRINT("CommandLineLen %d\n",CommandLineLen);
|
||||||
|
|
||||||
|
|
||||||
|
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||||
|
ObjectAttributes.RootDirectory = NULL;
|
||||||
|
ObjectAttributes.ObjectName = NULL;
|
||||||
|
ObjectAttributes.Attributes = 0;
|
||||||
|
if (lpThreadAttributes != NULL)
|
||||||
|
{
|
||||||
|
if (lpThreadAttributes->bInheritHandle)
|
||||||
|
ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||||
|
ObjectAttributes.SecurityDescriptor =
|
||||||
|
lpThreadAttributes->lpSecurityDescriptor;
|
||||||
|
}
|
||||||
|
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
|
if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED)
|
||||||
|
CreateSuspended = TRUE;
|
||||||
|
else
|
||||||
|
CreateSuspended = FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BaseAddress = (PVOID)(STACK_TOP - dwStackSize);
|
||||||
|
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||||
|
&BaseAddress,
|
||||||
|
0,
|
||||||
|
(PULONG)&dwStackSize,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
memset(&ThreadContext,0,sizeof(CONTEXT));
|
||||||
|
ThreadContext.Eip = (ULONG)lpStartAddress;
|
||||||
|
ThreadContext.SegGs = USER_DS;
|
||||||
|
ThreadContext.SegFs = USER_DS;
|
||||||
|
ThreadContext.SegEs = USER_DS;
|
||||||
|
ThreadContext.SegDs = USER_DS;
|
||||||
|
ThreadContext.SegCs = USER_CS;
|
||||||
|
ThreadContext.SegSs = USER_DS;
|
||||||
|
ThreadContext.Esp = STACK_TOP - 16;
|
||||||
|
ThreadContext.EFlags = (1<<1) + (1<<9);
|
||||||
|
|
||||||
|
DPRINT("ThreadContext.Eip %x\n",ThreadContext.Eip);
|
||||||
|
|
||||||
|
NtDuplicateObject(NtCurrentProcess(),
|
||||||
|
&SectionHandle,
|
||||||
|
ProcessHandle,
|
||||||
|
&DupSectionHandle,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
NtDuplicateObject(NtCurrentProcess(),
|
||||||
|
&NTDllSectionHandle,
|
||||||
|
ProcessHandle,
|
||||||
|
&DupNTDllSectionHandle,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
|
||||||
|
NtWriteVirtualMemory(ProcessHandle,
|
||||||
|
(PVOID)(STACK_TOP - 4),
|
||||||
|
&DupNTDllSectionHandle,
|
||||||
|
sizeof(DupNTDllSectionHandle),
|
||||||
|
&BytesWritten);
|
||||||
|
NtWriteVirtualMemory(ProcessHandle,
|
||||||
|
(PVOID)(STACK_TOP - 8),
|
||||||
|
&ImageBase,
|
||||||
|
sizeof(ImageBase),
|
||||||
|
&BytesWritten);
|
||||||
|
NtWriteVirtualMemory(ProcessHandle,
|
||||||
|
(PVOID)(STACK_TOP - 12),
|
||||||
|
&DupSectionHandle,
|
||||||
|
sizeof(DupSectionHandle),
|
||||||
|
&BytesWritten);
|
||||||
|
|
||||||
|
|
||||||
|
Status = NtCreateThread(&ThreadHandle,
|
||||||
|
THREAD_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
ProcessHandle,
|
||||||
|
&ClientId,
|
||||||
|
&ThreadContext,
|
||||||
|
&InitialTeb,
|
||||||
|
CreateSuspended);
|
||||||
|
if ( lpThreadId != NULL )
|
||||||
|
memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
|
||||||
|
|
||||||
|
return ThreadHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE KERNEL32_MapFile(LPCWSTR lpApplicationName,
|
||||||
|
LPCWSTR lpCommandLine,
|
||||||
|
PIMAGE_NT_HEADERS Headers,
|
||||||
|
PIMAGE_DOS_HEADER DosHeader)
|
||||||
|
{
|
||||||
|
WCHAR TempApplicationName[256];
|
||||||
|
WCHAR TempFileName[256];
|
||||||
|
HANDLE hFile;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
LARGE_INTEGER FileOffset;
|
||||||
|
ULONG i;
|
||||||
|
WCHAR TempDirectoryName[256];
|
||||||
|
UNICODE_STRING ApplicationNameString;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE hSection;
|
||||||
|
|
||||||
|
hFile = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the application name
|
||||||
|
*/
|
||||||
|
TempApplicationName[0] = '\\';
|
||||||
|
TempApplicationName[1] = '?';
|
||||||
|
TempApplicationName[2] = '?';
|
||||||
|
TempApplicationName[3] = '\\';
|
||||||
|
TempApplicationName[4] = 0;
|
||||||
|
|
||||||
|
DPRINT("TempApplicationName '%w'\n",TempApplicationName);
|
||||||
|
|
||||||
|
if (lpApplicationName != NULL)
|
||||||
|
{
|
||||||
|
wcscpy(TempFileName, lpApplicationName);
|
||||||
|
|
||||||
|
DPRINT("TempFileName '%w'\n",TempFileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wcscpy(TempFileName, lpCommandLine);
|
||||||
|
|
||||||
|
DPRINT("TempFileName '%w'\n",TempFileName);
|
||||||
|
|
||||||
|
for (i=0; TempFileName[i]!=' ' && TempFileName[i] != 0; i++);
|
||||||
|
TempFileName[i]=0;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (TempFileName[1] != ':')
|
||||||
|
{
|
||||||
|
GetCurrentDirectoryW(MAX_PATH,TempDirectoryName);
|
||||||
|
wcscat(TempApplicationName,TempDirectoryName);
|
||||||
|
}
|
||||||
|
wcscat(TempApplicationName,TempFileName);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&ApplicationNameString, TempApplicationName);
|
||||||
|
|
||||||
|
DPRINT("ApplicationName %w\n",ApplicationNameString.Buffer);
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&ApplicationNameString,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
SecurityDescriptor);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to open the executable
|
||||||
|
*/
|
||||||
|
|
||||||
|
Status = NtOpenFile(&hFile,
|
||||||
|
SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
FILE_SHARE_DELETE|FILE_SHARE_READ,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastError(RtlNtStatusToDosError(Status));
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = NtReadFile(hFile,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
DosHeader,
|
||||||
|
sizeof(IMAGE_DOS_HEADER),
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastError(RtlNtStatusToDosError(Status));
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_LARGE_INTEGER_HIGH_PART(FileOffset, 0);
|
||||||
|
SET_LARGE_INTEGER_LOW_PART(FileOffset, DosHeader->e_lfanew);
|
||||||
|
|
||||||
|
Status = NtReadFile(hFile,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
Headers,
|
||||||
|
sizeof(IMAGE_NT_HEADERS),
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastError(RtlNtStatusToDosError(Status));
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Status = NtCreateSection(&hSection,
|
||||||
|
SECTION_ALL_ACCESS,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
PAGE_EXECUTE,
|
||||||
|
SEC_IMAGE,
|
||||||
|
hFile);
|
||||||
|
NtClose(hFile);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastError(RtlNtStatusToDosError(Status));
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(hSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NTDLL_BASE (0x80000000)
|
||||||
|
|
||||||
|
WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
|
||||||
|
LPWSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
WINBOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCWSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFO lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation)
|
||||||
|
{
|
||||||
|
HANDLE hSection, hProcess, hThread;
|
||||||
|
NTSTATUS Status;
|
||||||
|
LPTHREAD_START_ROUTINE lpStartAddress = NULL;
|
||||||
|
LPVOID lpParameter = NULL;
|
||||||
|
WCHAR TempCommandLine[256];
|
||||||
|
PVOID BaseAddress;
|
||||||
|
LARGE_INTEGER SectionOffset;
|
||||||
|
IMAGE_NT_HEADERS Headers;
|
||||||
|
IMAGE_DOS_HEADER DosHeader;
|
||||||
|
HANDLE NTDllSection;
|
||||||
|
ULONG InitialViewSize;
|
||||||
|
|
||||||
|
DPRINT("CreateProcessW(lpApplicationName '%w', lpCommandLine '%w')\n",
|
||||||
|
lpApplicationName,lpCommandLine);
|
||||||
|
|
||||||
|
wcscpy(TempCommandLine, lpCommandLine);
|
||||||
|
|
||||||
|
|
||||||
|
hSection = KERNEL32_MapFile(lpApplicationName,
|
||||||
|
lpCommandLine,
|
||||||
|
&Headers, &DosHeader);
|
||||||
|
|
||||||
|
Status = NtCreateProcess(&hProcess,
|
||||||
|
PROCESS_ALL_ACCESS,
|
||||||
|
NULL,
|
||||||
|
NtCurrentProcess(),
|
||||||
|
bInheritHandles,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map NT DLL into the process
|
||||||
|
*/
|
||||||
|
Status = LdrMapNTDllForProcess(hProcess,
|
||||||
|
&NTDllSection);
|
||||||
|
|
||||||
|
InitialViewSize = DosHeader.e_lfanew + sizeof(IMAGE_NT_HEADERS)
|
||||||
|
+ sizeof(IMAGE_SECTION_HEADER) * Headers.FileHeader.NumberOfSections;
|
||||||
|
|
||||||
|
BaseAddress = (PVOID)Headers.OptionalHeader.ImageBase;
|
||||||
|
LARGE_INTEGER_QUAD_PART(SectionOffset) = 0;
|
||||||
|
Status = NtMapViewOfSection(hSection,
|
||||||
|
hProcess,
|
||||||
|
&BaseAddress,
|
||||||
|
0,
|
||||||
|
InitialViewSize,
|
||||||
|
&SectionOffset,
|
||||||
|
&InitialViewSize,
|
||||||
|
0,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastError(RtlNtStatusToDosError(Status));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("Creating thread for process\n");
|
||||||
|
lpStartAddress = (LPTHREAD_START_ROUTINE)
|
||||||
|
((PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(NTDLL_BASE))->
|
||||||
|
AddressOfEntryPoint +
|
||||||
|
((PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(NTDLL_BASE))->ImageBase;
|
||||||
|
hThread = CreateFirstThread(hProcess,
|
||||||
|
lpThreadAttributes,
|
||||||
|
Headers.OptionalHeader.SizeOfStackReserve,
|
||||||
|
lpStartAddress,
|
||||||
|
lpParameter,
|
||||||
|
dwCreationFlags,
|
||||||
|
&lpProcessInformation->dwThreadId,
|
||||||
|
TempCommandLine,
|
||||||
|
NTDllSection,
|
||||||
|
hSection,
|
||||||
|
(PVOID)Headers.OptionalHeader.ImageBase);
|
||||||
|
|
||||||
|
if ( hThread == NULL )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
lpProcessInformation->hProcess = hProcess;
|
||||||
|
lpProcessInformation->hThread = hThread;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,339 +124,6 @@ PWSTR InternalAnsiToUnicode(PWSTR Out, LPCSTR In, ULONG MaxLength)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WINBOOL STDCALL CreateProcessA(LPCSTR lpApplicationName,
|
|
||||||
LPSTR lpCommandLine,
|
|
||||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
|
||||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
|
||||||
WINBOOL bInheritHandles,
|
|
||||||
DWORD dwCreationFlags,
|
|
||||||
LPVOID lpEnvironment,
|
|
||||||
LPCSTR lpCurrentDirectory,
|
|
||||||
LPSTARTUPINFO lpStartupInfo,
|
|
||||||
LPPROCESS_INFORMATION lpProcessInformation)
|
|
||||||
/*
|
|
||||||
* FUNCTION: The CreateProcess function creates a new process and its
|
|
||||||
* primary thread. The new process executes the specified executable file
|
|
||||||
* ARGUMENTS:
|
|
||||||
*
|
|
||||||
* lpApplicationName = Pointer to name of executable module
|
|
||||||
* lpCommandLine = Pointer to command line string
|
|
||||||
* lpProcessAttributes = Process security attributes
|
|
||||||
* lpThreadAttributes = Thread security attributes
|
|
||||||
* bInheritHandles = Handle inheritance flag
|
|
||||||
* dwCreationFlags = Creation flags
|
|
||||||
* lpEnvironment = Pointer to new environment block
|
|
||||||
* lpCurrentDirectory = Pointer to current directory name
|
|
||||||
* lpStartupInfo = Pointer to startup info
|
|
||||||
* lpProcessInformation = Pointer to process information
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
WCHAR ApplicationNameW[MAX_PATH];
|
|
||||||
WCHAR CommandLineW[MAX_PATH];
|
|
||||||
WCHAR CurrentDirectoryW[MAX_PATH];
|
|
||||||
PWSTR PApplicationNameW;
|
|
||||||
PWSTR PCommandLineW;
|
|
||||||
PWSTR PCurrentDirectoryW;
|
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
DPRINT("CreateProcessA\n");
|
|
||||||
|
|
||||||
PApplicationNameW = InternalAnsiToUnicode(ApplicationNameW,
|
|
||||||
lpApplicationName,
|
|
||||||
MAX_PATH);
|
|
||||||
PCommandLineW = InternalAnsiToUnicode(CommandLineW,
|
|
||||||
lpCommandLine,
|
|
||||||
MAX_PATH);
|
|
||||||
PCurrentDirectoryW = InternalAnsiToUnicode(CurrentDirectoryW,
|
|
||||||
lpCurrentDirectory,
|
|
||||||
MAX_PATH);
|
|
||||||
return CreateProcessW(PApplicationNameW,
|
|
||||||
PCommandLineW,
|
|
||||||
lpProcessAttributes,
|
|
||||||
lpThreadAttributes,
|
|
||||||
bInheritHandles,
|
|
||||||
dwCreationFlags,
|
|
||||||
lpEnvironment,
|
|
||||||
PCurrentDirectoryW,
|
|
||||||
lpStartupInfo,
|
|
||||||
lpProcessInformation);
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE STDCALL CreateFirstThread(HANDLE hProcess,
|
|
||||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
|
||||||
DWORD dwStackSize,
|
|
||||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
|
||||||
LPVOID lpParameter,
|
|
||||||
DWORD dwCreationFlags,
|
|
||||||
LPDWORD lpThreadId,
|
|
||||||
PWSTR lpCommandLine)
|
|
||||||
{
|
|
||||||
NTSTATUS errCode;
|
|
||||||
HANDLE ThreadHandle;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
CLIENT_ID ClientId;
|
|
||||||
CONTEXT ThreadContext;
|
|
||||||
INITIAL_TEB InitialTeb;
|
|
||||||
BOOLEAN CreateSuspended = FALSE;
|
|
||||||
ULONG BaseAddress;
|
|
||||||
ULONG BytesWritten;
|
|
||||||
ULONG Temp;
|
|
||||||
ULONG CommandLineLen;
|
|
||||||
|
|
||||||
if (lpCommandLine == NULL)
|
|
||||||
{
|
|
||||||
lpCommandLine = "";
|
|
||||||
CommandLineLen = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CommandLineLen = wcslen(lpCommandLine) + 1;
|
|
||||||
}
|
|
||||||
CommandLineLen = CommandLineLen * sizeof(WCHAR);
|
|
||||||
CommandLineLen = (CommandLineLen & (~0x3)) + 4;
|
|
||||||
DPRINT("CommandLineLen %d\n",CommandLineLen);
|
|
||||||
|
|
||||||
|
|
||||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
|
||||||
ObjectAttributes.RootDirectory = NULL;
|
|
||||||
ObjectAttributes.ObjectName = NULL;
|
|
||||||
ObjectAttributes.Attributes = 0;
|
|
||||||
if ( lpThreadAttributes != NULL ) {
|
|
||||||
if ( lpThreadAttributes->bInheritHandle )
|
|
||||||
ObjectAttributes.Attributes = OBJ_INHERIT;
|
|
||||||
ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
|
|
||||||
}
|
|
||||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
|
||||||
|
|
||||||
if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )
|
|
||||||
CreateSuspended = TRUE;
|
|
||||||
else
|
|
||||||
CreateSuspended = FALSE;
|
|
||||||
|
|
||||||
BaseAddress = 0;
|
|
||||||
ZwAllocateVirtualMemory(hProcess,
|
|
||||||
&BaseAddress,
|
|
||||||
0,
|
|
||||||
&dwStackSize,
|
|
||||||
MEM_COMMIT,
|
|
||||||
PAGE_READWRITE);
|
|
||||||
|
|
||||||
|
|
||||||
memset(&ThreadContext,0,sizeof(CONTEXT));
|
|
||||||
ThreadContext.Eip = lpStartAddress;
|
|
||||||
ThreadContext.SegGs = USER_DS;
|
|
||||||
ThreadContext.SegFs = USER_DS;
|
|
||||||
ThreadContext.SegEs = USER_DS;
|
|
||||||
ThreadContext.SegDs = USER_DS;
|
|
||||||
ThreadContext.SegCs = USER_CS;
|
|
||||||
ThreadContext.SegSs = USER_DS;
|
|
||||||
ThreadContext.Esp = BaseAddress + dwStackSize - CommandLineLen - 8;
|
|
||||||
ThreadContext.EFlags = (1<<1) + (1<<9);
|
|
||||||
|
|
||||||
NtWriteVirtualMemory(hProcess,
|
|
||||||
BaseAddress + dwStackSize - CommandLineLen,
|
|
||||||
lpCommandLine,
|
|
||||||
CommandLineLen,
|
|
||||||
&BytesWritten);
|
|
||||||
Temp = BaseAddress + dwStackSize - CommandLineLen;
|
|
||||||
NtWriteVirtualMemory(hProcess,
|
|
||||||
BaseAddress + dwStackSize - CommandLineLen - 4,
|
|
||||||
&Temp,
|
|
||||||
sizeof(Temp),
|
|
||||||
&BytesWritten);
|
|
||||||
|
|
||||||
errCode = NtCreateThread(&ThreadHandle,
|
|
||||||
THREAD_ALL_ACCESS,
|
|
||||||
&ObjectAttributes,
|
|
||||||
hProcess,
|
|
||||||
&ClientId,
|
|
||||||
&ThreadContext,
|
|
||||||
&InitialTeb,
|
|
||||||
CreateSuspended);
|
|
||||||
if ( lpThreadId != NULL )
|
|
||||||
memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
|
|
||||||
|
|
||||||
return ThreadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
|
|
||||||
LPWSTR lpCommandLine,
|
|
||||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
|
||||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
|
||||||
WINBOOL bInheritHandles,
|
|
||||||
DWORD dwCreationFlags,
|
|
||||||
LPVOID lpEnvironment,
|
|
||||||
LPCWSTR lpCurrentDirectory,
|
|
||||||
LPSTARTUPINFO lpStartupInfo,
|
|
||||||
LPPROCESS_INFORMATION lpProcessInformation)
|
|
||||||
{
|
|
||||||
HANDLE hFile, hSection, hProcess, hThread;
|
|
||||||
KPRIORITY PriorityClass;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
BOOLEAN CreateSuspended;
|
|
||||||
NTSTATUS errCode;
|
|
||||||
UNICODE_STRING ApplicationNameString;
|
|
||||||
LPTHREAD_START_ROUTINE lpStartAddress = NULL;
|
|
||||||
LPVOID lpParameter = NULL;
|
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
|
||||||
WCHAR TempApplicationName[256];
|
|
||||||
WCHAR TempFileName[256];
|
|
||||||
WCHAR TempDirectoryName[256];
|
|
||||||
WCHAR TempCommandLine[256];
|
|
||||||
ULONG i;
|
|
||||||
ULONG BaseAddress;
|
|
||||||
ULONG Size;
|
|
||||||
LARGE_INTEGER SectionOffset;
|
|
||||||
|
|
||||||
DPRINT("CreateProcessW(lpApplicationName '%w', lpCommandLine '%w')\n",
|
|
||||||
lpApplicationName,lpCommandLine);
|
|
||||||
|
|
||||||
wcscpy(TempCommandLine, lpCommandLine);
|
|
||||||
|
|
||||||
hFile = NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the application name
|
|
||||||
*/
|
|
||||||
TempApplicationName[0] = '\\';
|
|
||||||
TempApplicationName[1] = '?';
|
|
||||||
TempApplicationName[2] = '?';
|
|
||||||
TempApplicationName[3] = '\\';
|
|
||||||
TempApplicationName[4] = 0;
|
|
||||||
|
|
||||||
DPRINT("TempApplicationName '%w'\n",TempApplicationName);
|
|
||||||
|
|
||||||
if (lpApplicationName != NULL)
|
|
||||||
{
|
|
||||||
wcscpy(TempFileName, lpApplicationName);
|
|
||||||
|
|
||||||
DPRINT("TempFileName '%w'\n",TempFileName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wcscpy(TempFileName, lpCommandLine);
|
|
||||||
|
|
||||||
DPRINT("TempFileName '%w'\n",TempFileName);
|
|
||||||
|
|
||||||
for (i=0; TempFileName[i]!=' ' && TempFileName[i] != 0; i++);
|
|
||||||
TempFileName[i]=0;
|
|
||||||
|
|
||||||
}
|
|
||||||
if (TempFileName[1] != ':')
|
|
||||||
{
|
|
||||||
GetCurrentDirectoryW(MAX_PATH,TempDirectoryName);
|
|
||||||
wcscat(TempApplicationName,TempDirectoryName);
|
|
||||||
}
|
|
||||||
wcscat(TempApplicationName,TempFileName);
|
|
||||||
|
|
||||||
RtlInitUnicodeString(&ApplicationNameString, TempApplicationName);
|
|
||||||
|
|
||||||
DPRINT("ApplicationName %w\n",ApplicationNameString.Buffer);
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
&ApplicationNameString,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
NULL,
|
|
||||||
SecurityDescriptor);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to open the executable
|
|
||||||
*/
|
|
||||||
|
|
||||||
errCode = NtOpenFile(&hFile,
|
|
||||||
SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
|
|
||||||
&ObjectAttributes,
|
|
||||||
&IoStatusBlock,
|
|
||||||
FILE_SHARE_DELETE|FILE_SHARE_READ,
|
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
|
|
||||||
|
|
||||||
if ( !NT_SUCCESS(errCode) )
|
|
||||||
{
|
|
||||||
SetLastError(RtlNtStatusToDosError(errCode));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
errCode = NtCreateSection(&hSection,
|
|
||||||
SECTION_ALL_ACCESS,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
PAGE_EXECUTE,
|
|
||||||
SEC_IMAGE,
|
|
||||||
hFile);
|
|
||||||
NtClose(hFile);
|
|
||||||
|
|
||||||
if ( !NT_SUCCESS(errCode) )
|
|
||||||
{
|
|
||||||
SetLastError(RtlNtStatusToDosError(errCode));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
errCode = NtCreateProcess(&hProcess,
|
|
||||||
PROCESS_ALL_ACCESS,
|
|
||||||
NULL,
|
|
||||||
NtCurrentProcess(),
|
|
||||||
bInheritHandles,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
BaseAddress = (PVOID)0x10000;
|
|
||||||
LARGE_INTEGER_QUAD_PART(SectionOffset) = 0;
|
|
||||||
Size = 0x20000;
|
|
||||||
NtMapViewOfSection(hSection,
|
|
||||||
hProcess,
|
|
||||||
&BaseAddress,
|
|
||||||
0,
|
|
||||||
Size,
|
|
||||||
&SectionOffset,
|
|
||||||
&Size,
|
|
||||||
0,
|
|
||||||
MEM_COMMIT,
|
|
||||||
PAGE_READWRITE);
|
|
||||||
|
|
||||||
|
|
||||||
NtClose(hSection);
|
|
||||||
|
|
||||||
if ( !NT_SUCCESS(errCode) )
|
|
||||||
{
|
|
||||||
SetLastError(RtlNtStatusToDosError(errCode));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
PriorityClass = NORMAL_PRIORITY_CLASS;
|
|
||||||
NtSetInformationProcess(hProcess,
|
|
||||||
ProcessBasePriority,
|
|
||||||
&PriorityClass,
|
|
||||||
sizeof(KPRIORITY));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DPRINT("Creating thread for process\n");
|
|
||||||
lpStartAddress = BaseAddress;
|
|
||||||
hThread = CreateFirstThread(hProcess,
|
|
||||||
lpThreadAttributes,
|
|
||||||
16384, // 3 page ??
|
|
||||||
lpStartAddress,
|
|
||||||
lpParameter,
|
|
||||||
dwCreationFlags,
|
|
||||||
&lpProcessInformation->dwThreadId,
|
|
||||||
TempCommandLine);
|
|
||||||
|
|
||||||
if ( hThread == NULL )
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
lpProcessInformation->hProcess = hProcess;
|
|
||||||
lpProcessInformation->hThread = hThread;
|
|
||||||
|
|
||||||
GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
HANDLE STDCALL OpenProcess(DWORD dwDesiredAccess,
|
HANDLE STDCALL OpenProcess(DWORD dwDesiredAccess,
|
||||||
WINBOOL bInheritHandle,
|
WINBOOL bInheritHandle,
|
||||||
DWORD dwProcessId)
|
DWORD dwProcessId)
|
||||||
|
|
|
@ -461,3 +461,4 @@ wcsrchr
|
||||||
wcsicmp
|
wcsicmp
|
||||||
wcsnicmp
|
wcsnicmp
|
||||||
vsprintf
|
vsprintf
|
||||||
|
LdrMapNTDllForProcess
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <ntdll/ldr.h>
|
#include <ntdll/ldr.h>
|
||||||
#include <ntdll/rtl.h>
|
#include <ntdll/rtl.h>
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <ntdll/ntdll.h>
|
#include <ntdll/ntdll.h>
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
@ -28,27 +28,68 @@ extern unsigned int _image_base__;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS LdrMapNTDllForProcess(HANDLE ProcessHandle,
|
||||||
|
PHANDLE PtrNTDllSectionHandle)
|
||||||
|
{
|
||||||
|
ULONG InitialViewSize;
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE NTDllSectionHandle;
|
||||||
|
PVOID ImageBase;
|
||||||
|
PIMAGE_NT_HEADERS NTHeaders;
|
||||||
|
PIMAGE_DOS_HEADER PEDosHeader;
|
||||||
|
|
||||||
|
DPRINT("LdrMapNTDllForProcess(ProcessHandle %x)\n",ProcessHandle);
|
||||||
|
|
||||||
|
PEDosHeader = (PIMAGE_DOS_HEADER)LdrDllListHead.BaseAddress;
|
||||||
|
NTHeaders = (PIMAGE_NT_HEADERS)(LdrDllListHead.BaseAddress +
|
||||||
|
PEDosHeader->e_lfanew);
|
||||||
|
|
||||||
|
NTDllSectionHandle = LdrDllListHead.SectionHandle;
|
||||||
|
InitialViewSize = PEDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
|
||||||
|
+ sizeof(IMAGE_SECTION_HEADER) * NTHeaders->FileHeader.NumberOfSections;
|
||||||
|
ImageBase = LdrDllListHead.BaseAddress;
|
||||||
|
DPRINT("Mapping at %x\n",ImageBase);
|
||||||
|
Status = ZwMapViewOfSection(NTDllSectionHandle,
|
||||||
|
ProcessHandle,
|
||||||
|
(PVOID *)&ImageBase,
|
||||||
|
0,
|
||||||
|
InitialViewSize,
|
||||||
|
NULL,
|
||||||
|
&InitialViewSize,
|
||||||
|
0,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
LdrMapSections(ProcessHandle,
|
||||||
|
ImageBase,
|
||||||
|
NTDllSectionHandle,
|
||||||
|
NTHeaders);
|
||||||
|
*PtrNTDllSectionHandle = NTDllSectionHandle;
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
/* LdrStartup
|
/* LdrStartup
|
||||||
* FUNCTION:
|
* FUNCTION:
|
||||||
* Handles Process Startup Activities.
|
* Handles Process Startup Activities.
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* DWORD ImageBase The base address of the process image
|
* DWORD ImageBase The base address of the process image
|
||||||
*/
|
*/
|
||||||
VOID LdrStartup(HANDLE SectionHandle, DWORD ImageBase)
|
VOID LdrStartup(HANDLE SectionHandle,
|
||||||
|
DWORD ImageBase,
|
||||||
|
HANDLE NTDllSectionHandle)
|
||||||
{
|
{
|
||||||
PEPFUNC EntryPoint;
|
PEPFUNC EntryPoint;
|
||||||
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)\n",ImageBase,
|
DPRINT("LdrStartup(ImageBase %x, SectionHandle %x, "
|
||||||
SectionHandle);
|
"NTDllSectionHandle %x)\n",ImageBase,
|
||||||
|
SectionHandle, NTDllSectionHandle);
|
||||||
|
|
||||||
DPRINT("&_image_base__ %x\n",&_image_base__);
|
|
||||||
LdrDllListHead.BaseAddress = (PVOID)&_image_base__;
|
LdrDllListHead.BaseAddress = (PVOID)&_image_base__;
|
||||||
LdrDllListHead.Prev = &LdrDllListHead;
|
LdrDllListHead.Prev = &LdrDllListHead;
|
||||||
LdrDllListHead.Next = &LdrDllListHead;
|
LdrDllListHead.Next = &LdrDllListHead;
|
||||||
LdrDllListHead.SectionHandle = SectionHandle;
|
LdrDllListHead.SectionHandle = NTDllSectionHandle;
|
||||||
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);
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <ntdll/ldr.h>
|
#include <ntdll/ldr.h>
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <ntdll/ntdll.h>
|
#include <ntdll/ntdll.h>
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
@ -170,9 +170,10 @@ static NTSTATUS LdrFindDll(PDLL* Dll, PCHAR Name)
|
||||||
return(LdrLoadDll(Dll, Name));
|
return(LdrLoadDll(Dll, Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS LdrMapSections(PVOID ImageBase,
|
NTSTATUS LdrMapSections(HANDLE ProcessHandle,
|
||||||
HANDLE SectionHandle,
|
PVOID ImageBase,
|
||||||
PIMAGE_NT_HEADERS NTHeaders)
|
HANDLE SectionHandle,
|
||||||
|
PIMAGE_NT_HEADERS NTHeaders)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -188,7 +189,7 @@ static NTSTATUS LdrMapSections(PVOID ImageBase,
|
||||||
SET_LARGE_INTEGER_HIGH_PART(Offset,0);
|
SET_LARGE_INTEGER_HIGH_PART(Offset,0);
|
||||||
SET_LARGE_INTEGER_LOW_PART(Offset,Sections[i].PointerToRawData);
|
SET_LARGE_INTEGER_LOW_PART(Offset,Sections[i].PointerToRawData);
|
||||||
Status = ZwMapViewOfSection(SectionHandle,
|
Status = ZwMapViewOfSection(SectionHandle,
|
||||||
NtCurrentProcess(),
|
ProcessHandle,
|
||||||
(PVOID *)&Base,
|
(PVOID *)&Base,
|
||||||
0,
|
0,
|
||||||
Sections[i].Misc.VirtualSize,
|
Sections[i].Misc.VirtualSize,
|
||||||
|
@ -351,7 +352,7 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders,
|
||||||
ImportModuleDirectory->dwRVAModuleName));
|
ImportModuleDirectory->dwRVAModuleName));
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return 0;
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the import address list */
|
/* Get the import address list */
|
||||||
|
@ -411,7 +412,7 @@ PEPFUNC LdrPEStartup(PVOID ImageBase, HANDLE SectionHandle)
|
||||||
NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + DosHeader->e_lfanew);
|
NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + DosHeader->e_lfanew);
|
||||||
|
|
||||||
/* Initialize Image sections */
|
/* Initialize Image sections */
|
||||||
LdrMapSections(ImageBase, SectionHandle, NTHeaders);
|
LdrMapSections(NtCurrentProcess(), ImageBase, SectionHandle, NTHeaders);
|
||||||
|
|
||||||
if (ImageBase != (PVOID)NTHeaders->OptionalHeader.ImageBase)
|
if (ImageBase != (PVOID)NTHeaders->OptionalHeader.ImageBase)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/hal/x86/exp.c
|
* FILE: ntoskrnl/hal/x86/exp.c
|
||||||
* PURPOSE: Handling exceptions
|
* PURPOSE: Handling exceptions
|
||||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||||
* REVISION HISTORY:
|
* REVISION HISTORY:
|
||||||
* ??/??/??: Created
|
* ??/??/??: Created
|
||||||
*/
|
*/
|
||||||
|
@ -203,35 +203,38 @@ asmlinkage void exception_handler(unsigned int edi,
|
||||||
*/
|
*/
|
||||||
if (type < 19)
|
if (type < 19)
|
||||||
{
|
{
|
||||||
printk("%s Exception: %d(%x)\n",TypeStrings[type],type,error_code&0xffff);
|
DbgPrint("%s Exception: %d(%x)\n",TypeStrings[type],type,
|
||||||
|
error_code&0xffff);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printk("Exception: %d(%x)\n",type,error_code&0xffff);
|
DbgPrint("Exception: %d(%x)\n",type,error_code&0xffff);
|
||||||
}
|
}
|
||||||
printk("CS:EIP %x:%x\n",cs&0xffff,eip);
|
DbgPrint("Process: %x\n",PsGetCurrentThread()->Cid.UniqueProcess);
|
||||||
printk("DS %x ES %x FS %x GS %x\n",ds&0xffff,es&0xffff,fs&0xffff,
|
DbgPrint("Thread: %x\n",PsGetCurrentThread()->Cid.UniqueThread);
|
||||||
gs&0xfff);
|
DbgPrint("CS:EIP %x:%x\n",cs&0xffff,eip);
|
||||||
// for(;;);
|
DbgPrint("DS %x ES %x FS %x GS %x\n",ds&0xffff,es&0xffff,fs&0xffff,
|
||||||
printk("EAX: %.8x EBX: %.8x ECX: %.8x\n",eax,ebx,ecx);
|
gs&0xfff);
|
||||||
printk("EDX: %.8x EBP: %.8x ESI: %.8x\n",edx,ebp,esi);
|
// for(;;);
|
||||||
printk("EDI: %.8x EFLAGS: %.8x ",edi,eflags);
|
DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n",eax,ebx,ecx);
|
||||||
if ((cs&0xffff)==KERNEL_CS)
|
DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n",edx,ebp,esi);
|
||||||
|
DbgPrint("EDI: %.8x EFLAGS: %.8x ",edi,eflags);
|
||||||
|
if ((cs&0xffff) == KERNEL_CS)
|
||||||
{
|
{
|
||||||
printk("ESP %.8x\n",esp);
|
DbgPrint("ESP %.8x\n",esp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printk("ESP %.8x\n",esp);
|
DbgPrint("ESP %.8x\n",esp);
|
||||||
}
|
}
|
||||||
|
|
||||||
__asm__("movl %%cr2,%0\n\t"
|
__asm__("movl %%cr2,%0\n\t"
|
||||||
: "=d" (cr2));
|
: "=d" (cr2));
|
||||||
printk("cr2 %x\n",cr2);
|
DbgPrint("cr2 %x\n",cr2);
|
||||||
|
|
||||||
if ((cs&0xffff)==KERNEL_CS)
|
if ((cs&0xffff)==KERNEL_CS)
|
||||||
{
|
{
|
||||||
printk("ESP %x\n",esp);
|
DbgPrint("ESP %x\n",esp);
|
||||||
stack=(unsigned int *)(esp+24);
|
stack=(unsigned int *)(esp+24);
|
||||||
|
|
||||||
// #if 0
|
// #if 0
|
||||||
|
|
|
@ -910,7 +910,8 @@ NTSTATUS LdrLoadImage(HANDLE ProcessHandle, PUNICODE_STRING Filename)
|
||||||
ULONG ImageSize, StackSize;
|
ULONG ImageSize, StackSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
OBJECT_ATTRIBUTES FileObjectAttributes;
|
OBJECT_ATTRIBUTES FileObjectAttributes;
|
||||||
HANDLE FileHandle, SectionHandle, ThreadHandle;
|
HANDLE FileHandle, SectionHandle, NTDllSectionHandle, ThreadHandle;
|
||||||
|
HANDLE DupNTDllSectionHandle;
|
||||||
CONTEXT Context;
|
CONTEXT Context;
|
||||||
UNICODE_STRING DllPathname;
|
UNICODE_STRING DllPathname;
|
||||||
PIMAGE_DOS_HEADER DosHeader;
|
PIMAGE_DOS_HEADER DosHeader;
|
||||||
|
@ -964,7 +965,7 @@ NTSTATUS LdrLoadImage(HANDLE ProcessHandle, PUNICODE_STRING Filename)
|
||||||
LdrStartupAddr = ImageBase + NTHeaders->OptionalHeader.AddressOfEntryPoint;
|
LdrStartupAddr = ImageBase + NTHeaders->OptionalHeader.AddressOfEntryPoint;
|
||||||
|
|
||||||
/* Create a section for NTDLL */
|
/* Create a section for NTDLL */
|
||||||
Status = ZwCreateSection(&SectionHandle,
|
Status = ZwCreateSection(&NTDllSectionHandle,
|
||||||
SECTION_ALL_ACCESS,
|
SECTION_ALL_ACCESS,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -983,7 +984,7 @@ NTSTATUS LdrLoadImage(HANDLE ProcessHandle, PUNICODE_STRING Filename)
|
||||||
/* Map the NTDLL into the process */
|
/* Map the NTDLL into the process */
|
||||||
InitialViewSize = DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
|
InitialViewSize = DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
|
||||||
+ sizeof(IMAGE_SECTION_HEADER) * NTHeaders->FileHeader.NumberOfSections;
|
+ sizeof(IMAGE_SECTION_HEADER) * NTHeaders->FileHeader.NumberOfSections;
|
||||||
Status = ZwMapViewOfSection(SectionHandle,
|
Status = ZwMapViewOfSection(NTDllSectionHandle,
|
||||||
ProcessHandle,
|
ProcessHandle,
|
||||||
(PVOID *)&ImageBase,
|
(PVOID *)&ImageBase,
|
||||||
0,
|
0,
|
||||||
|
@ -1014,7 +1015,7 @@ NTSTATUS LdrLoadImage(HANDLE ProcessHandle, PUNICODE_STRING Filename)
|
||||||
Base = Sections[i].VirtualAddress + ImageBase;
|
Base = Sections[i].VirtualAddress + ImageBase;
|
||||||
SET_LARGE_INTEGER_HIGH_PART(Offset,0);
|
SET_LARGE_INTEGER_HIGH_PART(Offset,0);
|
||||||
SET_LARGE_INTEGER_LOW_PART(Offset,Sections[i].PointerToRawData);
|
SET_LARGE_INTEGER_LOW_PART(Offset,Sections[i].PointerToRawData);
|
||||||
Status = ZwMapViewOfSection(SectionHandle,
|
Status = ZwMapViewOfSection(NTDllSectionHandle,
|
||||||
ProcessHandle,
|
ProcessHandle,
|
||||||
(PVOID *)&Base,
|
(PVOID *)&Base,
|
||||||
0,
|
0,
|
||||||
|
@ -1150,14 +1151,26 @@ NTSTATUS LdrLoadImage(HANDLE ProcessHandle, PUNICODE_STRING Filename)
|
||||||
0,
|
0,
|
||||||
FALSE,
|
FALSE,
|
||||||
DUPLICATE_SAME_ACCESS);
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
ZwDuplicateObject(NtCurrentProcess(),
|
||||||
|
&NTDllSectionHandle,
|
||||||
|
ProcessHandle,
|
||||||
|
&DupNTDllSectionHandle,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
|
||||||
ZwWriteVirtualMemory(ProcessHandle,
|
ZwWriteVirtualMemory(ProcessHandle,
|
||||||
(PVOID)(STACK_TOP - 4),
|
(PVOID)(STACK_TOP - 4),
|
||||||
|
&DupNTDllSectionHandle,
|
||||||
|
sizeof(DupNTDllSectionHandle),
|
||||||
|
&BytesWritten);
|
||||||
|
ZwWriteVirtualMemory(ProcessHandle,
|
||||||
|
(PVOID)(STACK_TOP - 8),
|
||||||
&ImageBase,
|
&ImageBase,
|
||||||
sizeof(ImageBase),
|
sizeof(ImageBase),
|
||||||
&BytesWritten);
|
&BytesWritten);
|
||||||
ZwWriteVirtualMemory(ProcessHandle,
|
ZwWriteVirtualMemory(ProcessHandle,
|
||||||
(PVOID)(STACK_TOP - 8),
|
(PVOID)(STACK_TOP - 12),
|
||||||
&DupSectionHandle,
|
&DupSectionHandle,
|
||||||
sizeof(DupSectionHandle),
|
sizeof(DupSectionHandle),
|
||||||
&BytesWritten);
|
&BytesWritten);
|
||||||
|
@ -1165,7 +1178,7 @@ NTSTATUS LdrLoadImage(HANDLE ProcessHandle, PUNICODE_STRING Filename)
|
||||||
/* 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 - 12;
|
Context.Esp = STACK_TOP - 16;
|
||||||
Context.EFlags = 0x202;
|
Context.EFlags = 0x202;
|
||||||
Context.SegCs = USER_CS;
|
Context.SegCs = USER_CS;
|
||||||
Context.Eip = LdrStartupAddr;
|
Context.Eip = LdrStartupAddr;
|
||||||
|
|
|
@ -52,6 +52,7 @@ ULONG PiNrRunnableThreads = 0;
|
||||||
static PETHREAD CurrentThread = NULL;
|
static PETHREAD CurrentThread = NULL;
|
||||||
|
|
||||||
static ULONG NextThreadUniqueId = 0;
|
static ULONG NextThreadUniqueId = 0;
|
||||||
|
//static ULONG NextProcessUniqueId = 0;
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
|
@ -256,6 +257,7 @@ NTSTATUS PsInitializeThread(HANDLE ProcessHandle,
|
||||||
InitializeListHead(&(Thread->IrpList));
|
InitializeListHead(&(Thread->IrpList));
|
||||||
Thread->Cid.UniqueThread = (HANDLE)InterlockedIncrement(
|
Thread->Cid.UniqueThread = (HANDLE)InterlockedIncrement(
|
||||||
&NextThreadUniqueId);
|
&NextThreadUniqueId);
|
||||||
|
DbgPrint("Thread->Cid.UniqueThread %d\n",Thread->Cid.UniqueThread);
|
||||||
ObReferenceObjectByPointer(Thread,
|
ObReferenceObjectByPointer(Thread,
|
||||||
THREAD_ALL_ACCESS,
|
THREAD_ALL_ACCESS,
|
||||||
PsThreadType,
|
PsThreadType,
|
||||||
|
|
|
@ -4,13 +4,11 @@ void InterlockedIncrement(void);
|
||||||
"_InterlockedIncrement:\n\t"
|
"_InterlockedIncrement:\n\t"
|
||||||
"pushl %ebp\n\t"
|
"pushl %ebp\n\t"
|
||||||
"movl %esp,%ebp\n\t"
|
"movl %esp,%ebp\n\t"
|
||||||
"pushl %eax\n\t"
|
|
||||||
"pushl %ebx\n\t"
|
"pushl %ebx\n\t"
|
||||||
"movl $1,%eax\n\t"
|
"movl $1,%eax\n\t"
|
||||||
"movl 8(%ebp),%ebx\n\t"
|
"movl 8(%ebp),%ebx\n\t"
|
||||||
"xaddl %eax,(%ebx)\n\t"
|
"xaddl %eax,(%ebx)\n\t"
|
||||||
"popl %ebx\n\t"
|
"popl %ebx\n\t"
|
||||||
"popl %eax\n\t"
|
|
||||||
"movl %ebp,%esp\n\t"
|
"movl %ebp,%esp\n\t"
|
||||||
"popl %ebp\n\t"
|
"popl %ebp\n\t"
|
||||||
"ret\n\t");
|
"ret\n\t");
|
||||||
|
|
Loading…
Reference in a new issue