Open BNO directory with correct privileges, open CSR connection with correct path. Add InWindows boolean to use the right CSR ServerID in windows and add a hack to get kernel32 to be loadable if used with .local to force an application to use our kernel and not the system one. The result of this is that our kernel32 can now load in Windows XP (not 2000).

svn path=/trunk/; revision=18097
This commit is contained in:
Alex Ionescu 2005-09-26 18:03:17 +00:00
parent 18a5faec31
commit 3438f98570
3 changed files with 193 additions and 100 deletions

View file

@ -36,7 +36,7 @@
#define DIRECTORY_TRAVERSE 0x0002
#define DIRECTORY_CREATE_OBJECT 0x0004
#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008
#define DIRECTORY_ALL_ACCESS STANDARD_RIGHTS_REQUIRED | 0xF
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
#endif
/* Duplication Flags */

View file

@ -55,7 +55,8 @@ BaseDumpAppcompatCache@0
BaseFlushAppcompatCache@0
;BaseInitAppcompatCache
;BaseInitAppcompatCacheSupport
;BaseProcessInitPostImport
BaseProcessInitPostImport@0
BaseQueryModuleData@20
BaseUpdateAppcompatCache@12
Beep@8
BeginUpdateResourceA@8

View file

@ -13,11 +13,9 @@
#include <k32.h>
#define NDEBUG
//#define NDEBUG
#include "../include/debug.h"
#define CSR_BASE_DLL 0 // <- This should be 1 when CSR gets committed
/* GLOBALS *******************************************************************/
extern UNICODE_STRING SystemDirectory;
@ -26,6 +24,8 @@ extern UNICODE_STRING WindowsDirectory;
HANDLE hProcessHeap = NULL;
HMODULE hCurrentModule = NULL;
HANDLE hBaseDir = NULL;
PPEB Peb;
ULONG SessionId;
static BOOL DllInitialized = FALSE;
static BOOL ConsoleInitialized = FALSE;
@ -44,6 +44,7 @@ extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAnd
extern BOOL FASTCALL NlsInit();
extern VOID FASTCALL NlsUninit();
BOOLEAN InWindows = FALSE;
HANDLE
STDCALL
@ -52,38 +53,74 @@ DuplicateConsoleHandle(HANDLE hConsole,
BOOL bInheritHandle,
DWORD dwOptions);
#define WIN_OBJ_DIR L"\\Windows"
#define SESSION_DIR L"\\Sessions"
/* FUNCTIONS *****************************************************************/
static NTSTATUS
NTSTATUS
WINAPI
OpenBaseDirectory(PHANDLE DirHandle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\BaseNamedObjects");
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\BaseNamedObjects");
NTSTATUS Status;
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE|OBJ_PERMANENT,
NULL,
NULL);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenDirectoryObject(DirHandle,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
Status = NtOpenDirectoryObject(DirHandle,
DIRECTORY_ALL_ACCESS &
~(DELETE | WRITE_DAC | WRITE_OWNER),
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
Status = NtCreateDirectoryObject(DirHandle,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DbgPrint("NtCreateDirectoryObject() failed\n");
}
return Status;
/* FIXME: It's not our job to create the BNO directory, csr does it */
Status = NtCreateDirectoryObject(DirHandle,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCreateDirectoryObject() failed\n");
}
}
return STATUS_SUCCESS;
DPRINT("Opened BNO: %lx\n", *DirHandle);
return Status;
}
/*
* @unimplemented
*/
BOOL
WINAPI
BaseQueryModuleData(IN LPSTR ModuleName,
IN LPSTR Unknown,
IN PVOID Unknown2,
IN PVOID Unknown3,
IN PVOID Unknown4)
{
DPRINT1("BaseQueryModuleData called: %s %s %x %x %x\n",
ModuleName,
Unknown,
Unknown2,
Unknown3,
Unknown4);
return FALSE;
}
/*
* @unimplemented
*/
NTSTATUS
WINAPI
BaseProcessInitPostImport(VOID)
{
/* FIXME: Initialize TS pointers */
return STATUS_SUCCESS;
}
BOOL
@ -210,20 +247,75 @@ DllMain(HANDLE hDll,
BOOLEAN IsServer;
ULONG Dummy;
ULONG DummySize = sizeof(Dummy);
WCHAR SessionDir[256];
DPRINT("DllMain(hInst %lx, dwReason %lu)\n",
hDll, dwReason);
/* Cache the PEB and Session ID */
Peb = NtCurrentPeb();
SessionId = Peb->SessionId;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
/* OK, yes, this is really retarded but it works for now */
InWindows = NtCurrentPeb()->BeingDebugged;
/*
* CreateProcess will run in the real kernel32 and it will write
* its own BaseProcessStartThunk EIP in the CONTEXT that ZwContinue
* will get. We'll be first called by Ldr while initializing, and we'll
* be wrapped in 3 layers of SEH, followed by two frames, finally
* followed by our CONTEXT on the stack. We'll modify the EIP in it
* to match the correct one (our own) and then everything works.
* Tested on XP and 2K3, probably doesn't work in 2K.
*/
if (InWindows)
{
/*
* Due to yet another bug in how Windows handles .local, LDR will
* actually end up loading us twice. The second time will be the
* "official" load, at a totally different address. It will be,
* it will be at -that- address that all the APIs will be called.
* However, that address is dynamic while this one will be static,
* so we'll do initilization with this one. Plus, at this one,
* we know exactly that we're within 3 SEH layers.
*/
if (hDll == (HANDLE)0x7c800000)
{
PULONG Eip;
Eip = (PULONG)*(PULONG)*(PULONG)NtCurrentTeb()->Tib.ExceptionList +
0x9 +
FIELD_OFFSET(CONTEXT, Eip) / sizeof(ULONG);
*Eip = (ULONG)BaseProcessStartThunk;
}
}
/* Don't bother us for each thread */
LdrDisableThreadCalloutsForDll((PVOID)hDll);
/* Setup the right Object Directory path */
if (!SessionId)
{
/* Use the raw path */
wcscpy(SessionDir, WIN_OBJ_DIR);
}
else
{
/* Use the session path */
swprintf(SessionDir,
L"%ws\\%ld%ws",
SESSION_DIR,
SessionId,
WIN_OBJ_DIR);
}
/* Connect to the base server */
Status = CsrClientConnectToServer(L"\\Windows", // <- FIXME: SessionDir
CSR_BASE_DLL,
DPRINT("Connecting to CSR...\n");
Status = CsrClientConnectToServer(SessionDir,
InWindows ? 1 : 0,
&Dummy,
&DummySize,
&IsServer);
@ -238,85 +330,85 @@ DllMain(HANDLE hDll,
if (!IsServer)
{
/* Set the termination port for the thread */
DPRINT("Creating new thread for CSR\n");
CsrNewThread();
}
hProcessHeap = RtlGetProcessHeap();
hCurrentModule = hDll;
hProcessHeap = RtlGetProcessHeap();
hCurrentModule = hDll;
DPRINT("Heap: %p\n", hProcessHeap);
/*
* Initialize WindowsDirectory and SystemDirectory
*/
DPRINT("NtSystemRoot: %S\n",
SharedUserData->NtSystemRoot);
RtlCreateUnicodeString (&WindowsDirectory,
SharedUserData->NtSystemRoot);
SystemDirectory.MaximumLength = WindowsDirectory.MaximumLength + 18;
SystemDirectory.Length = WindowsDirectory.Length + 18;
SystemDirectory.Buffer = RtlAllocateHeap (hProcessHeap,
0,
SystemDirectory.MaximumLength);
wcscpy (SystemDirectory.Buffer, WindowsDirectory.Buffer);
wcscat (SystemDirectory.Buffer, L"\\System32");
/*
* Initialize WindowsDirectory and SystemDirectory
*/
DPRINT("NtSystemRoot: %S\n", SharedUserData->NtSystemRoot);
RtlCreateUnicodeString (&WindowsDirectory, SharedUserData->NtSystemRoot);
SystemDirectory.MaximumLength = WindowsDirectory.MaximumLength + 18;
SystemDirectory.Length = WindowsDirectory.Length + 18;
SystemDirectory.Buffer = RtlAllocateHeap(hProcessHeap,
0,
SystemDirectory.MaximumLength);
wcscpy(SystemDirectory.Buffer, WindowsDirectory.Buffer);
wcscat(SystemDirectory.Buffer, L"\\System32");
/* Open object base directory */
Status = OpenBaseDirectory(&hBaseDir);
if (!NT_SUCCESS(Status))
{
DbgPrint("Failed to open object base directory (Status %lx)\n",
Status);
return FALSE;
}
/* Initialize the DLL critical section */
RtlInitializeCriticalSection(&DllLock);
/* Initialize the National Language Support routines */
if (! NlsInit())
{
/* Open object base directory */
Status = OpenBaseDirectory(&hBaseDir);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to open object base directory (Status %lx)\n", Status);
return FALSE;
}
}
/* Initialize Console Support */
if (!BasepInitConsole())
{
DPRINT1("Failure to set up console\n");
return FALSE;
/* Initialize the DLL critical section */
RtlInitializeCriticalSection(&DllLock);
/* Initialize the National Language Support routines */
if (!NlsInit())
{
DPRINT1("NLS Init failed\n");
return FALSE;
}
/* Initialize Console Support */
if (!BasepInitConsole())
{
DPRINT1("Failure to set up console\n");
return FALSE;
}
/* Insert more dll attach stuff here! */
DllInitialized = TRUE;
DPRINT1("Initialization complete\n");
break;
case DLL_PROCESS_DETACH:
DPRINT("DLL_PROCESS_DETACH\n");
if (DllInitialized == TRUE)
{
/* Insert more dll detach stuff here! */
NlsUninit();
/* Delete DLL critical section */
if (ConsoleInitialized == TRUE)
{
RtlDeleteCriticalSection (&ConsoleLock);
}
RtlDeleteCriticalSection (&DllLock);
/* Close object base directory */
NtClose(hBaseDir);
RtlFreeUnicodeString (&SystemDirectory);
RtlFreeUnicodeString (&WindowsDirectory);
}
break;
default:
break;
}
/* Insert more dll attach stuff here! */
DllInitialized = TRUE;
break;
case DLL_PROCESS_DETACH:
DPRINT("DLL_PROCESS_DETACH\n");
if (DllInitialized == TRUE)
{
/* Insert more dll detach stuff here! */
NlsUninit();
/* Delete DLL critical section */
if (ConsoleInitialized == TRUE)
{
RtlDeleteCriticalSection (&ConsoleLock);
}
RtlDeleteCriticalSection (&DllLock);
/* Close object base directory */
NtClose(hBaseDir);
RtlFreeUnicodeString (&SystemDirectory);
RtlFreeUnicodeString (&WindowsDirectory);
}
break;
default:
break;
}
return TRUE;
return TRUE;
}
/* EOF */