📄 init.c
字号:
OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
0,
&DosDevicesSd);
/* Create it */
Status = NtCreateDirectoryObject(&SessionObjectDirectory,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
/* Release the Security Descriptor */
CsrFreeDosDevicesSd(&DosDevicesSd);
return Status;
}
/* Next, create a directory for this session's DOS Devices */
/* Now create a directory for this session */
RtlInitUnicodeString(&SessionString, L"DosDevices");
/* Initialize the attributes for the Directory */
InitializeObjectAttributes(&ObjectAttributes,
&SessionString,
OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
0,
&DosDevicesSd);
/* Create it */
Status = NtCreateDirectoryObject(&DosDevicesDirectory,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
}
/* Release the Security Descriptor */
CsrFreeDosDevicesSd(&DosDevicesSd);
/* Return */
return Status;
}
/*++
* @name CsrSetProcessSecurity
*
* The CsrSetProcessSecurity routine protects access to the CSRSS process
* from unauthorized tampering.
*
* @param None.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSetProcessSecurity(VOID)
{
NTSTATUS Status;
HANDLE hToken;
ULONG ReturnLength;
PTOKEN_USER TokenUserInformation;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PACL Dacl;
/* Open our token */
Status = NtOpenProcessToken(NtCurrentProcess(),
TOKEN_QUERY,
&hToken);
if (!NT_SUCCESS(Status)) return Status;
/* Get the Token User Length */
NtQueryInformationToken(hToken,
TokenUser,
NULL,
0,
&ReturnLength);
/* Allocate space for it */
TokenUserInformation = RtlAllocateHeap(CsrHeap,
HEAP_ZERO_MEMORY,
ReturnLength);
/* Now query the data */
Status = NtQueryInformationToken(hToken,
TokenUser,
TokenUserInformation,
ReturnLength,
&ReturnLength);
/* Close the handle */
NtClose(hToken);
/* Make sure that we got the data */
if (!NT_SUCCESS(Status))
{
/* FAil */
RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
return Status;
}
/* Now check the SID Length */
ReturnLength = RtlLengthSid(TokenUserInformation->User.Sid);
/* Allocate a buffer for the Security Descriptor, with SID and DACL */
SecurityDescriptor = RtlAllocateHeap(CsrHeap,
HEAP_ZERO_MEMORY,
SECURITY_DESCRIPTOR_MIN_LENGTH +
sizeof(ACL) + ReturnLength +
sizeof(ACCESS_ALLOWED_ACE));
/* Set the pointer to the DACL */
Dacl = (PACL)((ULONG_PTR)SecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
/* Now create the SD itself */
Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status))
{
/* Fail */
RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
return Status;
}
/* Create the DACL for it*/
RtlCreateAcl(Dacl,
sizeof(ACL) + ReturnLength + sizeof(ACCESS_ALLOWED_ACE),
ACL_REVISION2);
/* Create the ACE */
Status = RtlAddAccessAllowedAce(Dacl,
ACL_REVISION,
PROCESS_VM_READ | PROCESS_VM_WRITE |
PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE |
PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME |
PROCESS_QUERY_INFORMATION | READ_CONTROL,
TokenUserInformation->User.Sid);
if (!NT_SUCCESS(Status))
{
/* Fail */
RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
return Status;
}
/* Clear the DACL in the SD */
Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
TRUE,
Dacl,
FALSE);
if (!NT_SUCCESS(Status))
{
/* Fail */
RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
return Status;
}
/* Write the SD into the Process */
Status = NtSetSecurityObject(NtCurrentProcess(),
DACL_SECURITY_INFORMATION,
SecurityDescriptor);
/* Free the memory and return */
RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
return Status;
}
/*++
* @name CsrSetDirectorySecurity
*
* The CsrSetDirectorySecurity routine sets the security descriptor for the
* specified Object Directory.
*
* @param ObjectDirectory
* Handle fo the Object Directory to protect.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSetDirectorySecurity(IN HANDLE ObjectDirectory)
{
/* FIXME: Implement */
return STATUS_SUCCESS;
}
/* PUBLIC FUNCTIONS **********************************************************/
/*++
* @name CsrServerInitialization
* @implemented NT4
*
* The CsrServerInitialization routine is the native (not Server) entrypoint
* of this Server DLL. It serves as the entrypoint for csrss.
*
* @param ArgumentCount
* Number of arguments on the command line.
*
* @param Arguments
* Array of arguments from the command line.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrServerInitialization(ULONG ArgumentCount,
PCHAR Arguments[])
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG i = 0;
PVOID ProcessData;
PCSR_SERVER_DLL ServerDll;
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
/* Create the Init Event */
Status = NtCreateEvent(&CsrInitializationEvent,
EVENT_ALL_ACCESS,
NULL,
SynchronizationEvent,
FALSE);
/* Cache System Basic Information so we don't always request it */
Status = NtQuerySystemInformation(SystemBasicInformation,
&CsrNtSysInfo,
sizeof(SYSTEM_BASIC_INFORMATION),
NULL);
/* Save our Heap */
CsrHeap = RtlGetProcessHeap();
/* Set our Security Descriptor to protect the process */
CsrSetProcessSecurity();
/* Set up Session Support */
Status = CsrInitializeNtSessions();
if(!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Set up Process Support */
Status = CsrInitializeProcesses();
if(!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrInitializeProcesses failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Parse the command line */
CsrpParseCommandLine(ArgumentCount, Arguments);
/* All Server DLLs are now loaded, allocate a heap for the Root Process */
ProcessData = RtlAllocateHeap(CsrHeap,
HEAP_ZERO_MEMORY,
CsrTotalPerProcessDataLength);
/*
* Our Root Process was never officially initalized, so write the data
* for each Server DLL manually.
*/
for(i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
/* Get the current Server */
ServerDll = CsrLoadedServerDll[i];
/* Is it loaded, and does it have per process data? */
if (ServerDll && ServerDll->SizeOfProcessData)
{
/* It does, give it part of our allocated heap */
CsrRootProcess->ServerData[i] = ProcessData;
/* Move to the next heap position */
ProcessData = (PVOID)((ULONG_PTR)ProcessData +
ServerDll->SizeOfProcessData);
}
else
{
/* Nothing for this Server DLL */
CsrRootProcess->ServerData[i] = NULL;
}
}
/* Now initialize the Root Process manually as well */
for(i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
/* Get the current Server */
ServerDll = CsrLoadedServerDll[i];
/* Is it loaded, and does it a callback for new processes? */
if (ServerDll && ServerDll->NewProcessCallback)
{
/* Call the callback */
(*ServerDll->NewProcessCallback)(NULL, CsrRootProcess);
}
}
/* Now initialize our API Port */
Status = CsrApiPortInitialize();
if(!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Initialize the API Port for SM communication */
Status = CsrSbApiPortInitialize();
if(!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* We're all set! Connect to SM! */
Status = SmConnectToSm(&CsrSbApiPortName,
CsrSbApiPort,
IMAGE_SUBSYSTEM_WINDOWS_GUI,
&CsrSmApiPort);
if(!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Finito! Signal the event */
NtSetEvent(CsrInitializationEvent, NULL);
NtClose(CsrInitializationEvent);
/* Have us handle Hard Errors */
NtSetDefaultHardErrorPort(CsrApiPort);
/* Return status */
return Status;
}
/*++
* @name CsrPopulateDosDevices
* @implemented NT5.1
*
* The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel
* to populate the Dos Devices Object Directory for the session.
*
* @param None.
*
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
CsrPopulateDosDevices(VOID)
{
NTSTATUS Status;
PROCESS_DEVICEMAP_INFORMATION OldDeviceMap;
PROCESS_DEVICEMAP_INFORMATION NewDeviceMap;
/* Query the Device Map */
Status = NtQueryInformationProcess(NtCurrentProcess(),
ProcessDeviceMap,
&OldDeviceMap.Query,
sizeof(PROCESS_DEVICEMAP_INFORMATION),
NULL);
if (!NT_SUCCESS(Status)) return;
/* Set the new one */
NewDeviceMap.Set.DirectoryHandle = DosDevicesDirectory;
Status = NtSetInformationProcess(NtCurrentProcess(),
ProcessDeviceMap,
&NewDeviceMap,
sizeof(ULONG));
if (!NT_SUCCESS(Status)) return;
/* Populate the Directory */
CsrPopulateDosDevicesDirectory(DosDevicesDirectory, &OldDeviceMap);
}
BOOL
NTAPI
DllMain(HANDLE hDll,
DWORD dwReason,
LPVOID lpReserved)
{
/* We don't do much */
return TRUE;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -