00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include <nt.h>
00023
#include <ntrtl.h>
00024
#include <nturtl.h>
00025
#include <windows.h>
00026
#include <stdlib.h>
00027
#include <stdio.h>
00028
#include <string.h>
00029
00030 #define PORT_NAME L"\\RPC Control\\LpcTestPort"
00031
00032 UNICODE_STRING
PortName;
00033
00034 char *
LpcMsgTypes[] = {
00035
"** INVALID **",
00036
"LPC_REQUEST",
00037
"LPC_REPLY",
00038
"LPC_DATAGRAM",
00039
"LPC_LOST_REPLY",
00040
"LPC_PORT_CLOSED",
00041
"LPC_CLIENT_DIED",
00042
"LPC_EXCEPTION",
00043
"LPC_DEBUG_EVENT",
00044
"LPC_ERROR_EVENT",
00045
"LPC_CONNECTION_REQUEST",
00046
NULL
00047 };
00048
00049 SECURITY_QUALITY_OF_SERVICE
DynamicQos = {
00050 SecurityImpersonation,
00051 SECURITY_DYNAMIC_TRACKING,
00052
TRUE
00053 };
00054
00055 #define TLPC_MAX_MSG_DATA_LENGTH 16
00056
00057 typedef struct _TLPC_PORTMSG {
00058 PORT_MESSAGE
h;
00059 ULONG
Data[
TLPC_MAX_MSG_DATA_LENGTH ];
00060 }
TLPC_PORTMSG, *
PTLPC_PORTMSG;
00061
00062 PCH
ClientMemoryBase = 0;
00063 ULONG
ClientMemorySize = 0;
00064 PCH
ServerMemoryBase = 0;
00065 ULONG
ServerMemoryDelta = 0;
00066
00067 typedef struct _PAGE {
00068 CHAR Data[ 4096 ];
00069 }
PAGE, *
PPAGE;
00070
00071 PPORT_MESSAGE
00072 InitTlpcMsg(
00073 PTLPC_PORTMSG Msg,
00074 PVOID Context,
00075 ULONG MsgLength
00076 )
00077 {
00078 ULONG i;
00079 ULONG ClientIndex;
00080 ULONG cbData = MsgLength % (
TLPC_MAX_MSG_DATA_LENGTH *
sizeof( ULONG ));
00081 PULONG ClientMemoryPtr;
00082
00083 Msg->
h.u1.Length = ((
sizeof( Msg->
h ) + cbData) << 16) | cbData;
00084 Msg->
h.u2.ZeroInit = 0;
00085 ClientIndex = (ULONG)Context & 0xF;
00086 ClientIndex -= 1;
00087
if (cbData) {
00088 Msg->
Data[ 0 ] = (ULONG)Context;
00089 ClientMemoryPtr = (PULONG)(
ClientMemoryBase + (ClientIndex * 0x1000));
00090
for (i=1; i<(cbData/
sizeof(ULONG)); i++) {
00091 *ClientMemoryPtr = (ULONG)Context;
00092 Msg->
Data[ i ] = (ULONG)ClientMemoryPtr +
ServerMemoryDelta;
00093 ClientMemoryPtr++;
00094 }
00095 }
00096
00097
return( (PPORT_MESSAGE)Msg );
00098 }
00099
00100 BOOLEAN
00101 CheckTlpcMsg(
00102 NTSTATUS Status,
00103 PTLPC_PORTMSG Msg
00104 )
00105 {
00106 ULONG i;
00107 ULONG ClientIndex;
00108 ULONG cbData = Msg->
h.u1.s1.DataLength;
00109 ULONG Context;
00110 PULONG ServerMemoryPtr;
00111 PULONG ClientMemoryPtr;
00112 ULONG ExpectedContext;
00113 BOOLEAN Result;
00114
00115
if (!
NT_SUCCESS(
Status )) {
00116 fprintf( stderr,
" - FAILED. Status == %X\n",
Status );
00117
return(
FALSE );
00118 }
00119
00120
if (Msg->
h.u2.s2.Type == LPC_CONNECTION_REQUEST) {
00121 fprintf( stderr,
" connection request" );
00122 }
00123
else
00124
if (cbData) {
00125 Context = Msg->
Data[ 0 ];
00126 ClientIndex = Context & 0xF;
00127 ClientIndex -= 1;
00128 ClientMemoryPtr = (PULONG)(
ClientMemoryBase + (ClientIndex * 0x1000));
00129
for (i=1; i<(cbData/
sizeof( ULONG )); i++) {
00130
if (Msg->
h.u2.s2.Type == LPC_REPLY) {
00131
if (Msg->
Data[ i ] != ((ULONG)ClientMemoryPtr +
ServerMemoryDelta) ||
00132 *ClientMemoryPtr != (ULONG)Context
00133 ) {
00134 fprintf( stderr,
" incorrectly\n" );
00135 fprintf( stderr,
" Msg->Data[ %ld ] == %lx != %lx || %lx -> %lx != %lx\n",
00136 i, Msg->
Data[ i ], (ULONG)ClientMemoryPtr +
ServerMemoryDelta,
00137 ClientMemoryPtr, *ClientMemoryPtr, Context
00138 );
00139
return(
FALSE );
00140 }
00141
00142 ClientMemoryPtr++;
00143 }
00144
else {
00145 ServerMemoryPtr = (PULONG)(Msg->
Data[ i ]);
00146
try {
00147 ExpectedContext = *ServerMemoryPtr;
00148 Result = (ExpectedContext != Context) ?
FALSE :
TRUE;
00149 }
00150 except(
EXCEPTION_EXECUTE_HANDLER ) {
00151 ExpectedContext = 0xFEFEFEFE;
00152 Result =
FALSE;
00153 }
00154
00155
if (!Result) {
00156 fprintf( stderr,
" incorrectly\n" );
00157 fprintf( stderr,
" Msg->Data[ %ld ] == %lx -> %lx != %lx\n",
00158 i, Msg->
Data[ i ], ExpectedContext, Context
00159 );
00160
return(
FALSE );
00161 }
00162 }
00163 }
00164 }
00165
00166 fprintf( stderr,
" correctly\n" );
00167
return(
TRUE );
00168 }
00169
00170
00171 BOOLEAN
00172 ShowHandleOrStatus(
00173 NTSTATUS Status,
00174 HANDLE Handle
00175 )
00176 {
00177
if (
NT_SUCCESS(
Status )) {
00178 fprintf( stderr,
" - Handle = 0x%lx\n",
Handle );
00179
return(
TRUE );
00180 }
00181
else {
00182 fprintf( stderr,
" - *** FAILED *** Status == %X\n",
Status );
00183
return(
FALSE );
00184 }
00185 }
00186
00187
00188 BOOLEAN
00189 ShowStatus(
00190 NTSTATUS Status
00191 )
00192 {
00193
if (
NT_SUCCESS(
Status )) {
00194 fprintf( stderr,
" - success\n" );
00195
return(
TRUE );
00196 }
00197
else {
00198 fprintf( stderr,
" - *** FAILED *** Status == %X\n",
Status );
00199
return(
FALSE );
00200 }
00201 }
00202
00203 PCH
EnterString =
">>>>>>>>>>";
00204 PCH
InnerString =
"||||||||||";
00205 PCH
LeaveString =
"<<<<<<<<<<";
00206
00207
NTSTATUS
00208 SendRequest(
00209 ULONG Level,
00210 PSZ ThreadName,
00211 HANDLE PortHandle,
00212 PVOID Context,
00213 ULONG MsgLength,
00214 PTLPC_PORTMSG CallBackTarget,
00215 BOOLEAN ServerCallingClient
00216 )
00217 {
00218
NTSTATUS Status;
00219
TLPC_PORTMSG Request, Reply;
00220 PTEB Teb = NtCurrentTeb();
00221
00222 fprintf( stderr,
"%.*sEnter SendRequest, %lx.%lx",
00223 Level,
EnterString,
00224 Teb->ClientId.UniqueProcess,
00225 Teb->ClientId.UniqueThread
00226 );
00227
00228
InitTlpcMsg( &
Request, Context, MsgLength );
00229
if (CallBackTarget ==
NULL) {
00230 fprintf( stderr,
" - Request");
00231 }
00232
else {
00233
Request.h.u2.s2.Type = LPC_REQUEST;
00234
Request.h.ClientId = CallBackTarget->
h.ClientId;
00235
Request.h.MessageId = CallBackTarget->
h.MessageId;
00236 fprintf( stderr,
" - Callback to %lx.%lx, ID: %ld",
00237
Request.h.ClientId.UniqueProcess,
00238
Request.h.ClientId.UniqueThread,
00239
Request.h.MessageId
00240 );
00241 }
00242
00243 fprintf( stderr,
" (%ld bytes)...\n",
Request.h.u1.s1.DataLength );
00244
Status =
NtRequestWaitReplyPort(
PortHandle,
00245 (PPORT_MESSAGE)&
Request,
00246 (PPORT_MESSAGE)&Reply
00247 );
00248 fprintf( stderr,
"%.*s %lx.%lx, ID: %u received ",
00249 Level,
InnerString,
00250 Teb->ClientId.UniqueProcess,
00251 Teb->ClientId.UniqueThread,
00252 Reply.h.MessageId
00253 );
00254
00255
if (Reply.h.u2.s2.Type == LPC_REPLY) {
00256
if (!
CheckTlpcMsg(
Status, &Reply )) {
00257
Status = STATUS_UNSUCCESSFUL;
00258 fprintf( stderr,
"SendRequest got invalid reply message at %x\n", &Reply );
00259 DbgBreakPoint();
00260 }
00261 }
00262
else {
00263 fprintf( stderr,
"callback from %lx.%lx, ID: %ld",
00264 Reply.h.ClientId.UniqueProcess,
00265 Reply.h.ClientId.UniqueThread,
00266 Reply.h.MessageId
00267 );
00268
if (!
CheckTlpcMsg(
Status, &Reply )) {
00269
Status = STATUS_UNSUCCESSFUL;
00270 fprintf( stderr,
"SendRequest got invalid callback message at %x\n", &Reply );
00271 DbgBreakPoint();
00272 }
00273
else {
00274 MsgLength = Reply.h.u1.s1.DataLength / 2;
00275
if (MsgLength) {
00276
Status =
SendRequest( Level+1,
00277 ThreadName,
00278
PortHandle,
00279 Context,
00280 MsgLength,
00281 &Reply,
00282 ServerCallingClient
00283 );
00284 }
00285
00286
if (!ServerCallingClient || Level > 1) {
00287 fprintf( stderr,
"%.*s %lx.%lx sending ",
00288 Level,
InnerString,
00289 Teb->ClientId.UniqueProcess,
00290 Teb->ClientId.UniqueThread
00291 );
00292 fprintf( stderr,
" callback (%u) reply to %lx.%lx, ID: %u (%ld bytes)...\n",
00293 Level,
00294 Reply.h.ClientId.UniqueProcess,
00295 Reply.h.ClientId.UniqueThread,
00296 Reply.h.MessageId,
00297 Reply.h.u1.s1.DataLength
00298 );
00299
if (Level > 1) {
00300
Status =
NtReplyWaitReplyPort(
PortHandle,
00301 (PPORT_MESSAGE)&Reply
00302 );
00303 }
00304 }
00305 }
00306 }
00307
00308 fprintf( stderr,
"%.*sLeave SendRequest, %lx.%lx - Status == %X\n",
00309 Level,
LeaveString,
00310 Teb->ClientId.UniqueProcess,
00311 Teb->ClientId.UniqueThread,
00312
Status
00313 );
00314
return(
Status );
00315 }
00316
00317
VOID
00318 EnterThread(
00319 PSZ ThreadName,
00320 ULONG Context
00321 )
00322 {
00323 fprintf( stderr,
"Entering %s thread, Context = 0x%lx\n",
00324 ThreadName,
00325 Context
00326 );
00327 }