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_TRAVERSE 0x0002
#define DIRECTORY_CREATE_OBJECT 0x0004 #define DIRECTORY_CREATE_OBJECT 0x0004
#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008 #define DIRECTORY_CREATE_SUBDIRECTORY 0x0008
#define DIRECTORY_ALL_ACCESS STANDARD_RIGHTS_REQUIRED | 0xF #define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
#endif #endif
/* Duplication Flags */ /* Duplication Flags */

View file

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

View file

@ -13,11 +13,9 @@
#include <k32.h> #include <k32.h>
#define NDEBUG //#define NDEBUG
#include "../include/debug.h" #include "../include/debug.h"
#define CSR_BASE_DLL 0 // <- This should be 1 when CSR gets committed
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
extern UNICODE_STRING SystemDirectory; extern UNICODE_STRING SystemDirectory;
@ -26,6 +24,8 @@ extern UNICODE_STRING WindowsDirectory;
HANDLE hProcessHeap = NULL; HANDLE hProcessHeap = NULL;
HMODULE hCurrentModule = NULL; HMODULE hCurrentModule = NULL;
HANDLE hBaseDir = NULL; HANDLE hBaseDir = NULL;
PPEB Peb;
ULONG SessionId;
static BOOL DllInitialized = FALSE; static BOOL DllInitialized = FALSE;
static BOOL ConsoleInitialized = FALSE; static BOOL ConsoleInitialized = FALSE;
@ -44,6 +44,7 @@ extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAnd
extern BOOL FASTCALL NlsInit(); extern BOOL FASTCALL NlsInit();
extern VOID FASTCALL NlsUninit(); extern VOID FASTCALL NlsUninit();
BOOLEAN InWindows = FALSE;
HANDLE HANDLE
STDCALL STDCALL
@ -52,38 +53,74 @@ DuplicateConsoleHandle(HANDLE hConsole,
BOOL bInheritHandle, BOOL bInheritHandle,
DWORD dwOptions); DWORD dwOptions);
#define WIN_OBJ_DIR L"\\Windows"
#define SESSION_DIR L"\\Sessions"
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
static NTSTATUS NTSTATUS
WINAPI
OpenBaseDirectory(PHANDLE DirHandle) OpenBaseDirectory(PHANDLE DirHandle)
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\BaseNamedObjects"); UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\BaseNamedObjects");
NTSTATUS Status; NTSTATUS Status;
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&Name, &Name,
OBJ_CASE_INSENSITIVE|OBJ_PERMANENT, OBJ_CASE_INSENSITIVE,
NULL, NULL,
NULL); NULL);
Status = NtOpenDirectoryObject(DirHandle, Status = NtOpenDirectoryObject(DirHandle,
DIRECTORY_ALL_ACCESS, DIRECTORY_ALL_ACCESS &
&ObjectAttributes); ~(DELETE | WRITE_DAC | WRITE_OWNER),
if (!NT_SUCCESS(Status)) &ObjectAttributes);
if (!NT_SUCCESS(Status))
{ {
Status = NtCreateDirectoryObject(DirHandle, /* FIXME: It's not our job to create the BNO directory, csr does it */
DIRECTORY_ALL_ACCESS, Status = NtCreateDirectoryObject(DirHandle,
&ObjectAttributes); DIRECTORY_ALL_ACCESS,
if (!NT_SUCCESS(Status)) &ObjectAttributes);
{ if (!NT_SUCCESS(Status))
DbgPrint("NtCreateDirectoryObject() failed\n"); {
} DPRINT1("NtCreateDirectoryObject() failed\n");
}
return Status;
} }
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 BOOL
@ -210,20 +247,75 @@ DllMain(HANDLE hDll,
BOOLEAN IsServer; BOOLEAN IsServer;
ULONG Dummy; ULONG Dummy;
ULONG DummySize = sizeof(Dummy); ULONG DummySize = sizeof(Dummy);
WCHAR SessionDir[256];
DPRINT("DllMain(hInst %lx, dwReason %lu)\n", DPRINT("DllMain(hInst %lx, dwReason %lu)\n",
hDll, dwReason); hDll, dwReason);
/* Cache the PEB and Session ID */
Peb = NtCurrentPeb();
SessionId = Peb->SessionId;
switch (dwReason) switch (dwReason)
{ {
case DLL_PROCESS_ATTACH: 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 */ /* Don't bother us for each thread */
LdrDisableThreadCalloutsForDll((PVOID)hDll); 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 */ /* Connect to the base server */
Status = CsrClientConnectToServer(L"\\Windows", // <- FIXME: SessionDir DPRINT("Connecting to CSR...\n");
CSR_BASE_DLL, Status = CsrClientConnectToServer(SessionDir,
InWindows ? 1 : 0,
&Dummy, &Dummy,
&DummySize, &DummySize,
&IsServer); &IsServer);
@ -238,85 +330,85 @@ DllMain(HANDLE hDll,
if (!IsServer) if (!IsServer)
{ {
/* Set the termination port for the thread */ /* Set the termination port for the thread */
DPRINT("Creating new thread for CSR\n");
CsrNewThread(); CsrNewThread();
} }
hProcessHeap = RtlGetProcessHeap(); hProcessHeap = RtlGetProcessHeap();
hCurrentModule = hDll; hCurrentModule = hDll;
DPRINT("Heap: %p\n", hProcessHeap);
/* /*
* Initialize WindowsDirectory and SystemDirectory * Initialize WindowsDirectory and SystemDirectory
*/ */
DPRINT("NtSystemRoot: %S\n", DPRINT("NtSystemRoot: %S\n", SharedUserData->NtSystemRoot);
SharedUserData->NtSystemRoot); RtlCreateUnicodeString (&WindowsDirectory, SharedUserData->NtSystemRoot);
RtlCreateUnicodeString (&WindowsDirectory, SystemDirectory.MaximumLength = WindowsDirectory.MaximumLength + 18;
SharedUserData->NtSystemRoot); SystemDirectory.Length = WindowsDirectory.Length + 18;
SystemDirectory.MaximumLength = WindowsDirectory.MaximumLength + 18; SystemDirectory.Buffer = RtlAllocateHeap(hProcessHeap,
SystemDirectory.Length = WindowsDirectory.Length + 18; 0,
SystemDirectory.Buffer = RtlAllocateHeap (hProcessHeap, SystemDirectory.MaximumLength);
0, wcscpy(SystemDirectory.Buffer, WindowsDirectory.Buffer);
SystemDirectory.MaximumLength); wcscat(SystemDirectory.Buffer, L"\\System32");
wcscpy (SystemDirectory.Buffer, WindowsDirectory.Buffer);
wcscat (SystemDirectory.Buffer, L"\\System32");
/* Open object base directory */ /* Open object base directory */
Status = OpenBaseDirectory(&hBaseDir); Status = OpenBaseDirectory(&hBaseDir);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("Failed to open object base directory (Status %lx)\n", DPRINT1("Failed to open object base directory (Status %lx)\n", Status);
Status);
return FALSE;
}
/* Initialize the DLL critical section */
RtlInitializeCriticalSection(&DllLock);
/* Initialize the National Language Support routines */
if (! NlsInit())
{
return FALSE; return FALSE;
} }
/* Initialize Console Support */ /* Initialize the DLL critical section */
if (!BasepInitConsole()) RtlInitializeCriticalSection(&DllLock);
{
DPRINT1("Failure to set up console\n"); /* Initialize the National Language Support routines */
return FALSE; 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! */ return TRUE;
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;
} }
/* EOF */ /* EOF */