📄 connect.c
字号:
LpcWrite.Length = sizeof(PORT_VIEW);
LpcWrite.SectionHandle = CsrSectionHandle;
LpcWrite.SectionOffset = 0;
LpcWrite.ViewSize = CsrSectionViewSize.u.LowPart;
LpcWrite.ViewBase = 0;
LpcWrite.ViewRemoteBase = 0;
LpcRead.Length = sizeof(REMOTE_PORT_VIEW);
LpcRead.ViewSize = 0;
LpcRead.ViewBase = 0;
/* Setup the QoS */
SecurityQos.ImpersonationLevel = SecurityImpersonation;
SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
SecurityQos.EffectiveOnly = TRUE;
/* Setup the connection info */
ConnectionInfo.Version = 0x10000;
/* Create a SID for us */
Status = RtlAllocateAndInitializeSid(&NtSidAuthority,
1,
SECURITY_LOCAL_SYSTEM_RID,
0,
0,
0,
0,
0,
0,
0,
&SystemSid);
if (!NT_SUCCESS(Status))
{
/* Failure */
DPRINT1("Couldn't allocate SID\n");
NtClose(CsrSectionHandle);
return Status;
}
/* Connect to the port */
Status = NtSecureConnectPort(&CsrApiPort,
&PortName,
&SecurityQos,
&LpcWrite,
SystemSid,
&LpcRead,
NULL,
&ConnectionInfo,
&ConnectionInfoLength);
NtClose(CsrSectionHandle);
if (!NT_SUCCESS(Status))
{
/* Failure */
DPRINT1("Couldn't connect to CSR port\n");
return Status;
}
/* Save the delta between the sections, for capture usage later */
CsrPortMemoryDelta = (ULONG_PTR)LpcWrite.ViewRemoteBase -
(ULONG_PTR)LpcWrite.ViewBase;
/* Save the Process */
CsrProcessId = ConnectionInfo.ProcessId;
/* Save CSR Section data */
NtCurrentPeb()->ReadOnlySharedMemoryBase = ConnectionInfo.SharedSectionBase;
NtCurrentPeb()->ReadOnlySharedMemoryHeap = ConnectionInfo.SharedSectionHeap;
NtCurrentPeb()->ReadOnlyStaticServerData = ConnectionInfo.SharedSectionData;
/* Create the port heap */
CsrPortHeap = RtlCreateHeap(0,
LpcWrite.ViewBase,
LpcWrite.ViewSize,
PAGE_SIZE,
0,
0);
if (CsrPortHeap == NULL)
{
NtClose(CsrApiPort);
CsrApiPort = NULL;
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Return success */
return STATUS_SUCCESS;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
CsrClientConnectToServer(PWSTR ObjectDirectory,
ULONG ServerId,
PVOID ConnectionInfo,
PULONG ConnectionInfoSize,
PBOOLEAN ServerToServerCall)
{
NTSTATUS Status;
PIMAGE_NT_HEADERS NtHeader;
UNICODE_STRING CsrSrvName;
HANDLE hCsrSrv;
ANSI_STRING CsrServerRoutineName;
PCSR_CAPTURE_BUFFER CaptureBuffer;
CSR_API_MESSAGE RosApiMessage;
CSR_API_MESSAGE2 ApiMessage;
PCSR_CLIENT_CONNECT ClientConnect = &ApiMessage.ClientConnect;
/* Validate the Connection Info */
DPRINT("CsrClientConnectToServer: %lx %p\n", ServerId, ConnectionInfo);
if (ConnectionInfo && (!ConnectionInfoSize || !*ConnectionInfoSize))
{
DPRINT1("Connection info given, but no length\n");
return STATUS_INVALID_PARAMETER;
}
/* Check if we're inside a CSR Process */
if (InsideCsrProcess)
{
/* Tell the client that we're already inside CSR */
if (ServerToServerCall) *ServerToServerCall = TRUE;
return STATUS_SUCCESS;
}
/*
* We might be in a CSR Process but not know it, if this is the first call.
* So let's find out.
*/
if (!(NtHeader = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress)))
{
/* The image isn't valid */
DPRINT1("Invalid image\n");
return STATUS_INVALID_IMAGE_FORMAT;
}
InsideCsrProcess = (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE);
/* Now we can check if we are inside or not */
if (InsideCsrProcess && !UsingOldCsr)
{
/* We're inside, so let's find csrsrv */
DbgBreakPoint();
RtlInitUnicodeString(&CsrSrvName, L"csrsrv");
Status = LdrGetDllHandle(NULL,
NULL,
&CsrSrvName,
&hCsrSrv);
RtlFreeUnicodeString(&CsrSrvName);
/* Now get the Server to Server routine */
RtlInitAnsiString(&CsrServerRoutineName, "CsrCallServerFromServer");
Status = LdrGetProcedureAddress(hCsrSrv,
&CsrServerRoutineName,
0L,
(PVOID*)&CsrServerApiRoutine);
/* Use the local heap as port heap */
CsrPortHeap = RtlGetProcessHeap();
/* Tell the caller we're inside the server */
*ServerToServerCall = InsideCsrProcess;
return STATUS_SUCCESS;
}
/* Now check if connection info is given */
if (ConnectionInfo)
{
/* Well, we're defintely in a client now */
InsideCsrProcess = FALSE;
/* Do we have a connection to CSR yet? */
if (!CsrApiPort)
{
/* No, set it up now */
if (!NT_SUCCESS(Status = CsrConnectToServer(ObjectDirectory)))
{
/* Failed */
DPRINT1("Failure to connect to CSR\n");
return Status;
}
}
/* Setup the connect message header */
ClientConnect->ServerId = ServerId;
ClientConnect->ConnectionInfoSize = *ConnectionInfoSize;
/* Setup a buffer for the connection info */
CaptureBuffer = CsrAllocateCaptureBuffer(1,
ClientConnect->ConnectionInfoSize);
if (CaptureBuffer == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Allocate a pointer for the connection info*/
CsrAllocateMessagePointer(CaptureBuffer,
ClientConnect->ConnectionInfoSize,
&ClientConnect->ConnectionInfo);
/* Copy the data into the buffer */
RtlMoveMemory(ClientConnect->ConnectionInfo,
ConnectionInfo,
ClientConnect->ConnectionInfoSize);
/* Return the allocated length */
*ConnectionInfoSize = ClientConnect->ConnectionInfoSize;
/* Call CSR */
#if 0
Status = CsrClientCallServer(&ApiMessage,
CaptureBuffer,
CSR_MAKE_OPCODE(CsrSrvClientConnect,
CSR_SRV_DLL),
sizeof(CSR_CLIENT_CONNECT));
#endif
Status = CsrClientCallServer(&RosApiMessage,
NULL,
MAKE_CSR_API(CONNECT_PROCESS, CSR_NATIVE),
sizeof(CSR_API_MESSAGE));
}
else
{
/* No connection info, just return */
Status = STATUS_SUCCESS;
}
/* Let the caller know if this was server to server */
DPRINT("Status was: 0x%lx. Are we in server: 0x%x\n", Status, InsideCsrProcess);
if (ServerToServerCall) *ServerToServerCall = InsideCsrProcess;
return Status;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -