//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1994 - 2001 // // File: rpcdbg.cxx // //-------------------------------------------------------------------------- /*++ Module Name: rpcdbg.cxx Abstract: Author: Jeff Roberts (jroberts) 13-May-1996 Revision History: 13-May-1996 jroberts Created this module. Mazhar Mohammed (mazharm) 3-20-97 - changed it all for async RPC, added some cool stuff single dll for ntsd and kd KamenM Dec 99 Added debugging support and multiple ntsd-through-kd sessions support GrigoriK Mar 2001 Added support for type info. --*/ #define KDEXT_64BIT #include #include #define DG_LOGGING #define private public #define protected public #include #include #include #include #include #include #include #include #define SECURITY_WIN32 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rpcexts.hxx" HANDLE ProcessHandle = 0; BOOL fKD = 0; // is debuggee a CHK build? BOOL ChkTarget; EXT_API_VERSION ApiVersion = { VER_PRODUCTVERSION_W >> 8, VER_PRODUCTVERSION_W & 0xff, EXT_API_VERSION_NUMBER64, 0 }; WINDBG_EXTENSION_APIS ExtensionApis; USHORT SavedMajorVersion; USHORT SavedMinorVersion; BOOL bDebuggingChecked; VOID WinDbgExtensionDllInit( PWINDBG_EXTENSION_APIS64 lpExtensionApis, USHORT MajorVersion, USHORT MinorVersion ) { KDDEBUGGER_DATA64 KdDebuggerData; ExtensionApis = *lpExtensionApis ; SavedMajorVersion = MajorVersion; SavedMinorVersion = MinorVersion; ChkTarget = SavedMajorVersion == 0x0c ? TRUE : FALSE; KdDebuggerData.Header.OwnerTag = KDBG_TAG; KdDebuggerData.Header.Size = sizeof( KdDebuggerData ); if (Ioctl( IG_GET_DEBUGGER_DATA, &KdDebuggerData, sizeof( KdDebuggerData ) )) { fKD = 1; } INIT_ADDRESS_SIZE; } // By default we use the type information in extensins. // This flag can be reset with !rpcexts.typeinfo off which will // disable the use of type information. !typeinfo on will // enable it. BOOL fUseTypeInfo = TRUE; int AddressSize = 0; // If not set, the _NOSPEW macros will not print debugger spew. // It is set to FALSE after the spew is printed by one of thise macros. BOOL fSpew = TRUE; char * BoolString( BOOL Value ) { switch (Value) { case TRUE: return "True"; case FALSE: return "False"; default: return "?????"; } } ULONG GetTypeSize(PUCHAR TypeName) { SYM_DUMP_PARAM Sym = { sizeof (SYM_DUMP_PARAM), TypeName, DBG_DUMP_NO_PRINT, 0, NULL, NULL, NULL, NULL }; return Ioctl(IG_GET_TYPE_SIZE, &Sym, Sym.size); } ULONG64 GetVar(PCSTR VarName) { ULONG64 Var = 0; ULONG64 VarAddr = GetExpression(VarName); if (!VarAddr) { dprintf("Failure to get address of %s\n", VarName); return NULL; } ReadPtr(VarAddr, &Var); return Var; } void do_dcebinding (ULONG64 qwAddr); void do_dgep (ULONG64 qwAddr); void do_dgsc (ULONG64 qwAddr); void do_dgsn (ULONG64 qwAddr); void do_osfbh (ULONG64 qwAddr); void do_osfca (ULONG64 qwAddr); void do_osfcconn (ULONG64 qwAddr); void do_osfccall (ULONG64 qwAddr); void do_osfaddr (ULONG64 qwAddr); void do_osfsconn (ULONG64 qwAddr); void do_osfscall (ULONG64 qwAddr); void do_osfsa (ULONG64 qwAddr); void do_rpcsvr (ULONG64 qwAddr); void do_lpcaddr (ULONG64 qwAddr); void do_lpcsa (ULONG64 qwAddr); void do_lpcscall (ULONG64 qwAddr); void do_lpcccall (ULONG64 qwAddr); void do_lpcbh (ULONG64 qwAddr); void do_lpcca (ULONG64 qwAddr); void do_rpcmem (ULONG64 qwAddr, long lDisplay, long lVerbose); void do_rpcmsg (ULONG64 qwAddr); void do_pasync (ULONG64 qwAddr); void do_authinfo (ULONG64 qwAddr); void do_error (ULONG64 qwAddr); void do_dict (ULONG64 qwAddr); void do_dict2 (ULONG64 qwAddr); void do_queue (ULONG64 qwAddr); void do_stubmsg (ULONG64 qwAddr); void do_thread (ULONG64 qwAddr); void do_copacket (ULONG64 qwAddr); void do_obj (ULONG64 qwAddr); void do_transinfo (ULONG64 qwAddr); void do_lpcpacket (ULONG64 qwAddr); void do_IF (ULONG64 qwAddr); void do_assoctable (ULONG64 qwAddr); void do_eerecord (ULONG64 qwAddr); void do_eeinfo (ULONG64 qwAddr); void do_dgaddr (ULONG64 qwAddr); void do_dgca (ULONG64 qwAddr); void do_dgbh (ULONG64 qwAddr); void do_dgag (ULONG64 qwAddr); void do_dgcn (ULONG64 qwAddr); void do_typeinfo (ULONG64 qwAddr); void do_pipestate (ULONG64 qwAddr); void do_pipedesc (ULONG64 qwAddr); void do_pipearg (ULONG64 qwAddr); void do_pipemsg (ULONG64 qwAddr); void do_dgpe (ULONG64 qwAddr); void do_dgcc (ULONG64 qwAddr); void do_packet (ULONG64 qwAddr); void do_packet_header (ULONG64 qwAddr); void do_trans (ULONG64 qwAddr); void do_dgpkt (ULONG64 qwAddr); void do_dgpkthdr (ULONG64 qwAddr); void do_asyncdcom (ULONG64 qwAddr); void do_asyncmsg (ULONG64 qwAddr); void do_asyncrpc (ULONG64 qwAddr); void do_listcalls (ULONG64 qwAddr); MY_DECLARE_API( assoctable ) MY_DECLARE_API( dgep ) MY_DECLARE_API( dgca ) MY_DECLARE_API( dgcn ) MY_DECLARE_API( dgsn ) MY_DECLARE_API( dgsc ) MY_DECLARE_API( osfbh ) MY_DECLARE_API( osfca ) MY_DECLARE_API( osfaddr ) MY_DECLARE_API( osfscall ) MY_DECLARE_API( osfsconn ) MY_DECLARE_API( dcebinding ) MY_DECLARE_API( osfccall ) MY_DECLARE_API( osfcconn ) MY_DECLARE_API( osfsa ) MY_DECLARE_API( rpcmsg ) MY_DECLARE_API( lpcaddr ) MY_DECLARE_API( lpcsa ); MY_DECLARE_API( lpcscall ); MY_DECLARE_API( lpcccall ); MY_DECLARE_API( lpcbh ); MY_DECLARE_API( lpcca ); MY_DECLARE_API( pasync); MY_DECLARE_API( authinfo ); MY_DECLARE_API( error ); MY_DECLARE_API( dict ); MY_DECLARE_API( dict2 ); MY_DECLARE_API( queue ); MY_DECLARE_API( stubmsg ); MY_DECLARE_API( thread ); MY_DECLARE_API( copacket ); MY_DECLARE_API( obj ); MY_DECLARE_API( transinfo ); MY_DECLARE_API( lpcpacket ); MY_DECLARE_API( IF ); MY_DECLARE_API( eerecord ); MY_DECLARE_API( eeinfo ); MY_DECLARE_API( dgcc ); MY_DECLARE_API( dgpe ); MY_DECLARE_API( pipestate ); MY_DECLARE_API( pipedesc ); MY_DECLARE_API( pipearg ); MY_DECLARE_API( pipemsg ); MY_DECLARE_API( dgpkt ); MY_DECLARE_API( dgpkthdr ); MY_DECLARE_API( asyncdcom ); MY_DECLARE_API( asyncmsg ); MY_DECLARE_API( asyncrpc ); // define our own operators new and delete, so that we do not have to include the crt void * __cdecl ::operator new(size_t dwBytes) { void *p; p = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytes); return (p); } void __cdecl ::operator delete (void *p) { HeapFree(GetProcessHeap(), 0, p); } BOOL GetData(IN ULONG64 qwAddress, IN LPVOID ptr, IN ULONG size) { BOOL b; ULONG BytesRead = 0; b = ReadMemory(qwAddress, ptr, size, &BytesRead ); if (!b || BytesRead != size ) { return FALSE; } return TRUE; } #define MAX_MESSAGE_BLOCK_SIZE 1024 #define BLOCK_SIZE 16 RPC_CHAR * ReadProcessRpcChar( ULONG64 qwAddr ) { char block[BLOCK_SIZE]; RPC_CHAR *RpcBlock = (RPC_CHAR *)█ char *string_block = new char[MAX_MESSAGE_BLOCK_SIZE]; RPC_CHAR *RpcString = (RPC_CHAR *)string_block; int length = 0; int i = 0; BOOL b; BOOL end = FALSE; if (qwAddr == NULL) { return (NULL); } if (string_block == NULL) { dprintf("couldn't allocate %d memory\n", MAX_MESSAGE_BLOCK_SIZE); return (NULL); } for (length = 0; length < MAX_MESSAGE_BLOCK_SIZE/2; ) { b = GetData(qwAddr, &block, BLOCK_SIZE); if (b == FALSE) { dprintf("couldn't read address %I64xx\n", qwAddr); return (NULL); } for (i = 0; i < BLOCK_SIZE/2; i++) { if (RpcBlock[i] == L'\0') { end = TRUE; } RpcString[length] = RpcBlock[i]; length++; } if (end == TRUE) { break; } qwAddr += BLOCK_SIZE; } return (RpcString); } long myatol(char *string) { int i = 0; BOOL minus = FALSE; long number = 0; long tmpnumber = 0 ; long chknum = LONG_MAX; if (string[0] == '-') { minus = TRUE; i++; } else if (string[0] == '+') { i++; } for (; string[i] != '\0'; i++) { if ((string[i] >= '0')&&(string[i] <= '9')) { tmpnumber = string[i] - '0'; if (number != 0) { chknum = LONG_MAX/number; } if (chknum > 11) { number = number*10 + tmpnumber; } } else return 0; } if (minus == TRUE) { number = 0 - number; } return number; } PCHAR MapSymbol(ULONG64 qwAddr) { static CHAR Name[256]; ULONG64 Displacement; GetSymbol(qwAddr, Name, &Displacement); if (strcmp(Name, "") != 0) { if (Displacement) strcat(Name, "+"); PCHAR p = strchr(Name, '\0'); if (Displacement) _ui64toa(Displacement, p, 16); return(Name); } else { return NULL; } } // checks if the uuid is null, prints the uuid void PrintUuidLocal(UUID *Uuid) { unsigned long PAPI * Vector; Vector = (unsigned long PAPI *) Uuid; if ( (Vector[0] == 0) && (Vector[1] == 0) && (Vector[2] == 0) && (Vector[3] == 0)) { dprintf("(Null Uuid)"); } else { dprintf("%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Uuid->Data1, Uuid->Data2, Uuid->Data3, Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2], Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5], Uuid->Data4[6], Uuid->Data4[7] ); } return; } // prints the uuid at a given address within the process void PrintUuid(ULONG64 Uuid) { UUID UuidStore; GetData(Uuid, &UuidStore, sizeof(UUID)); PrintUuidLocal(&UuidStore); } // Returns a string for the symbol that matches the value at // address dwAddr, or "". PCHAR SymbolAtAddress(ULONG64 Addr) { CHAR Symbol[128]; ULONG64 Displacement = 0; static CHAR Name[256]; ULONG64 Val; ReadPtr(Addr, &Val); GetSymbol(Val, Symbol, &Displacement); if (strcmp(Symbol, "") != 0) { sprintf(Name, "%s+%x", Symbol, Displacement); return Name; } else return ""; } // Returns a string for the symbol that matches the value at // address dwAddr, without the offset, or "". PCHAR SymbolAtAddressNoOffset(ULONG64 Addr) { CHAR Symbol[128]; ULONG64 Displacement = 0; static CHAR Name[256]; ULONG64 Val; ReadPtr(Addr, &Val); GetSymbol(Val, Symbol, &Displacement); if (strcmp(Symbol, "") != 0) { sprintf(Name, "%s", Symbol); return Name; } else return ""; } void do_securitycontext ( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; if (qwAddr == 0) { return; } do_authinfo(qwAddr); PRINT_MEMBER_WITH_LABEL(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, AuthContextId, " AuthContextId ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, Flags, " Flags ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, ContextAttributes, " ContextAttributes ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, fFullyConstructed, " fFullyConstructed ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, DontForgetToDelete, " DontForgetToDelete ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, fDatagram, " fDatagram ", tmp1); ULONG64 SecurityContext; GET_ADDRESS_OF(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, SecurityContext, SecurityContext, tmp2); ULONG64 dwUpper, dwLower; GET_MEMBER(SecurityContext, _SecHandle, RPCRT4!_SecHandle, dwUpper, dwUpper); GET_MEMBER(SecurityContext, _SecHandle, RPCRT4!_SecHandle, dwLower, dwLower); dprintf( " SecurityContext(0x%I64x, 0x%I64x) - 0x%I64x\n", dwUpper, dwLower, SecurityContext); PRINT_MEMBER_WITH_LABEL(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, MaxHeaderLength, " MaxHeaderLength ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, MaxSignatureLength, " MaxSignatureLength ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, cbBlockSize, " cbBlockSize ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, RpcSecurityInterface, " RpcSecurityInterface ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, SECURITY_CONTEXT, RPCRT4!SECURITY_CONTEXT, FailedContext, " FailedContext ", tmp1); } VOID do_sizes( ) { PRINT_RPC_TYPE_SIZE(ASSOCIATION_HANDLE); dprintf("BIND_NAK_PICKLE_BUFFER_OFFSET - 0x%x\n", BIND_NAK_PICKLE_BUFFER_OFFSET); PRINT_RPC_TYPE_SIZE(BINDING_HANDLE); PRINT_RPC_TYPE_SIZE(BITSET); PRINT_RPC_TYPE_SIZE(CALL); PRINT_RPC_TYPE_SIZE(CCALL); PRINT_RPC_TYPE_SIZE(CLIENT_AUTH_INFO); PRINT_RPC_TYPE_SIZE(CLIENT_ID); PRINT_RPC_TYPE_SIZE(DCE_BINDING); PRINT_RPC_TYPE_SIZE(DCE_SECURITY_INFO); PRINT_RPC_TYPE_SIZE(EVENT); PRINT_RPC_TYPE_SIZE(GENERIC_OBJECT); PRINT_RPC_TYPE_SIZE(INTERLOCKED_INTEGER); PRINT_RPC_TYPE_SIZE(LOADABLE_TRANSPORT); PRINT_RPC_TYPE_SIZE(LRPC_ADDRESS); PRINT_RPC_TYPE_SIZE(LRPC_BIND_EXCHANGE); PRINT_RPC_TYPE_SIZE(LRPC_BINDING_HANDLE); PRINT_RPC_TYPE_SIZE(LRPC_CASSOCIATION); PRINT_RPC_TYPE_SIZE(LRPC_CCALL); PRINT_RPC_TYPE_SIZE(LRPC_MESSAGE); PRINT_RPC_TYPE_SIZE(LRPC_FAULT_MESSAGE); PRINT_RPC_TYPE_SIZE(LRPC_FAULT2_MESSAGE); PRINT_RPC_TYPE_SIZE(LRPC_RPC_HEADER); PRINT_RPC_TYPE_SIZE(LRPC_SASSOCIATION); PRINT_RPC_TYPE_SIZE(LRPC_SCALL); PRINT_RPC_TYPE_SIZE(LRPC_SERVER); dprintf("MAX_BIND_NAK - 0x%x\n", MAX_BIND_NAK); dprintf("MAXIMUM_FAULT_MESSAGE - 0x%x\n", MAXIMUM_FAULT_MESSAGE); dprintf("MAXIMUM_MESSAGE_BUFFER - 0x%x\n", MAXIMUM_MESSAGE_BUFFER); PRINT_RPC_TYPE_SIZE(MESSAGE_OBJECT); PRINT_RPC_TYPE_SIZE(MUTEX); PRINT_RPC_TYPE_SIZE(OSF_ADDRESS); PRINT_RPC_TYPE_SIZE(OSF_ASSOCIATION); PRINT_RPC_TYPE_SIZE(OSF_BINDING); PRINT_RPC_TYPE_SIZE(OSF_BINDING_HANDLE); PRINT_RPC_TYPE_SIZE(OSF_CASSOCIATION); PRINT_RPC_TYPE_SIZE(OSF_CCALL); PRINT_RPC_TYPE_SIZE(OSF_CCONNECTION); PRINT_RPC_TYPE_SIZE(OSF_SBINDING); PRINT_RPC_TYPE_SIZE(OSF_SCALL); PRINT_RPC_TYPE_SIZE(OSF_SCONNECTION); dprintf("PORT_MAXIMUM_MESSAGE_LENGTH - 0x%x\n", PORT_MAXIMUM_MESSAGE_LENGTH); PRINT_RPC_TYPE_SIZE(PORT_MESSAGE); PRINT_RPC_TYPE_SIZE(QUEUE); PRINT_RPC_TYPE_SIZE(RPC_ADDRESS); PRINT_RPC_TYPE_SIZE(RPC_APC_INFO); PRINT_RPC_TYPE_SIZE(RPC_CLIENT_INTERFACE); PRINT_RPC_TYPE_SIZE(RPC_CLIENT_PROCESS_IDENTIFIER); PRINT_RPC_TYPE_SIZE(rpcconn_alter_context); PRINT_RPC_TYPE_SIZE(rpcconn_alter_context_resp); PRINT_RPC_TYPE_SIZE(rpcconn_bind); PRINT_RPC_TYPE_SIZE(rpcconn_bind_ack); PRINT_RPC_TYPE_SIZE(rpcconn_common); PRINT_RPC_TYPE_SIZE(rpcconn_fault); PRINT_RPC_TYPE_SIZE(rpcconn_request); PRINT_RPC_TYPE_SIZE(rpcconn_response); PRINT_RPC_TYPE_SIZE(RPC_INTERFACE); PRINT_RPC_TYPE_SIZE(RPC_INTERFACE_MANAGER); #if DBG PRINT_RPC_TYPE_SIZE(RPC_MEMORY_BLOCK); #endif PRINT_RPC_TYPE_SIZE(RPC_MESSAGE); PRINT_RPC_TYPE_SIZE(RPC_SERVER); PRINT_RPC_TYPE_SIZE(RPC_SERVER_INTERFACE); PRINT_RPC_TYPE_SIZE(RPC_SYNTAX_IDENTIFIER); PRINT_RPC_TYPE_SIZE(RPC_UUID); PRINT_RPC_TYPE_SIZE(SCALL); PRINT_RPC_TYPE_SIZE(SECURITY_CONTEXT); PRINT_RPC_TYPE_SIZE(sec_trailer); PRINT_RPC_TYPE_SIZE(SIMPLE_DICT); PRINT_RPC_TYPE_SIZE(SIMPLE_DICT2); PRINT_RPC_TYPE_SIZE(THREAD); PRINT_RPC_TYPE_SIZE(TRANS_INFO); } DECLARE_API( sizes ) { do_sizes(); } char * GetError (DWORD dwError) { DWORD dwFlag = FORMAT_MESSAGE_FROM_SYSTEM; static CHAR szErrorMessage[1024]; static HANDLE hSource = NULL; if ((dwError >= 2100) && (dwError < 6000)) { if (hSource == NULL) { hSource = LoadLibrary("netmsg.dll"); } if (hSource == NULL) { sprintf (szErrorMessage, "Unable to load netmsg.dll. Error %d occured.\n", dwError); return(szErrorMessage); } dwFlag = FORMAT_MESSAGE_FROM_HMODULE; } if (!FormatMessage (dwFlag, hSource, dwError, 0, szErrorMessage, 1024, NULL)) { sprintf (szErrorMessage, "An unknown error occured: 0x%x \n", dwError); } return(szErrorMessage); } VOID do_error ( ULONG64 Error ) { dprintf("%x: %s\n", (unsigned long)Error, GetError((unsigned long) Error)); } VOID do_IF ( ULONG64 rpcif ) { ULONG64 tmp0; ULONG64 tmp1; ULONG tmp2; dprintf("RPC_INTERFACE at 0x%I64x\n\n", rpcif); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, Server, tmp0); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, NullManagerEpv, tmp0); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, NullManagerFlag, tmp0); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, ManagerCount, tmp0); GET_ADDRESS_OF(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, NullManagerActiveCallCount, tmp0, tmp2); PRINT_MEMBER_WITH_LABEL(tmp0, INTERLOCKED_INTEGER, RPCRT4!INTERLOCKED_INTEGER, Integer, "NullManagerActiveCallCount", tmp1); GET_ADDRESS_OF(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, AutoListenCallCount, tmp0, tmp2); PRINT_MEMBER_WITH_LABEL(tmp0, INTERLOCKED_INTEGER, RPCRT4!INTERLOCKED_INTEGER, Integer, "AutoListenCallCount", tmp1); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, Flags, tmp0); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, MaxCalls, tmp0); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, CallbackFn, tmp0); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, PipeInterfaceFlag, tmp0); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, fReplace, tmp0); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, fBindingsExported, tmp0); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, UuidVector, tmp0); PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, SequenceNumber, tmp0); #if DBG PRINT_MEMBER(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, Strict, tmp0); #endif PRINT_ADDRESS_OF(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, RpcInterfaceInformation, tmp2); PRINT_ADDRESS_OF(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, InterfaceManagerDictionary, tmp2); PRINT_ADDRESS_OF(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, Annotation, tmp2); PRINT_ADDRESS_OF(rpcif, RPC_INTERFACE, RPCRT4!RPC_INTERFACE, NsEntries, tmp2); } VOID do_obj ( ULONG64 qwAddr ) { BOOL b; ULONG64 MagicValue; ULONG64 ObjectType; ReadPtr(qwAddr+AddressSize, &MagicValue); ReadPtr(qwAddr+AddressSize+4, &ObjectType); if ((ULONG)MagicValue != MAGICLONG) { dprintf("Bad or deleted object at %p\n", qwAddr); } switch (((ULONG)ObjectType) & (~OBJECT_DELETED)) { case DG_CALLBACK_TYPE: dprintf("this is a DG_CLIENT_CALLBACK object\n"); break; case DG_CCALL_TYPE: { dprintf("Dumping DG_CCALL...\n"); do_dgcc(qwAddr); break; } case DG_SCALL_TYPE: { dprintf("Dumping DG_SCALL...\n"); do_dgsc(qwAddr); break; } case DG_BINDING_HANDLE_TYPE: { dprintf("dumping DG_BINDING_HANDLE...\n"); do_dgbh(qwAddr); break; } case DG_CCONNECTION_TYPE: { dprintf("Dumping DG_CCONNECTION...\n"); do_dgcn(qwAddr); break; } case DG_SCONNECTION_TYPE: { dprintf("Dumping DG_SCONNECTION...\n"); do_dgsn(qwAddr); break; } case DG_ADDRESS_TYPE: { dprintf("dumping DG_ADDRESS\n"); do_dgaddr(qwAddr); break; } case DG_CASSOCIATION_TYPE: { dprintf("a DG_CASSOCIATION\n"); do_dgca(qwAddr); break; } case DG_SASSOCIATION_TYPE: { dprintf("a datagram ASSOCIATION_GROUP\n"); do_dgag(qwAddr); break; } case OSF_BINDING_HANDLE_TYPE: dprintf("Dumping OSF_BINDING_HANDLE...\n"); do_osfbh(qwAddr); break; case OSF_CCALL_TYPE: dprintf("Dumping OSF_CCALL...\n"); do_osfccall(qwAddr); break; case OSF_SCALL_TYPE: dprintf("Dumping OSF_SCALL...\n"); do_osfscall(qwAddr); break; case OSF_CCONNECTION_TYPE: dprintf("Dumping OSF_CCONNECTION...\n"); do_osfcconn(qwAddr); break; case OSF_SCONNECTION_TYPE: dprintf("Dumping OSF_SCONNECTION...\n"); do_osfsconn(qwAddr); break; case OSF_CASSOCIATION_TYPE: dprintf("Dumping OSF_CASSOCIATION...\n"); do_osfca(qwAddr); break; case OSF_ASSOCIATION_TYPE: dprintf("Dumping OSF_ASSOCIATION...\n"); do_osfsa(qwAddr); break; case OSF_ADDRESS_TYPE: dprintf("Dumping OSF_ADDRESS...\n"); do_osfaddr(qwAddr); break; case LRPC_CCALL_TYPE: dprintf("Dumping LRPC_CCALL ...\n"); do_lpcccall(qwAddr); break; case LRPC_SCALL_TYPE: dprintf("Dumping LRPC_SCALL ...\n"); do_lpcscall(qwAddr); break; case LRPC_CASSOCIATION_TYPE: dprintf("Dumping LRPC_CASSOCIATION...\n"); do_lpcca(qwAddr); break; case LRPC_SASSOCIATION_TYPE: dprintf("Dumping LRPC_SASSOCIATION...\n"); do_lpcsa(qwAddr); break; case LRPC_BINDING_HANDLE_TYPE: dprintf("Dumping LRPC_BINDING_HANDLE...\n"); do_lpcbh(qwAddr); break; case LRPC_ADDRESS_TYPE: dprintf("Dumping LRPC_ADDRESS...\n"); do_lpcaddr(qwAddr); break; default: dprintf("The RPC object type is 0x%lx and I don't recognize it.\n", (ObjectType) & ~(OBJECT_DELETED)); } } void do_secinfo ( ) { ULONG64 SecurityPackages; ULONG64 List; ULONG64 ProviderList; int NumberOfPackages; int LoadedProviders; int AvailableProviders; int i, Index; BOOL b; ULONG64 qwAddr; ULONG tmp; LoadedProviders = (int) GetVar("RPCRT4!LoadedProviders"); dprintf("LoadedProviders = %d\n", LoadedProviders); AvailableProviders = (int) GetVar("RPCRT4!AvailableProviders"); dprintf("AvailableProviders = %d\n", AvailableProviders); ProviderList = GetVar("RPCRT4!ProviderList"); dprintf("ProviderList = 0x%I64x\n", ProviderList); List = ProviderList; for (i = 0; i < LoadedProviders; i ++) { ULONG64 Count; ULONG64 SecurityPackages; GET_MEMBER(List, SECURITY_PROVIDER_INFO, RPCRT4!SECURITY_PROVIDER_INFO, Count, Count); NumberOfPackages = (int)Count; GET_MEMBER(List, SECURITY_PROVIDER_INFO, RPCRT4!SECURITY_PROVIDER_INFO, SecurityPackages, SecurityPackages); dprintf("Provider: %d\n", i); for (Index = 0;Index < NumberOfPackages;Index++) { ULONG64 SecurityPackageInfo = SecurityPackages + Index * AddressSize; ULONG64 wRPCID; ULONG64 PackageInfoAddr; GET_ADDRESS_OF(SecurityPackageInfo, SECURITY_PACKAGE_INFO, RPCRT4!SECURITY_PACKAGE_INFO, PackageInfo, PackageInfoAddr, tmp); GET_MEMBER(PackageInfoAddr, _SecPkgInfoA, RPCRT4!_SecPkgInfoA, wRPCID, wRPCID); dprintf("PackageId :%d\n", (ULONG) wRPCID); } dprintf("\n"); List+=GET_TYPE_SIZE(SECURITY_PROVIDER_INFO, RPCRT4!SECURITY_PROVIDER_INFO); } //For over all packages in one provider(dll) } DECLARE_API( secinfo ) { do_secinfo(); } VOID do_authinfo( ULONG64 authInfo ) { RPC_CHAR *ServerPrincipalName; ULONG64 tmp1; ULONG tmp2; if (authInfo == 0) { return; } ULONG64 ServerPrincipalNameAddr; GET_MEMBER(authInfo, CLIENT_AUTH_INFO, RPCRT4!CLIENT_AUTH_INFO, ServerPrincipalName, ServerPrincipalNameAddr); ServerPrincipalName = ReadProcessRpcChar(ServerPrincipalNameAddr); dprintf(" ServerPrincipalName - %ws (Address: 0x%I64x)\n", ServerPrincipalName, ServerPrincipalNameAddr); ULONG64 AuthenticationLevel; GET_MEMBER(authInfo, CLIENT_AUTH_INFO, RPCRT4!CLIENT_AUTH_INFO, AuthenticationLevel, AuthenticationLevel); switch ((ULONG)AuthenticationLevel) { case RPC_C_AUTHN_LEVEL_DEFAULT: dprintf(" AuthenticationLevel - default\n"); break; case RPC_C_AUTHN_LEVEL_NONE: dprintf(" AuthenticationLevel - none\n"); break; case RPC_C_AUTHN_LEVEL_CONNECT: dprintf(" AuthenticationLevel - connect\n"); break; case RPC_C_AUTHN_LEVEL_CALL: dprintf(" AuthenticationLevel - call\n"); break; case RPC_C_AUTHN_LEVEL_PKT: dprintf(" AuthenticationLevel - pkt\n"); break; case RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: dprintf(" AuthenticationLevel - pkt integrity\n"); break; case RPC_C_AUTHN_LEVEL_PKT_PRIVACY: dprintf(" AuthenticationLevel - pkt privacy\n"); break; default: dprintf(" AuthenticationLevel - %ul\n", (ULONG)AuthenticationLevel); break; } ULONG64 AuthenticationService; GET_MEMBER(authInfo, CLIENT_AUTH_INFO, RPCRT4!CLIENT_AUTH_INFO, AuthenticationService, AuthenticationService); switch ((ULONG)AuthenticationService) { case RPC_C_AUTHN_NONE: dprintf(" AuthenticationService - none\n"); break; case RPC_C_AUTHN_DCE_PRIVATE: dprintf(" AuthenticationService - DCE private\n"); break; case RPC_C_AUTHN_DCE_PUBLIC: dprintf(" AuthenticationService - DCE public\n"); break; case RPC_C_AUTHN_DEC_PUBLIC: dprintf(" AuthenticationService - DEC public\n"); break; case RPC_C_AUTHN_WINNT: dprintf(" AuthenticationService - WINNT\n"); break; case RPC_C_AUTHN_DEFAULT: dprintf(" AuthenticationService - default\n"); break; default: dprintf(" AuthenticationService - %ul\n", (ULONG)AuthenticationService); break; } ULONG64 AuthIdentity; GET_MEMBER(authInfo, CLIENT_AUTH_INFO, RPCRT4!CLIENT_AUTH_INFO, AuthIdentity, AuthIdentity); dprintf(" AuthIdentity - %08x\n", (ULONG)AuthIdentity); ULONG64 AuthorizationService; GET_MEMBER(authInfo, CLIENT_AUTH_INFO, RPCRT4!CLIENT_AUTH_INFO, AuthorizationService, AuthorizationService); switch ((ULONG)AuthorizationService) { case RPC_C_AUTHZ_NONE: dprintf(" AuthorizationService - none\n"); break; case RPC_C_AUTHZ_NAME: dprintf(" AuthorizationService - name\n"); break; case RPC_C_AUTHZ_DCE: dprintf(" AuthorizationService - DCE\n"); break; default: dprintf(" AuthorizationService - %ul\n", (ULONG)AuthorizationService); break; } ULONG64 IdentityTracking; GET_MEMBER(authInfo, CLIENT_AUTH_INFO, RPCRT4!CLIENT_AUTH_INFO, IdentityTracking, IdentityTracking); switch ((ULONG)IdentityTracking) { case RPC_C_QOS_IDENTITY_STATIC: dprintf(" IdentityTracking - Static\n"); break; case RPC_C_QOS_IDENTITY_DYNAMIC: dprintf(" IdentityTracking - Dynamic\n"); break; default: dprintf(" IdentityTracking - %08x\n", (ULONG)IdentityTracking); break; } ULONG64 ImpersonationType; GET_MEMBER(authInfo, CLIENT_AUTH_INFO, RPCRT4!CLIENT_AUTH_INFO, ImpersonationType, ImpersonationType); switch ((ULONG)ImpersonationType) { case RPC_C_IMP_LEVEL_ANONYMOUS: dprintf(" ImpersonationType - Anonymous\n"); break; case RPC_C_IMP_LEVEL_IDENTIFY: dprintf(" ImpersonationType - Identify\n"); break; case RPC_C_IMP_LEVEL_IMPERSONATE: dprintf(" ImpersonationType - Impersonate\n"); break; case RPC_C_IMP_LEVEL_DELEGATE: dprintf(" ImpersonationType - Delegate\n"); break; default: dprintf(" ImpersonationType - %08x\n", (ULONG)ImpersonationType); break; } ULONG64 Capabilities; GET_MEMBER(authInfo, CLIENT_AUTH_INFO, RPCRT4!CLIENT_AUTH_INFO, Capabilities, Capabilities); switch ((ULONG)Capabilities) { case RPC_C_QOS_CAPABILITIES_DEFAULT: dprintf(" Capabilities - Default\n"); break; case RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH: dprintf(" Capabilities - Mutual Auth\n"); break; default: dprintf(" Capabilities - %08x\n", (ULONG)Capabilities); break; } ULONG64 ModifiedId, LowPart, HighPart; GET_ADDRESS_OF(authInfo, CLIENT_AUTH_INFO, RPCRT4!CLIENT_AUTH_INFO, ModifiedId, ModifiedId, tmp2); GET_MEMBER(ModifiedId, _LUID, RPCRT4!_LUID, LowPart, LowPart); GET_MEMBER(ModifiedId, _LUID, RPCRT4!_LUID, HighPart, HighPart); dprintf(" ModifiedId - %08x, %08x\n", (ULONG)LowPart, (ULONG)HighPart); PRINT_MEMBER_WITH_LABEL(authInfo, CLIENT_AUTH_INFO, RPCRT4!CLIENT_AUTH_INFO, DefaultLogonId, " DefaultLogonId ", tmp1); PRINT_MEMBER_WITH_LABEL(authInfo, CLIENT_AUTH_INFO, RPCRT4!CLIENT_AUTH_INFO, Credentials, " Credentials ", tmp1); if (ServerPrincipalName) { delete[] ServerPrincipalName; } } void do_dict ( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; ULONG64 cDictSize; ULONG64 cDictSlots; GET_MEMBER(qwAddr, SIMPLE_DICT, RPCRT4!SIMPLE_DICT, cDictSize, cDictSize); GET_MEMBER(qwAddr, SIMPLE_DICT, RPCRT4!SIMPLE_DICT, cDictSlots, cDictSlots); if ((ULONG)cDictSize > (ULONG)cDictSlots) { dprintf("Bad dictionary\t\t- %I64p\n", qwAddr); return; } ULONG64 DictSlots; GET_MEMBER(qwAddr, SIMPLE_DICT, RPCRT4!SIMPLE_DICT, DictSlots, DictSlots); dprintf("\n"); dprintf("Printing %d items in dictionary: %I64p with %d slots\n\n", (ULONG)cDictSize, qwAddr, (ULONG)cDictSlots); int i; for (i = 0; i < MIN((int)cDictSize, MAX_ITEMS_IN_DICTIONARY); i++) { ULONG64 DictSlot; ReadPtr(DictSlots + i * AddressSize, &DictSlot); dprintf ("(%d): 0x%I64x\n", i, DictSlot); dprintf("\n"); } } void do_dict2 ( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; ULONG64 DictKeys; ULONG64 DictItems; GET_MEMBER(qwAddr, SIMPLE_DICT2, RPCRT4!SIMPLE_DICT2, DictKeys, DictKeys); GET_MEMBER(qwAddr, SIMPLE_DICT2, RPCRT4!SIMPLE_DICT2, DictItems, DictItems); ULONG64 cDictSlots; GET_MEMBER(qwAddr, SIMPLE_DICT2, RPCRT4!SIMPLE_DICT2, cDictSlots, cDictSlots); dprintf("\n"); dprintf("Printing dictionary at %I64p with %d slots\n\n", qwAddr, (ULONG) cDictSlots); int i; for (i = 0; i < MIN((int)cDictSlots, MAX_ITEMS_IN_DICTIONARY); i++) { ULONG64 DictKey; ReadPtr(DictKeys + i * AddressSize, &DictKey); if (DictKey != 0) { ULONG64 DictItem; ReadPtr(DictItems + i * AddressSize, &DictItem); dprintf ("(Key: 0x%I64p): 0x%I64p\n", DictKey, DictItem); dprintf("\n"); } } } void do_queue ( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; int i; ULONG64 EndOfQueue; ULONG64 QueueSlots; GET_MEMBER(qwAddr, QUEUE, RPCRT4!QUEUE, EndOfQueue, EndOfQueue); GET_MEMBER(qwAddr, QUEUE, RPCRT4!QUEUE, QueueSlots, QueueSlots); dprintf("\n"); dprintf("Printing %d items in queue at %I64p\n", (ULONG)EndOfQueue, qwAddr); dprintf("TAIL:\n"); for (i = 0; i < (int)EndOfQueue; i++) { ULONG64 QueueSlot; ReadPtr(QueueSlots + i * AddressSize, &QueueSlot); ULONG64 Buffer; GET_MEMBER(QueueSlot, QUEUE_ITEM, RPCRT4!QUEUE_ITEM, Buffer, Buffer); dprintf ("(%d): %I64p\n", i, Buffer); dprintf("\n"); } dprintf("HEAD:\n"); } void do_thread ( ULONG64 Addr ) { ULONG64 RpcThread; ULONG64 tmp; ULONG offset; GET_MEMBER(Addr, TEB, TEB, ReservedForNtRpc, RpcThread); dprintf("RPC TLS at 0x%I64x\n\n", RpcThread); PRINT_MEMBER(RpcThread, THREAD, RPCRT4!THREAD, HandleToThread, tmp); PRINT_MEMBER(RpcThread, THREAD, RPCRT4!THREAD, SavedProcedure, tmp); PRINT_MEMBER(RpcThread, THREAD, RPCRT4!THREAD, SavedParameter, tmp); PRINT_MEMBER(RpcThread, THREAD, RPCRT4!THREAD, ActiveCall, tmp); PRINT_MEMBER(RpcThread, THREAD, RPCRT4!THREAD, Context, tmp); PRINT_MEMBER(RpcThread, THREAD, RPCRT4!THREAD, CancelTimeout, tmp); PRINT_MEMBER(RpcThread, THREAD, RPCRT4!THREAD, SecurityContext, tmp); PRINT_MEMBER(RpcThread, THREAD, RPCRT4!THREAD, ExtendedStatus, tmp); PRINT_MEMBER(RpcThread, THREAD, RPCRT4!THREAD, ThreadEEInfo, tmp); GET_OFFSET_OF(THREAD, RPCRT4!THREAD, ThreadEvent, &offset); dprintf("ThreadEvent at - 0x%I64x\n", RpcThread + offset); PRINT_MEMBER(RpcThread, THREAD, RPCRT4!THREAD, Flags, tmp); GET_OFFSET_OF(THREAD, RPCRT4!THREAD, BufferCache, &offset); dprintf("buffer cache array at - 0x%I64x\n", RpcThread + offset); PRINT_MEMBER(RpcThread, THREAD, RPCRT4!THREAD, fAsync, tmp); dprintf("\n"); } char *osf_ptype[] = { "rpc_request", "bad packet", "rpc_response", "rpc_fault", "bad packet", "bad packet", "bad packet", "bad packet", "bad packet", "bad packet", "bad packet", "rpc_bind", "rpc_bind_ack", "rpc_bind_nak", "rpc_alter_context", "rpc_alter_context_resp", "rpc_auth_3", "rpc_shutdown", "rpc_cancel", "rpc_orphaned" }; void do_copacket ( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; ULONG64 StubData; // // Dump the common header first // dprintf("\n"); PRINT_MEMBER(qwAddr, rpcconn_common, RPCRT4!rpcconn_common, rpc_vers, tmp1); PRINT_MEMBER(qwAddr, rpcconn_common, RPCRT4!rpcconn_common, rpc_vers_minor, tmp1); ULONG64 PTYPE; GET_MEMBER(qwAddr, rpcconn_common, RPCRT4!rpcconn_common, PTYPE, PTYPE); dprintf ("PTYPE - 0x%x, %s\n", (ULONG)PTYPE, osf_ptype[(ULONG)PTYPE]); PRINT_MEMBER(qwAddr, rpcconn_common, RPCRT4!rpcconn_common, pfc_flags, tmp1); PRINT_MEMBER(qwAddr, rpcconn_common, RPCRT4!rpcconn_common, drep, tmp1); PRINT_MEMBER(qwAddr, rpcconn_common, RPCRT4!rpcconn_common, frag_length, tmp1); PRINT_MEMBER(qwAddr, rpcconn_common, RPCRT4!rpcconn_common, auth_length, tmp1); PRINT_MEMBER(qwAddr, rpcconn_common, RPCRT4!rpcconn_common, call_id, tmp1); // // Dump the packet specific stuff // switch ((ULONG)PTYPE) { case rpc_request: PRINT_MEMBER(qwAddr, rpcconn_request, RPCRT4!rpcconn_request, alloc_hint, tmp1); PRINT_MEMBER(qwAddr, rpcconn_request, RPCRT4!rpcconn_request, p_cont_id, tmp1); PRINT_MEMBER(qwAddr, rpcconn_request, RPCRT4!rpcconn_request, opnum, tmp1); ULONG64 pfc_flags; GET_MEMBER(qwAddr, rpcconn_common, RPCRT4!rpcconn_common, pfc_flags, pfc_flags); if ((ULONG)pfc_flags & PFC_OBJECT_UUID) { dprintf("UUID -\n"); ULONG64 UUID = qwAddr; UUID += GET_TYPE_SIZE(rpcconn_common, RPCRT4!rpcconn_common); PrintUuid(UUID); dprintf("\n"); StubData = qwAddr; StubData += GET_TYPE_SIZE(rpcconn_request, RPCRT4!rpcconn_request); StubData += GET_TYPE_SIZE(UUID, RPCRT4!UUID); dprintf ("Stub Data - 0x%I64x\n", StubData); } else { StubData = qwAddr; StubData += GET_TYPE_SIZE(rpcconn_request, RPCRT4!rpcconn_request); dprintf ("Stub Data - 0x%I64x\n", StubData); } break; case rpc_response: PRINT_MEMBER(qwAddr, rpcconn_response, RPCRT4!rpcconn_response, alloc_hint, tmp1); PRINT_MEMBER(qwAddr, rpcconn_response, RPCRT4!rpcconn_response, p_cont_id, tmp1); PRINT_MEMBER(qwAddr, rpcconn_response, RPCRT4!rpcconn_response, alert_count, tmp1); PRINT_MEMBER(qwAddr, rpcconn_response, RPCRT4!rpcconn_response, reserved, tmp1); StubData = qwAddr; StubData += GET_TYPE_SIZE(rpcconn_response, RPCRT4!rpcconn_response); dprintf ("Stub Data - 0x%I64x\n", StubData); break; case rpc_fault: PRINT_MEMBER(qwAddr, rpcconn_fault, RPCRT4!rpcconn_fault, alloc_hint, tmp1); PRINT_MEMBER(qwAddr, rpcconn_fault, RPCRT4!rpcconn_fault, p_cont_id, tmp1); PRINT_MEMBER(qwAddr, rpcconn_fault, RPCRT4!rpcconn_fault, alert_count, tmp1); PRINT_MEMBER(qwAddr, rpcconn_fault, RPCRT4!rpcconn_fault, reserved, tmp1); PRINT_MEMBER(qwAddr, rpcconn_fault, RPCRT4!rpcconn_fault, status, tmp1); PRINT_MEMBER(qwAddr, rpcconn_fault, RPCRT4!rpcconn_fault, reserved2, tmp1); break; case rpc_bind: case rpc_alter_context: PRINT_MEMBER(qwAddr, rpcconn_bind, RPCRT4!rpcconn_bind, max_xmit_frag, tmp1); PRINT_MEMBER(qwAddr, rpcconn_bind, RPCRT4!rpcconn_bind, max_recv_frag, tmp1); PRINT_MEMBER(qwAddr, rpcconn_bind, RPCRT4!rpcconn_bind, assoc_group_id, tmp1); break; case rpc_bind_ack: PRINT_MEMBER(qwAddr, rpcconn_bind_ack, RPCRT4!rpcconn_bind_ack, max_xmit_frag, tmp1); PRINT_MEMBER(qwAddr, rpcconn_bind_ack, RPCRT4!rpcconn_bind_ack, max_recv_frag, tmp1); PRINT_MEMBER(qwAddr, rpcconn_bind_ack, RPCRT4!rpcconn_bind_ack, assoc_group_id, tmp1); PRINT_MEMBER(qwAddr, rpcconn_bind_ack, RPCRT4!rpcconn_bind_ack, sec_addr_length, tmp1); break; case rpc_bind_nak: PRINT_MEMBER(qwAddr, rpcconn_bind_nak, RPCRT4!rpcconn_bind_nak, provider_reject_reason, tmp1); PRINT_MEMBER(qwAddr, rpcconn_bind_nak, RPCRT4!rpcconn_bind_nak, versions, tmp1); break; case rpc_alter_context_resp: PRINT_MEMBER(qwAddr, rpcconn_alter_context_resp, RPCRT4!rpcconn_alter_context_resp, max_xmit_frag, tmp1); PRINT_MEMBER(qwAddr, rpcconn_alter_context_resp, RPCRT4!rpcconn_alter_context_resp, max_recv_frag, tmp1); PRINT_MEMBER(qwAddr, rpcconn_alter_context_resp, RPCRT4!rpcconn_alter_context_resp, assoc_group_id, tmp1); PRINT_MEMBER(qwAddr, rpcconn_alter_context_resp, RPCRT4!rpcconn_alter_context_resp, sec_addr_length, tmp1); PRINT_MEMBER(qwAddr, rpcconn_alter_context_resp, RPCRT4!rpcconn_alter_context_resp, pad, tmp1); break; case rpc_auth_3: case rpc_shutdown: case rpc_cancel: case rpc_orphaned: break; default: dprintf ("Bad Packet\n"); break; } // // Dump the security trailer // ULONG64 auth_length; ULONG64 frag_length; GET_MEMBER(qwAddr, rpcconn_common, RPCRT4!rpcconn_common, auth_length, auth_length); GET_MEMBER(qwAddr, rpcconn_common, RPCRT4!rpcconn_common, frag_length, frag_length); if ((ULONG)auth_length) { ULONG64 SecurityTrailer = qwAddr; SecurityTrailer += frag_length-auth_length-GET_TYPE_SIZE(sec_trailer, RPCRT4!sec_trailer); dprintf("\nSecurity trailer: 0x%I64x\n", SecurityTrailer); PRINT_MEMBER(SecurityTrailer, sec_trailer, RPCRT4!sec_trailer, auth_type, tmp1); PRINT_MEMBER(SecurityTrailer, sec_trailer, RPCRT4!sec_trailer, auth_level, tmp1); PRINT_MEMBER(SecurityTrailer, sec_trailer, RPCRT4!sec_trailer, auth_pad_length, tmp1); PRINT_MEMBER(SecurityTrailer, sec_trailer, RPCRT4!sec_trailer, auth_reserved, tmp1); PRINT_MEMBER(SecurityTrailer, sec_trailer, RPCRT4!sec_trailer, auth_context_id, tmp1); dprintf ("trailer - 0x%I64x\n", SecurityTrailer+1); } } char *lpc_ptype[] = { "LRPC_MSG_BIND", "LRPC_MSG_REQUEST", "LRPC_MSG_RESPONSE", "LRPC_MSG_CALLBACK", "LRPC_MSG_FAULT", "LRPC_MSG_CLOSE", "LRPC_MSG_ACK", "LRPC_BIND_ACK", "LRPC_MSG_COPY", "LRPC_MSG_PUSH", "LRPC_MSG_CANCEL", "LRPC_MSG_BIND_BACK", "LRPC_ASYNC_REQUEST", "LRPC_PARTIAL_REQUEST", "LRPC_CLIENT_SEND_MORE", "LRPC_SERVER_SEND_MORE", "LRPC_MSG_FAULT2" }; VOID do_lpcpacket( ULONG64 qwAddr ) { if (fUseTypeInfo) { ULONG64 LpcHeader; ULONG64 RpcHeader; ULONG64 Buffer; ULONG64 tmp1; ULONG tmp2; GET_ADDRESS_OF(qwAddr, LRPC_RPC_MESSAGE, RPCRT4!LRPC_RPC_MESSAGE, LpcHeader, LpcHeader, tmp2); GET_ADDRESS_OF(qwAddr, LRPC_RPC_MESSAGE, RPCRT4!LRPC_RPC_MESSAGE, RpcHeader, RpcHeader, tmp2); dprintf("\n"); // // dump the LPC header // PRINT_ADDRESS_OF_WITH_LABEL(LpcHeader, _PORT_MESSAGE, RPCRT4!_PORT_MESSAGE, u1, "&u1\t\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(LpcHeader, _PORT_MESSAGE, RPCRT4!_PORT_MESSAGE, u2, "&u2\t\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(LpcHeader, _PORT_MESSAGE, RPCRT4!_PORT_MESSAGE, ClientId, "&CLIENT_ID\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(LpcHeader, _PORT_MESSAGE, RPCRT4!_PORT_MESSAGE, MessageId, "MessageId\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(LpcHeader, _PORT_MESSAGE, RPCRT4!_PORT_MESSAGE, CallbackId, "CallbackId\t\t", tmp1); // // dump the LRPC header // ULONG64 MessageType; GET_MEMBER(RpcHeader, _LRPC_RPC_HEADER, RPCRT4!_LRPC_RPC_HEADER, MessageType, MessageType); dprintf("MessageType\t\t - %s\n", lpc_ptype[(long)MessageType]); PRINT_MEMBER_WITH_LABEL(RpcHeader, _LRPC_RPC_HEADER, RPCRT4!_LRPC_RPC_HEADER, PresentContext, "PresentationContext\t", tmp1); PRINT_MEMBER_WITH_LABEL(RpcHeader, _LRPC_RPC_HEADER, RPCRT4!_LRPC_RPC_HEADER, Flags, "Flags\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(RpcHeader, _LRPC_RPC_HEADER, RPCRT4!_LRPC_RPC_HEADER, ProcedureNumber, "ProcedureNumber\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(RpcHeader, _LRPC_RPC_HEADER, RPCRT4!_LRPC_RPC_HEADER, CallId, "CallId\t\t\t", tmp1); ULONG64 ObjectUuid; GET_ADDRESS_OF(RpcHeader, _LRPC_RPC_HEADER, RPCRT4!_LRPC_RPC_HEADER, ObjectUuid, ObjectUuid, tmp2); dprintf("ObjectUuid\t\t - "); PrintUuid(ObjectUuid); dprintf("\n\n"); } else { BOOL b; char block[sizeof(LRPC_RPC_MESSAGE)]; LRPC_RPC_MESSAGE *m = (LRPC_RPC_MESSAGE *)█ b = GetData(qwAddr, &block, sizeof(LRPC_RPC_MESSAGE)); if ( !b ) { dprintf("couldn't read address %p\n", qwAddr); return; } dprintf("\n"); // // dump the LPC header // dprintf("DataLength\t\t- 0x%x\n", (long) m->LpcHeader.u1.s1.DataLength); dprintf("TotalLength\t\t- 0x%x\n", (long) m->LpcHeader.u1.s1.TotalLength); dprintf("Type\t\t\t- 0x%x\n", (long) m->LpcHeader.u2.s2.Type); dprintf("DataInfoOffset\t\t- 0x%x\n", (long) m->LpcHeader.u2.s2.DataInfoOffset); dprintf("CLIENT_ID: \t\t- Process(0x%x), Thread(0x%x)\n", m->LpcHeader.ClientId.UniqueProcess, m->LpcHeader.ClientId.UniqueThread); dprintf("MessageId\t\t- 0x%x\n", m->LpcHeader.MessageId); dprintf("CallbackId\t\t- 0x%x\n", m->LpcHeader.CallbackId); // // dump the LRPC header // dprintf("MessageType\t\t- %s\n", lpc_ptype[(long) m->RpcHeader.MessageType]); dprintf("PresentationContext\t- 0x%x\n", (long) m->RpcHeader.PresentContext); dprintf("Flags\t\t\t- 0x%x\n", (unsigned long) m->RpcHeader.Flags); dprintf("ProcedureNumber\t\t- 0x%x\n", (long) m->RpcHeader.ProcedureNumber); dprintf("CallId\t\t\t- 0x%x\n", (long) m->RpcHeader.CallId); dprintf("ObjectUuid\t\t- "); PrintUuidLocal((UUID *) &(m->RpcHeader.ObjectUuid)); dprintf("\nStubData\t\t- 0x%x\n", m+1); dprintf("\n"); } } VOID do_bh( ULONG64 qwAddr ) { RPC_CHAR *EntryName; ULONG64 tmp1; ULONG tmp2; ULONG64 EntryNameAddr; ULONG64 ObjectUuidAddr; GET_MEMBER(qwAddr, BINDING_HANDLE, RPCRT4!BINDING_HANDLE, EntryName, EntryNameAddr); GET_MEMBER(qwAddr, BINDING_HANDLE, RPCRT4!BINDING_HANDLE, ObjectUuid, ObjectUuidAddr); EntryName = ReadProcessRpcChar(EntryNameAddr); dprintf("\n"); PRINT_MEMBER(qwAddr, BINDING_HANDLE, RPCRT4!BINDING_HANDLE, Timeout, tmp1); dprintf("ObjectUuid\t\t- "); PrintUuid(ObjectUuidAddr); dprintf("\n"); PRINT_MEMBER(qwAddr, BINDING_HANDLE, RPCRT4!BINDING_HANDLE, NullObjectUuidFlag, tmp1); PRINT_MEMBER(qwAddr, BINDING_HANDLE, RPCRT4!BINDING_HANDLE, EntryNameSyntax, tmp1); dprintf("EntryName\t\t- %ws (Address: 0x%x)\n", EntryName ? EntryName : L"(null)", EntryNameAddr); PRINT_MEMBER(qwAddr, BINDING_HANDLE, RPCRT4!BINDING_HANDLE, EpLookupHandle, tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, BINDING_HANDLE, RPCRT4!BINDING_HANDLE, BindingMutex, "&BindingMutex(MUTEX)", tmp2); PRINT_MEMBER(qwAddr, BINDING_HANDLE, RPCRT4!BINDING_HANDLE, pvTransportOptions, tmp1); PRINT_ADDRESS_OF(qwAddr, BINDING_HANDLE, RPCRT4!BINDING_HANDLE, ClientAuthInfo, tmp2); do_authinfo(qwAddr+tmp2); } VOID do_osfbh( ULONG64 qwAddr ) { BOOL b; ULONG64 tmp1; ULONG tmp2; do_bh(qwAddr); PRINT_MEMBER(qwAddr, OSF_BINDING_HANDLE, RPCRT4!OSF_BINDING_HANDLE, Association, tmp1); PRINT_MEMBER(qwAddr, OSF_BINDING_HANDLE, RPCRT4!OSF_BINDING_HANDLE, DceBinding, tmp1); do_dcebinding(tmp1); PRINT_MEMBER(qwAddr, OSF_BINDING_HANDLE, RPCRT4!OSF_BINDING_HANDLE, TransInfo, tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_BINDING_HANDLE, RPCRT4!OSF_BINDING_HANDLE, RecursiveCalls, "&RecursiveCalls(OSF_ACTIVE_ENTRY_DICT)", tmp2); PRINT_MEMBER(qwAddr, OSF_BINDING_HANDLE, RPCRT4!OSF_BINDING_HANDLE, ReferenceCount, tmp1); PRINT_MEMBER(qwAddr, OSF_BINDING_HANDLE, RPCRT4!OSF_BINDING_HANDLE, pToken, tmp1); dprintf("\n"); } VOID do_osfca( ULONG64 qwAddr ) { BOOL b; ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, DceBinding, "DceBinding(DCE_BINDING)", tmp1); do_dcebinding(tmp1); PRINT_MEMBER(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, BindHandleCount, tmp1); PRINT_ADDRESS_OF(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, Bindings, tmp2); PRINT_ADDRESS_OF(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, ActiveConnections, tmp2); PRINT_MEMBER(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, AssocGroupId, tmp1); PRINT_MEMBER(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, TransInfo, tmp1); PRINT_MEMBER(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, SecondaryEndpoint, tmp1); PRINT_MEMBER(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, Key, tmp1); PRINT_MEMBER(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, OpenConnectionCount, tmp1); PRINT_MEMBER(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, CallIdCounter, tmp1); PRINT_ADDRESS_OF(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, AssociationMutex, tmp2); PRINT_MEMBER(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, AssociationValid, tmp1); PRINT_MEMBER(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, FailureCount, tmp1); PRINT_MEMBER(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, fMultiplex, tmp1); PRINT_MEMBER(qwAddr, OSF_CASSOCIATION, RPCRT4!OSF_CASSOCIATION, SavedDrep, tmp1); dprintf("\n"); } VOID do_dcebinding( ULONG64 qwAddr ) { RPC_STATUS RpcStatus; BOOL b; ULONG tmp2; ULONG64 RpcProtocolSequenceAddr; ULONG64 NetworkAddressAddr; ULONG64 EndpointAddr; ULONG64 OptionsAddr; ULONG64 ObjectUuidAddr; RPC_CHAR *RpcProtocolSequence; RPC_CHAR *NetworkAddress; RPC_CHAR *Endpoint; RPC_CHAR *Options; GET_MEMBER(qwAddr, DCE_BINDING, RPCRT4!DCE_BINDING, RpcProtocolSequence, RpcProtocolSequenceAddr); GET_MEMBER(qwAddr, DCE_BINDING, RPCRT4!DCE_BINDING, NetworkAddress, NetworkAddressAddr); GET_MEMBER(qwAddr, DCE_BINDING, RPCRT4!DCE_BINDING, Endpoint, EndpointAddr); GET_MEMBER(qwAddr, DCE_BINDING, RPCRT4!DCE_BINDING, Options, OptionsAddr); GET_ADDRESS_OF(qwAddr, DCE_BINDING, RPCRT4!DCE_BINDING, ObjectUuid, ObjectUuidAddr, tmp2); RpcProtocolSequence = ReadProcessRpcChar( RpcProtocolSequenceAddr); NetworkAddress = ReadProcessRpcChar( NetworkAddressAddr); Endpoint = ReadProcessRpcChar( EndpointAddr); Options = ReadProcessRpcChar( OptionsAddr); dprintf("\tObjectUuid:\t"); PrintUuid(ObjectUuidAddr); dprintf("\n"); dprintf("\tprotseq: \t\"%ws\"\t(Address: %p)\n", RpcProtocolSequence, RpcProtocolSequenceAddr); dprintf("\tNetworkAddress:\t\"%ws\"\t(Address: %p)\n", NetworkAddress, NetworkAddressAddr); dprintf("\tEndpoint:\t\"%ws\" \t(Address: %p)\n", Endpoint, EndpointAddr); dprintf("\tOptions:\t\"%ws\" \t(Address: %p)\n", Options, OptionsAddr); dprintf("\n"); } VOID do_osfcconn( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, Association, "pAssociation(OSF_CASSOCIATION)\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, CurrentCall, "CurrentCall (OSF_CCALL)\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, ConnectionKey, "ConnectionKey\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, State, "State\t\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, MaxFrag, "MaxFrag\t\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, ThreadId, "ThreadId\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, CachedCCall, "CachedCCall\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, CachedCCallAvailable, "CachedCCallAvailable\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, MaxSavedHeaderSize, "MaxSavedHeaderSize\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, SavedHeaderSize, "SavedHeaderSize\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, SavedHeader, "SavedHeader\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, AdditionalLegNeeded, "AdditionalLegNeeded\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, LastTimeUsed, "LastTimeUsed\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, TokenLength, "TokenLength\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, AdditionalSpaceForSecurity, "AdditionalSpaceForSecurity\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, fIdle, "fIdle\t\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, fExclusive, "fExclusive\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, fConnectionAborted, "fConnectionAborted\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, RefCount, "RefCount\t\t\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, Bindings, "&Bindings(BITSET)\t\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, CallQueue, "&CallQueue\t\t\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, ConnMutex, "&ConnMutex\t\t\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, ActiveCalls, "&ActiveCalls\t\t\t\t", tmp2); ULONG64 ClientSecurityContext; GET_ADDRESS_OF(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, ClientSecurityContext, ClientSecurityContext, tmp2); dprintf("&ClientSecurityContext(CSECURITY_CONTEXT)- 0x%I64x\n", ClientSecurityContext); do_securitycontext(ClientSecurityContext); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, ClientInfo, "ClientInfo (RPC_CONNECTION_TRANSPORT)\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, ComTimeout, "ComTimeout\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, u, "ConnSendContext\t\t\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, DceSecurityInfo, "&DceSecurityInfo(DCE_SECURITY_INFO)\t", tmp2); ULONG64 DceSecurityInfo; GET_ADDRESS_OF(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, DceSecurityInfo, DceSecurityInfo, tmp2); PRINT_MEMBER_WITH_LABEL(DceSecurityInfo, _DCE_SECURITY_INFO, RPCRT4!_DCE_SECURITY_INFO, SendSequenceNumber, " SendSequenceNumber\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(DceSecurityInfo, _DCE_SECURITY_INFO, RPCRT4!_DCE_SECURITY_INFO, ReceiveSequenceNumber, " ReceiveSequenceNumber\t", tmp1); ULONG64 AssociationUuid; GET_ADDRESS_OF(DceSecurityInfo, _DCE_SECURITY_INFO, RPCRT4!_DCE_SECURITY_INFO, AssociationUuid, AssociationUuid, tmp2); dprintf(" AssociationUuid\t\t - "); PrintUuid(AssociationUuid); dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, BufferToFree, "BufferToFree\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION, ConnectionReady, "ConnectionReady\t\t\t", tmp1); dprintf("\n"); ULONG64 TransConnection = qwAddr; TransConnection += GET_TYPE_SIZE(OSF_CCONNECTION, RPCRT4!OSF_CCONNECTION); dprintf("TransConnection\t\t\t - 0x%I64x\n", TransConnection); do_trans(TransConnection); } struct CallStateMap { OSF_CCALL_STATE State; char *StateString; }; struct CallStateMap CCall_States[] = { NeedOpenAndBind, "NeedOpenAndBind", NeedAlterContext, "NeedAlterContext", WaitingForAlterContext, "WaitingForAlterContext", SendingFirstBuffer, "SendingFirstBuffer", SendingMoreData, "SendingMoreData", WaitingForReply, "WaitingForReply", InCallbackRequest, "InCallbackRequest", InCallbackReply, "InCallbackReply", Receiving, "Receiving", Aborted, "Aborted", Complete, "Complete", }; char * GetCallState ( OSF_CCALL_STATE State ) { int i; for (i = 0; i < sizeof(CCall_States)/sizeof(CallStateMap); i++) { if (State == CCall_States[i].State) { return CCall_States[i].StateString; } } return "Unknown State"; } VOID do_osfccall( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, AsyncStatus, "AsyncStatus\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CachedAPCInfo, "pCachedAPCInfo\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CachedAPCInfoAvailable, "CachedAPCInfoAvailable\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, pAsync, "pAsync\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CallingThread, "CallingThread\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, NotificationIssued, "NotificationIssued\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, Connection, "Connection\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, BindingHandle, "BindingHandle\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, Bindings, "Binding\t\t\t", tmp1); ULONG64 CurrentState; GET_MEMBER(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CurrentState, CurrentState); dprintf("CurrentState\t\t - 0x%x, %s\n", (ULONG)CurrentState, GetCallState((OSF_CCALL_STATE)CurrentState)); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CurrentBuffer, "CurrentBuffer\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CurrentOffset, "CurrentOffset\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CurrentBufferLength, "CurrentBufferLength\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CallId, "CallId\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, RcvBufferLength, "RcvBufferLength\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, FirstSend, "FirstSend\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, DispatchTableCallback, "DispatchTableCallback\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, MaximumFragmentLength, "MaximumFragmentLength\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, MaxSecuritySize, "MaxSecuritySize\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, MaxDataLength, "MaxDataLength\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, ReservedForSecurity, "ReservedForSecurity\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, SecBufferLength, "SecBufferLength\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, HeaderSize, "HeaderSize\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, SavedHeaderSize, "SavedHeaderSize\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, SavedHeader, "SavedHeader\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, LastBuffer, "LastBuffer\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, ProcNum, "ProcNum\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, SyncEvent, "SyncEvent\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, ActualBufferLength, "ActualBufferLength\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, NeededLength, "NeededLength\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CallSendContext, "CallSendContext\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, RefCount, "RefCount\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, RecursiveCallsKey, "RecursiveCallsKeyF\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CallStack, "CallStack\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, fCallCancelled, "fCallCancelled\t\t", tmp1); ULONG64 CancelState; GET_MEMBER(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CancelState, CancelState); switch ((ULONG)CancelState) { case CANCEL_NOTREGISTERED: dprintf("fEnableCancels\t\t - CANCEL_NOTREGISTERED\n"); break; case CANCEL_INFINITE: dprintf("fEnableCancels\t\t - CANCEL_INFINITE\n"); break; case CANCEL_NOTINFINITE: dprintf("fEnableCancels\t\t - CANCEL_NOTINFINITE\n"); break; } PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, CallMutex, "&CallMutex\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, BufferQueue, "&BufferQueue\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, InReply, "InReply\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, fChoked, "fChoked\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_CCALL, RPCRT4!OSF_CCALL, fPeerChoked, "fPeerChoked\t\t", tmp1); dprintf("\n"); } VOID do_rpcaddr( ULONG64 qwAddr ) { RPC_CHAR *Endpoint; RPC_CHAR *RpcProtocolSequence; ULONG64 EndpointAddr; ULONG64 RpcProtocolSequenceAddr; ULONG64 tmp1; ULONG tmp2; dprintf("\n"); GET_MEMBER(qwAddr, RPC_ADDRESS, RPCRT4!RPC_ADDRESS, Endpoint, EndpointAddr); GET_MEMBER(qwAddr, RPC_ADDRESS, RPCRT4!RPC_ADDRESS, RpcProtocolSequence, RpcProtocolSequenceAddr); Endpoint = ReadProcessRpcChar(EndpointAddr); RpcProtocolSequence = ReadProcessRpcChar(RpcProtocolSequenceAddr); if ((Endpoint == NULL) || (RpcProtocolSequence == NULL)) return; dprintf("Endpoint - \"%ws\"\n", Endpoint); dprintf("RpcProtocolSequence - \"%ws\"\n", RpcProtocolSequence); PRINT_MEMBER(qwAddr, RPC_ADDRESS, RPCRT4!RPC_ADDRESS, StaticEndpointFlag, tmp1); PRINT_MEMBER(qwAddr, RPC_ADDRESS, RPCRT4!RPC_ADDRESS, pNetworkAddressVector, tmp1); PRINT_MEMBER(qwAddr, RPC_ADDRESS, RPCRT4!RPC_ADDRESS, ActiveCallCount, tmp1); PRINT_MEMBER(qwAddr, RPC_ADDRESS, RPCRT4!RPC_ADDRESS, EndpointFlags, tmp1); PRINT_MEMBER(qwAddr, RPC_ADDRESS, RPCRT4!RPC_ADDRESS, NICFlags, tmp1); PRINT_MEMBER(qwAddr, RPC_ADDRESS, RPCRT4!RPC_ADDRESS, Server, tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, RPC_ADDRESS, RPCRT4!RPC_ADDRESS, AddressMutex, "AddressMutex at", tmp2); PRINT_MEMBER(qwAddr, RPC_ADDRESS, RPCRT4!RPC_ADDRESS, DictKey, tmp1); delete Endpoint; delete RpcProtocolSequence; } VOID do_osfaddr( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; ULONG64 TransAddr = qwAddr; do_rpcaddr(qwAddr); dprintf("\n"); PRINT_ADDRESS_OF(qwAddr, OSF_ADDRESS, RPCRT4!OSF_ADDRESS, Associations, tmp2); PRINT_MEMBER(qwAddr, OSF_ADDRESS, RPCRT4!OSF_ADDRESS, SetupAddressOccurred, tmp1); PRINT_MEMBER(qwAddr, OSF_ADDRESS, RPCRT4!OSF_ADDRESS, TransInfo, tmp1); PRINT_MEMBER(qwAddr, OSF_ADDRESS, RPCRT4!OSF_ADDRESS, ServerInfo, tmp1); PRINT_MEMBER(qwAddr, OSF_ADDRESS, RPCRT4!OSF_ADDRESS, ServerListeningFlag, tmp1); TransAddr += GET_TYPE_SIZE(OSF_ADDRESS, RPCRT4!OSF_ADDRESS); dprintf("\n"); dprintf("TransAddr 0x%I64x\n", TransAddr); do_trans(TransAddr); } VOID do_osfsconn( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); ULONG64 AuthInfo; GET_ADDRESS_OF(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, AuthInfo, AuthInfo, tmp2); dprintf("&AuthInfo(CLIENT_AUTH_INFO)\t - 0x%p\n", AuthInfo); do_authinfo(AuthInfo ); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, Association, "Association(OSF_ASSOCIATION)\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, Address, "Address(OSF_ADDRESS)\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, MaxFrag, "MaxFrag\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, DataRep, "DataRep\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, AuthContextId, "AuthContextId\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, SecurityContextAltered, "SecurityContextAltered\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, RpcSecurityBeingUsed, "RpcSecurityBeingUsed\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, CurrentSecurityContext, "pCurrentSecurityContext(SSECURITY_CONTEXT)", tmp1); do_authinfo(tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, SecurityContextDict, "&SecurityContextDict(SSECURITY_CONTEXT_DICT)", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, AdditionalSpaceForSecurity, "AdditionalSpaceForSecurity\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, SavedHeaderSize, "SavedHeaderSize\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, SavedHeader, "pSavedHeader(VOID)\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, CurrentCallId, "CurrentCallId\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, CachedSCallAvailable, "CachedSCallAvailable\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, AuthContinueNeeded, "AuthContinueNeeded\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, InitSecurityInfo, "&InitSecurityInfo\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, CallDict, "&CallDict\t\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, Bindings, "&Bindings(OSF_SBINDING_DICT)\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, ConnMutex, "&ConnMutex\t\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, CachedSCall, "CachedSCall\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, ServerInfo, "ServerInfo\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, ConnectionClosedFlag, "ConnectionClosedFlag\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, DceSecurityInfo, "&DceSecurityInfo\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, fExclusive, "fExclusive\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, fDontFlush, "fDontFlush\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION, fFirstCall, "fFirstCall\t\t\t", tmp1); dprintf("\n"); ULONG64 TransConnection = qwAddr; TransConnection += GET_TYPE_SIZE(OSF_SCONNECTION, RPCRT4!OSF_SCONNECTION); dprintf("TransConnection\t\t\t - 0x%I64x\n", TransConnection); do_trans(TransConnection); } char *SCall_States[] = { "NewRequest", "CallCancelled", "CallAborted", "CallCompleted", "ReceivedCallback", "ReceivedCallbackReply", "ReceivedFault" }; VOID do_osfscall( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, AsyncStatus, "AsyncStatus\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CachedAPCInfo, "pCachedAPCInfo\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CachedAPCInfoAvailable, "CachedAPCInfoAvailable\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, pAsync, "pAsync\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CallingThread, "CallingThread\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, NotificationIssued, "NotificationIssued\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CurrentBinding, "CurrentBinding\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, Connection, "Connection\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, Address, "Address\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CallId, "CallId\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CallStack, "CallStack\t\t", tmp1); ULONG64 ObjectUuid; GET_ADDRESS_OF(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, ObjectUuid, ObjectUuid, tmp2); dprintf("ObjectUuid\t\t - "); PrintUuid(ObjectUuid); dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, ObjectUuidSpecified, "ObjectUuidSpecified\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CurrentBuffer, "CurrentBuffer\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CurrentBufferLength, "CurrentBufferLength\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CurrentOffset, "CurrentOffset\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, FirstFrag, "FirstFrag\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, FirstSend, "FirstSend\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, fPipeCall, "fPipeCall\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, fCallDispatched, "fCallDispatched\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, DispatchBuffer, "DispatchBuffer\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, LastBuffer, "LastBuffer\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, SendContext, "SendContext\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, DispatchBufferOffset, "DispatchBufferOffset\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, ProcNum, "ProcNum\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, AllocHint, "AllocHint\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, SavedHeaderSize, "SavedHeaderSize\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, SavedHeader, "SavedHeader\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, RcvBufferLength, "RcvBufferLength\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, NeededLength, "NeededLength\t\t", tmp1); ULONG64 CurrentState; GET_MEMBER(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CurrentState, CurrentState); dprintf("CurrentState\t\t - 0x%x, %s\n", (ULONG)CurrentState, SCall_States[(ULONG)CurrentState]); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CallMutex, "&CallMutex\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, SyncEvent, "&SyncEvent\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, BufferQueue, "&BufferQueue\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, Thread, "Thread\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CallOrphaned, "CallOrphaned\t\t", tmp1); ULONG64 RefCount; GET_MEMBER(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, RefCount, RefCount); dprintf("RefCount\t\t - 0x%x\n", (ULONG)RefCount); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, MaxSecuritySize, "MaxSecuritySize\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, FirstCallRpcMessage, "&FirstCallRpcMessage\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, FirstCallRuntimeInfo, "&FirstCallRuntimeInfo\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, MaximumFragmentLength, "MaximumFragmentLength\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, ActualBufferLength, "ActualBufferLength\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, fChoked, "fChoked\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, fPeerChoked, "fPeerChoked\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, DispatchFlags, "DispatchFlags\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, fSecurityFailure, "fSecurityFailure\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, CancelPending, "CancelPending\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_SCALL, RPCRT4!OSF_SCALL, fChoked, "fChoked\t\t\t", tmp1); dprintf("\n"); } VOID do_osfsa( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER(qwAddr, OSF_ASSOCIATION, RPCRT4!OSF_ASSOCIATION, CtxCollection, tmp1); PRINT_MEMBER(qwAddr, OSF_ASSOCIATION, RPCRT4!OSF_ASSOCIATION, AssociationID, tmp1); PRINT_MEMBER(qwAddr, OSF_ASSOCIATION, RPCRT4!OSF_ASSOCIATION, ConnectionCount, tmp1); PRINT_MEMBER(qwAddr, OSF_ASSOCIATION, RPCRT4!OSF_ASSOCIATION, AssociationGroupId, tmp1); PRINT_MEMBER(qwAddr, OSF_ASSOCIATION, RPCRT4!OSF_ASSOCIATION, AssociationDictKey, tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, OSF_ASSOCIATION, RPCRT4!OSF_ASSOCIATION, Address, "pAddress(OSF_ADDRESS)", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, OSF_ASSOCIATION, RPCRT4!OSF_ASSOCIATION, ClientProcess, "&ClientProcess(RPC_CLIENT_PROCESS_IDENTIFIER)", tmp2); dprintf("\n"); } DECLARE_API( rpcsvr ) { ULONG64 qwAddr; BOOL fArgSpecified = FALSE; ULONG64 ServerAddress; LPSTR lpArgumentString = (LPSTR)args; if (0 == strtok(lpArgumentString)) { lpArgumentString = "rpcrt4!GlobalRpcServer"; fArgSpecified = TRUE; } qwAddr = GetExpression(lpArgumentString); if ( !qwAddr ) { dprintf("Error: can't evaluate '%s'\n", lpArgumentString); return; } if (fArgSpecified) { if (ReadPtr(qwAddr, &ServerAddress)) { dprintf("couldn't read memory at address 0x%I64x\n", qwAddr); return; } } else ServerAddress = qwAddr; do_rpcsvr(ServerAddress); } VOID do_rpcsvr( ULONG64 qwAddr ) { ULONG64 tmp0; ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, pRpcForwardFunction, "pRpcForwardFunction(RPC_FORWARD_FUNCTION)", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, RpcInterfaceDictionary, "&RpcInterfaceDictionary(RPC_SIMPLE_DICT)", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, ServerMutex, "&ServerMutex(MUTEX)", tmp2); GET_ADDRESS_OF(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, AvailableCallCount, tmp1, tmp2); PRINT_MEMBER_WITH_LABEL(tmp1, INTERLOCKED_INTEGER, RPCRT4!INTERLOCKED_INTEGER, Integer, "AvailableCallCount", tmp0); PRINT_MEMBER(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, ServerListeningFlag, tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, RpcAddressDictionary, "&RpcAddressDictionary(RPC_SIMPLE_DICT)", tmp2); PRINT_MEMBER(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, ListeningThreadFlag, tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, StopListeningEvent, "&StopListeningEvent(EVENT)", tmp2); PRINT_MEMBER(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, MaximumConcurrentCalls, tmp1); PRINT_MEMBER(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, MinimumCallThreads, tmp1); PRINT_MEMBER(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, IncomingRpcCount, tmp1); PRINT_MEMBER(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, OutgoingRpcCount, tmp1); PRINT_MEMBER(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, ReceivedPacketCount, tmp1); PRINT_MEMBER(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, SentPacketCount, tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, AuthenticationDictionary, "&AuthenticationDictionary(RPC_SIMPLE_DICT)", tmp2); PRINT_MEMBER(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, WaitingThreadFlag, tmp1); PRINT_MEMBER(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, ThreadCache, tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, ThreadCacheMutex, "&ThreadCacheMutex(MUTEX)", tmp2); PRINT_MEMBER(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, fAccountForMaxCalls, tmp1); dprintf("\n"); } struct SizeTable { int Size; int Count; }; struct SizeTable *Stats = NULL; int MaxSize = 1048*10; int CurrentSize = 0; void AddToStats ( int Size ) { int i; for (i = 0; i < CurrentSize; i++) { if (Stats[i].Size == Size) { Stats[i].Count++; return; } } Stats[CurrentSize].Size = Size; Stats[CurrentSize].Count = 1; CurrentSize++; } int __cdecl compare( const void *arg1, const void *arg2 ) { return ((struct SizeTable *) arg2)->Count - ((struct SizeTable *) arg1)->Count; } void PrintStats ( ) { int i; int Total = 0; qsort(&Stats[0], CurrentSize, sizeof(SizeTable), compare); dprintf("\n\nSummary:\n"); for (i = 0; i < CurrentSize; i++) { dprintf("Size: %08x Count: %d\n", Stats[i].Size, Stats[i].Count ); Total += Stats[i].Count; } dprintf("Total Count: %d\n", Total); } VOID do_rpcmem( ULONG64 qwAddr, long Count, long Verbose, BOOL Summary, long Size ) { BOOL b; BOOL forwards = TRUE; BOOL doAll = FALSE; DWORD t; ULONG64 tmp1; ULONG tmp2; unsigned Data[16]; unsigned char RearGuardBlock[4]; #if DBG if (Count < 0) { forwards = FALSE; } else if (Count == 0) { doAll = TRUE; } if (Stats == NULL) { Stats = (struct SizeTable *) RpcpFarAllocate(MaxSize * sizeof(struct SizeTable)); if (Stats == NULL) { return; } } RpcpMemorySet(Stats, 0, MaxSize); dprintf("\n"); do { if ((CheckControlC)()) { return; } ULONG64 size; GET_MEMBER(qwAddr, RPC_MEMORY_BLOCK, RPCRT4!RPC_MEMORY_BLOCK, size, size); AddToStats((int)size); if ((Size == 0 || Size == (long) size) && !Summary) { ULONG64 rearguard; GET_ADDRESS_OF(qwAddr, RPC_MEMORY_BLOCK, RPCRT4!RPC_MEMORY_BLOCK, rearguard, rearguard, tmp2); dprintf("-------- size (%08x) block: 0x%I64x contains: %s", (ULONG)size, qwAddr, SymbolAtAddressNoOffset(rearguard) ); if (Verbose) { b = GetData(rearguard, Data, min((ULONG)size, sizeof(Data))); if ( !b ) { dprintf("can't read block data at 0x%I64x\n", rearguard); return; } for (t = 0; t < min(((ULONG)size)/4, sizeof(Data)/4); t++) { if (t % 4 == 0) { dprintf("\n%I64p ", rearguard + t*4); } dprintf("%I64p ", Data[t]); } } dprintf("\n"); } ULONG64 frontguardAddr; ULONG64 rearguardAddr; GET_ADDRESS_OF(qwAddr, RPC_MEMORY_BLOCK, RPCRT4!RPC_MEMORY_BLOCK, frontguard, frontguardAddr, tmp2); GET_ADDRESS_OF(qwAddr+size, RPC_MEMORY_BLOCK, RPCRT4!RPC_MEMORY_BLOCK, rearguard, rearguardAddr, tmp2); unsigned char frontguardVal[4]; unsigned char rearguardVal[4]; GetData(frontguardAddr, frontguardVal, sizeof(frontguardVal)); GetData(rearguardAddr, rearguardVal, sizeof(rearguardVal)); if ( (frontguardVal[0] != RPC_GUARD) || (frontguardVal[1] != RPC_GUARD) || (frontguardVal[2] != RPC_GUARD) || (frontguardVal[3] != RPC_GUARD) ) { dprintf(" RPC: BAD FRONTGUARD %x-%x-%x-%x\n", frontguardVal[0], frontguardVal[1], frontguardVal[2], frontguardVal[3]); } if ( (rearguardVal[0] != RPC_GUARD) || (rearguardVal[1] != RPC_GUARD) || (rearguardVal[2] != RPC_GUARD) || (rearguardVal[3] != RPC_GUARD) ) { dprintf(" RPC: BAD REARGUARD %x-%x-%x-%x\n", rearguardVal[0], rearguardVal[1], rearguardVal[2], rearguardVal[3]); } ULONG64 next; ULONG64 previous; GET_MEMBER(qwAddr, RPC_MEMORY_BLOCK, RPCRT4!RPC_MEMORY_BLOCK, next, next); GET_MEMBER(qwAddr, RPC_MEMORY_BLOCK, RPCRT4!RPC_MEMORY_BLOCK, previous, previous); if (forwards == TRUE) { qwAddr = next; Count--; } else { qwAddr = previous; Count++; } } while (qwAddr && (Count || doAll) ); PrintStats(); #endif dprintf("\n"); } VOID do_rpcmsg( ULONG64 qwAddr ) { ULONG64 tmp1; dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_MESSAGE, RPCRT4!RPC_MESSAGE, Handle, "Handle(RPC_BINDING_HANDLE) ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_MESSAGE, RPCRT4!RPC_MESSAGE, DataRepresentation, "DataRepresentation ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_MESSAGE, RPCRT4!RPC_MESSAGE, Buffer, "pBuffer(void) ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_MESSAGE, RPCRT4!RPC_MESSAGE, BufferLength, "BufferLength ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_MESSAGE, RPCRT4!RPC_MESSAGE, ProcNum, "ProcNum ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_MESSAGE, RPCRT4!RPC_MESSAGE, TransferSyntax, "TransferSyntax(RPC_SYNTAX_IDENTIFIER) ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_MESSAGE, RPCRT4!RPC_MESSAGE, RpcInterfaceInformation, "pRpcInterfaceInformation(void) ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_MESSAGE, RPCRT4!RPC_MESSAGE, ReservedForRuntime, "pReservedForRuntime(void) ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_MESSAGE, RPCRT4!RPC_MESSAGE, ManagerEpv, "pManagerEpv(RPC_MGR_EPV) ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_MESSAGE, RPCRT4!RPC_MESSAGE, ImportContext, "pImportContext(void) ", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_MESSAGE, RPCRT4!RPC_MESSAGE, RpcFlags, "RpcFlags ", tmp1); dprintf("\n"); } VOID do_transinfo( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; ULONG64 LoadableTrans; GET_MEMBER(qwAddr, TRANS_INFO, RPCRT4!TRANS_INFO, LoadableTrans, LoadableTrans); dprintf("\n"); PRINT_MEMBER(qwAddr, TRANS_INFO, RPCRT4!TRANS_INFO, pTransportInterface, tmp1); PRINT_MEMBER(qwAddr, TRANS_INFO, RPCRT4!TRANS_INFO, LoadableTrans, tmp1); PRINT_MEMBER(LoadableTrans, LOADABLE_TRANSPORT, RPCRT4!LOADABLE_TRANSPORT, ThreadsStarted, tmp1); PRINT_MEMBER(LoadableTrans, LOADABLE_TRANSPORT, RPCRT4!LOADABLE_TRANSPORT, NumThreads, tmp1); PRINT_MEMBER(LoadableTrans, LOADABLE_TRANSPORT, RPCRT4!LOADABLE_TRANSPORT, ProcessCallsFunc, tmp1); PRINT_MEMBER(LoadableTrans, LOADABLE_TRANSPORT, RPCRT4!LOADABLE_TRANSPORT, LoadedDll, tmp1); PRINT_ADDRESS_OF(LoadableTrans, LOADABLE_TRANSPORT, RPCRT4!LOADABLE_TRANSPORT, ProtseqDict, tmp2); PRINT_ADDRESS_OF(LoadableTrans, LOADABLE_TRANSPORT, RPCRT4!LOADABLE_TRANSPORT, DllName, tmp2); PRINT_MEMBER(qwAddr, TRANS_INFO, RPCRT4!TRANS_INFO, RpcProtocolSequence, tmp1); dprintf("\n"); } DECLARE_API( help ) { LPSTR lpArgumentString = (LPSTR)args; if (lpArgumentString[0] == '\0') { dprintf( "\n"); dprintf( "rpcdbg help:\n\n"); dprintf( "\n"); dprintf( "!obj
- Dumps an RPC object \n"); dprintf( "\n"); dprintf( "!sizes - Prints sizes of the data structures\n"); dprintf( "!error - Translates and error value into the error message\n"); dprintf( "!symbol (
|) - Returns symbol name/address\n"); dprintf( "!rpcheap [-a
][-d ] - Dumps RPC_MEMORY_BLOCK linked list\n"); dprintf( "\n"); dprintf( "!pasync
- Dumps RPC_ASYNC_STATE\n"); dprintf( "!rpcmsg
- Dumps RPC_MESSAGE\n"); dprintf( "!stubmsg
- Dumps MIDL_STUB_MESSAGE\n"); dprintf( "!authinfo
- Dumps CLIENT_AUTH_INFO\n"); dprintf( "!rpcsvr
- Dumps RPC_SERVER \n"); dprintf( "!secinfo - Dumps security provider/package info\n"); dprintf( "!dict
- Dumps SDICT \n"); dprintf( "!dict2
- Dumps SDICT2 \n"); dprintf( "!queue
- Dumps QUEUE \n"); dprintf( "!thread - Dumps THREAD \n"); dprintf( "!copacket
- Dumps CO packet \n"); dprintf( "!lpcpacket
- Dumps LRPC packet \n"); dprintf( "!transinfo
- Dumps TRANS_INFO \n"); dprintf( "\n"); dprintf( "!scan [options] - Dumps the event log, add '-?' for help\n"); dprintf( "!dgcc
- Dumps DG_CCALL \n"); dprintf( "!dgsc
- Dumps DG_SCALL \n"); dprintf( "!dgpe
- Dumps DG_PACKET_ENGINE\n"); dprintf( "!dgpkt
- Dumps DG_PACKET \n"); dprintf( "!dgpkthdr
- Dumps dg packet header (NCA_PACKET_HEADER)\n"); dprintf( "!dgep
- Dumps DG_ENDPOINT \n"); dprintf( "\n"); dprintf( "!asyncmsg
- Dumps NDR_ASYNC_MESSAGE\n"); dprintf( "!asyncrpc
- Dumps RPC_ASYNC_STATE\n"); dprintf( "!asyncdcom
- Dumps CAsyncManager\n"); dprintf( "\n"); dprintf( "!pipemsg
- Dumps NDR_PIPE_MESSAGE\n"); dprintf( "!pipedesc
- Dumps NDR_PIPE_DESC\n"); dprintf( "!pipestate
- Dumps NDR_PIPE_STATE\n"); dprintf( "\n"); dprintf( "!trans
- Dumps most NT RPC transport objects\n"); dprintf( "!overlap
- Dumps object associated with OVERLAPPED pointer\n"); dprintf( "!wsaddr
- Dumps sockaddr structure\n"); dprintf( "!protocols
- Dumps PnP protocols map & related objects\n"); dprintf( "\n"); dprintf( "!rpcsleep - Pauses the extension\n"); dprintf( "!rpctime - Displays current system time\n"); dprintf( "!getcallinfo [options] - Searches the system for call info, add '-?' for help\n"); dprintf( "!getendpointinfo [options] - Searches the system for endpoint info, add '-?' for help\n"); dprintf( "!getdbgcell . - Gets info for the specified cell\n"); dprintf( "!getthreadinfo [options] - Searches the system for thread info, add '-?' for help\n"); dprintf( "!getclientcallinfo [options] - Searches the system for client call info, add '-?' for help\n"); dprintf( "!checkrpcsym - Checks whether RPC symbols are correct\n"); dprintf( "!rpcreadstack - Reads an RPC client side stack and retrieves the call info\n"); dprintf( "!rpcverbosestack - toggles the state of the verbose spew when reading the stack\n"); dprintf( "!eerecord - prints an extended error info record\n"); dprintf( "!eeinfo - prints the extended error info chain\n"); dprintf( "!typeinfo - turns on/off the use of type information\n"); dprintf( "!stackmatch start_addr [depth] matches stack symbols and target addresses\n"); dprintf( "!listcalls
- Dumps addresses, associations, and calls active within the RPC_SERVER at address\n\n"); } } void do_symbol(ULONG64 qwAddr) { CHAR Symbol[128]; ULONG64 Displacement = 0; GetSymbol(qwAddr, Symbol, &Displacement); dprintf("%I64x %s+%I64x\n", qwAddr, Symbol, Displacement); } DECLARE_API( symbol ) { ULONG64 qwAddr; LPSTR lpArgumentString = (LPSTR)args; qwAddr = GetExpression(lpArgumentString); if ( !qwAddr ) { return; } do_symbol(qwAddr); } #define MAX_ARGS 4 DECLARE_API( rpcheap ) { ULONG64 qwAddr = 0; ULONG64 dwTmpAddr = 0; long lDisplay = 0; long lVerbose = 1; BOOL Summary = 0; char **argv = new char*[MAX_ARGS]; int argc = 0; int i; long lSize = 0; CurrentSize = 0; LPSTR lpArgumentString = (LPSTR)args; //#ifdef DEBUGRPC for (i = 0; ; ) { while (lpArgumentString[i] == ' ') { lpArgumentString[i] = '\0'; i++; } if (lpArgumentString[i] == '\0') { break; } argv[argc] = &(lpArgumentString[i]); argc++; if (argc > MAX_ARGS) { dprintf("\nToo many arguments. Extra args ignored.\n\n"); break; } while ((lpArgumentString[i] != ' ')&& (lpArgumentString[i] != '\0')) { i++; } } for (i = 0; i < argc; i++) { if ((*argv[i] == '-') || (*argv[i] == '/') || (*argv[i] == '+')) { switch (*(argv[i]+1)) { case 'A': case 'a': qwAddr = GetExpression(argv[++i]); if (!qwAddr) { dprintf("Error: Failure to get address of RPC memory list\n"); return; } break; case 'D': case 'd': lDisplay = (long)myatol(argv[++i]); break; case 's': Summary = 1; break; case 'z': lSize = (long) GetExpression(argv[++i]); break; case 'q': case 'Q': lVerbose = FALSE; break; case '?': default: dprintf("rpcheap \n"); dprintf(" -a
(default:starts at head of linked list)\n"); dprintf(" -d (default: to end)\n"); break; } } else { dprintf("rpcheap \n"); dprintf(" -a
(default:starts at head of linked list)\n"); dprintf(" -d (default: to end)\n"); } } if (!qwAddr) { dwTmpAddr = GetExpression("rpcrt4!AllocatedBlocks"); ReadPtr(dwTmpAddr, &qwAddr); dprintf("Address of AllocatedBlocks - 0x%I64x\n", dwTmpAddr); dprintf("Contents of AllocatedBlocks - 0x%I64x\n", qwAddr); } do_rpcmem(qwAddr, lDisplay, lVerbose, Summary, lSize); //#else // DEBUGRPC //dprintf("This extension command is not supported on a free build!\n"); //#endif // DEBUGRPC if (argv) { delete[] argv; } return; } VOID do_lpcaddr( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; do_rpcaddr( qwAddr ); dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_ADDRESS, RPCRT4!LRPC_ADDRESS, LpcAddressPort, "LpcAddressPort(HANDLE)\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_ADDRESS, RPCRT4!LRPC_ADDRESS, CallThreadCount, "CallThreadCount\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_ADDRESS, RPCRT4!LRPC_ADDRESS, MinimumCallThreads, "MinimumCallThreads\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_ADDRESS, RPCRT4!LRPC_ADDRESS, AssociationDictionary, "&Associations(LRPC_ASSOCIATION_DICT)", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_ADDRESS, RPCRT4!LRPC_ADDRESS, AssociationCount, "AssociationCount\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_ADDRESS, RPCRT4!LRPC_ADDRESS, ServerListeningFlag, "ServerListeningFlag\t\t", tmp1); dprintf("\n"); } VOID do_lpcsa( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, AssociationReferenceCount, "AssociationReferenceCount\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, DictionaryKey, "DictionaryKey\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, LpcServerPort, "LpcServerPort(HANDLE)\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, LpcReplyPort, "LpcReplyPort\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, Address, "Address\t\t\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, Bindings, "&Bindings(LRPC_SBINDING_DICT)\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, Aborted, "Aborted\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, Deleted, "Deleted\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, SequenceNumber, "SequenceNumber\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, CachedSCall, "CachedSCall\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, CachedSCallAvailable, "CachedSCallAvailable\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, Buffers, "&Buffers(LRPC_CLIENT_BUFFER_DICT)", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, AssociationMutex, "&AssociationMutex\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, FreeSCallQueue, "&FreeSCallQueue\t\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, ClientThreadDict, "&ClientThreadDict\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, SContextDict, "&SContextDict\t\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_SASSOCIATION, RPCRT4!LRPC_SASSOCIATION, SCallDict, "&SCallDict\t\t\t", tmp2); dprintf("\n"); } VOID do_lpcscall( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, AsyncStatus, "AsyncStatus\t\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, CachedAPCInfo, "pCachedAPCInfo\t\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, CachedAPCInfoAvailable, "CachedAPCInfoAvailable\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, pAsync, "pAsync\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, CallingThread, "CallingThread\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, NotificationIssued, "NotificationIssued\t\t", tmp1); ULONG64 AuthInfo; GET_ADDRESS_OF(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, AuthInfo, AuthInfo, tmp2); dprintf("&ClientAuthInfo\t\t\t - 0x%I64x\n", AuthInfo); do_authinfo(AuthInfo ); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, ActiveContextHandles, "&ActiveContextHandles(ServerContextHandle_DICT)\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, DispatchBuffer, "DispatchBuffer\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, Association, "pAssociation(LRPC_ASSOCIATION)\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, LrpcRequestMessage, "pLrpcMessage(LRPC_MESSAGE)\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, LrpcReplyMessage, "pLrpcReplyMessage(LRPC_MESSAGE)\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, SBinding, "pSBinding(LRPC_SBINDING)\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, ObjectUuidFlag, "ObjectUuidFlag\t\t\t", tmp1); ULONG64 ObjectUuid; GET_ADDRESS_OF(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, ObjectUuid, ObjectUuid, tmp2); dprintf("ObjectUuid\t\t\t - "); PrintUuid(ObjectUuid); dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, CallId, "CallId\t\t\t\t", tmp1); ULONG64 ClientId; GET_ADDRESS_OF(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, ClientId, ClientId, tmp2); PRINT_MEMBER_WITH_LABEL(ClientId, CLIENT_ID, RPCRT4!CLIENT_ID, UniqueProcess, "ClientId.UniqueProcess(CLIENT_ID.HANDLE)", tmp1); PRINT_MEMBER_WITH_LABEL(ClientId, CLIENT_ID, RPCRT4!CLIENT_ID, UniqueThread, "ClientId.UniqueThread (CLIENT_ID.HANDLE)", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, MessageId, "MessageId\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, PushedResponse, "pPushedResponse(VOID)\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, CurrentBufferLength, "CurrentBuffferLength\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, BufferComplete, "BufferComplete\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, Flags, "Flags\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, FirstSend, "FirstSend\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, PipeSendCalled, "PipeSendCalled\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, Deleted, "Deleted\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, ReceiveEvent, "ReceiveEvent\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, CallMutex, "CallMutex\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, RcvBufferLength, "RcvBufferLength\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, AsyncReply, "AsyncReply\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, NextSCall, "NextSCall\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, NeededLength, "NeededLength\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, fSyncDispatch, "fSyncDispatch\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, Choked, "Choked\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, CancelPending, "CancelPending\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, RefCount, "RefCount\t\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, BufferQueue, "&BufferQueue\t\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_SCALL, RPCRT4!LRPC_SCALL, SContext, "SContext\t\t\t", tmp1); dprintf("\n"); } VOID do_lpcbh( ULONG64 qwAddr ) { ULONG64 tmp0; ULONG tmp1; do_bh(qwAddr); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_BINDING_HANDLE, RPCRT4!LRPC_BINDING_HANDLE, CurrentAssociation, "pCurrentAssociation(LRPC_CASSOCIATION)", tmp0); PRINT_ADDRESS_OF(qwAddr, LRPC_BINDING_HANDLE, RPCRT4!LRPC_BINDING_HANDLE, SecAssociation, tmp1); PRINT_MEMBER(qwAddr, LRPC_BINDING_HANDLE, RPCRT4!LRPC_BINDING_HANDLE, DceBinding, tmp0); GET_ADDRESS_OF(qwAddr, LRPC_BINDING_HANDLE, RPCRT4!LRPC_BINDING_HANDLE, DceBinding, tmp0, tmp1); do_dcebinding(tmp0); PRINT_MEMBER(qwAddr, LRPC_BINDING_HANDLE, RPCRT4!LRPC_BINDING_HANDLE, BindingReferenceCount, tmp0); PRINT_ADDRESS_OF(qwAddr, LRPC_BINDING_HANDLE, RPCRT4!LRPC_BINDING_HANDLE, RecursiveCalls, tmp1); PRINT_MEMBER(qwAddr, LRPC_BINDING_HANDLE, RPCRT4!LRPC_BINDING_HANDLE, AuthInfoInitialized, tmp0); } VOID do_lpcca( ULONG64 qwAddr ) { dprintf("\n"); ULONG64 tmp1; ULONG tmp2; ULONG64 DceBinding; GET_MEMBER(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, DceBinding, DceBinding); dprintf("pDceBinding(DCE_BINDING)\t- 0x%I64x\n", DceBinding); do_dcebinding(DceBinding); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, AssociationDictKey, "AssociationDictKey\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, Bindings, "&Bindings(LRPC_BINDING_DICT)\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, FreeCCalls, "&FreeCCalls\t\t\t", tmp2); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, ActiveCCalls, "&ActiveCCalls\t\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, LpcClientPort, "LpcClientPort\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, LpcReceivePort, "LpcReceivePort\t\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, AssociationMutex, "&AssociationMutex(MUTEX)\t", tmp2); ULONG64 AssocAuthInfo; GET_ADDRESS_OF(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, AssocAuthInfo, AssocAuthInfo, tmp2); do_authinfo(AssocAuthInfo); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, BackConnectionCreated, "BackConnectionCreated\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, CachedCCall, "pCachedCCall(LRPC_CCALL)\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, CachedCCallFlag, "CachedCCallFlag\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, CallIdCounter, "CallIdCounter\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, SequenceNumber, "SequenceNumber\t\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, SecurityContextDict, "&SecurityContextDict\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, LastSecContextTrimmingTimestamp, "Timestamp\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CASSOCIATION, RPCRT4!LRPC_CASSOCIATION, BindingHandleReferenceCount, "BindingHAndleReferenceCount\t", tmp1); dprintf("\n"); } VOID do_lpcccall( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, AsyncStatus, "AsyncStatus\t\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CachedAPCInfo, "pCachedAPCInfo\t\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CachedAPCInfoAvailable, "CachedAPCInfoAvailable\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, pAsync, "pAsync\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CallingThread, "CallingThread\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, NotificationIssued, "NotificationIssued\t\t", tmp1); ULONG64 AuthInfo; GET_ADDRESS_OF(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, AuthInfo, AuthInfo, tmp2); dprintf("AuthInfo\t\t\t- 0x%I64x\n", AuthInfo); do_authinfo(AuthInfo); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CurrentBindingHandle, "pCurrentBindingHandle(LRPC_BINDING_HANDLE)", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, Association, "pAssociation(LRPC_CASSOCIATION)\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, LrpcMessage, "pLrpcMessage(LRPC_MESSAGE)\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, RpcReplyMessage, "RpcReplyMessage\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, LpcReplyMessage, "LpcReplyMessage\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, RcvBufferLength, "RcvBufferLength\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, Choked, "Choked\t\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, RecursiveCallsKey, "RecursiveCallsKey\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, FreeCallKey, "FreeCallKey\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CallId, "CallId\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, MessageId, "MessageId\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CallbackId, "CallbackId\t\t\t", tmp1); ULONG64 ClientId; GET_ADDRESS_OF(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, ClientId, ClientId, tmp2); PRINT_MEMBER_WITH_LABEL(ClientId, CLIENT_ID, RPCRT4!CLIENT_ID, UniqueProcess, "ClientId.UniqueProcess(CLIENT_ID.HANDLE)", tmp1); PRINT_MEMBER_WITH_LABEL(ClientId, CLIENT_ID, RPCRT4!CLIENT_ID, UniqueThread, "ClientId.UniqueThread (CLIENT_ID.HANDLE)", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, DataInfoOffset, "DataInfoOffset\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CallAbortedFlag, "CallAbortedFlag\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, Thread, "Thread(THREAD_IDENTIFIER)\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, Binding, "Binding(LRPC_BINDING)", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, RecursionCount, "RecursionCount\t\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, SyncEvent, "SyncEvent\t\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, MsgFlags, "MsgFlags\t\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CallMutex, "CallMutex\t\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CallStack, "CallStack\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CachedLrpcMessage, "CachedLrpcMessage\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, FirstFrag, "FirstFrag\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CurrentBufferLength, "CurrentBufferLength\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, NeededLength, "NeededLength\t\t\t", tmp1); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, BufferQueue, "BufferQueue\t\t\t", tmp2); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, fSendComplete, "fSendcomplete\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, CurrentSecurityContext, "CurrentSecurityContext\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, LRPC_CCALL, RPCRT4!LRPC_CCALL, EEInfo, "Extended Error Info\t\t", tmp1); dprintf("\n"); } VOID do_pasync( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, Size, "Size\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, Signature, "Signature\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, Lock, "Lock\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, Flags, "Flags\t\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, StubInfo, "StubInfo\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, UserInfo, "UserInfo\t\t", tmp1); PRINT_MEMBER_WITH_LABEL(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, RuntimeInfo, "RuntimeInfo\t\t", tmp1); ULONG64 Event; GET_MEMBER(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, Event, Event); dprintf("Event\t\t\t - "); switch ((ULONG)Event) { case RpcCallComplete: dprintf("RpcCallComplete\n"); break; case RpcSendComplete: dprintf("RpcSendComplete\n"); break; case RpcReceiveComplete: dprintf("RpcReceiveComplete\n"); break; default: dprintf("(unknown) 0x%I64x\n", Event); break; } ULONG64 NotificationType; GET_MEMBER(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, NotificationType, NotificationType); dprintf("NotificationType\t - "); BOOL b; char block[sizeof(RPC_ASYNC_STATE)]; PRPC_ASYNC_STATE pa = (PRPC_ASYNC_STATE)█ if (!fUseTypeInfo) { b = GetData(qwAddr, &block, sizeof(RPC_ASYNC_STATE)); if ( !b ) { dprintf("can't read %p\n", qwAddr); return; } } switch ((ULONG)NotificationType) { case RpcNotificationTypeNone: dprintf("RpcNotificationTypeNone\n"); break; case RpcNotificationTypeEvent: dprintf("RpcNotificationTypeEvent\n"); if (!fUseTypeInfo) dprintf("\thEvent\t\t - 0x%p\n", pa->u.hEvent); break; case RpcNotificationTypeApc: dprintf("RpcNotificationTypeApc\n"); if (!fUseTypeInfo) { dprintf("\tNotificationRoutine\t - 0x%p\n", pa->u.APC.NotificationRoutine); dprintf("\thThread\t\t\t - 0x%p\n", pa->u.APC.hThread); } break; case RpcNotificationTypeIoc: dprintf("RpcNotificationTypeIoc\n"); if (!fUseTypeInfo) { dprintf("\thIOPort\t\t\t - 0x%p\n", pa->u.IOC.hIOPort); dprintf("\tdwNumberOfBytesTransferred - 0x%x\n", pa->u.IOC.dwNumberOfBytesTransferred); dprintf("\tdwCompletionKey\t\t - 0x%p\n", pa->u.IOC.dwCompletionKey); dprintf("\tlpOverlapped\t\t - 0x%x\n", pa->u.IOC.lpOverlapped); } break; case RpcNotificationTypeHwnd: dprintf("RpcNotificationTypeHwnd\n"); if (!fUseTypeInfo) { dprintf("\thWnd\t\t - 0x%p\n", pa->u.HWND.hWnd); dprintf("\tMsg\t\t - 0x%x\n", pa->u.HWND.Msg); } break; case RpcNotificationTypeCallback: dprintf("RpcNotificationTypeCallback\n"); if (!fUseTypeInfo) { dprintf("NotificationRoutine\t - 0x%p\n", pa->u.NotificationRoutine); } break; default: dprintf("Bad notification type\n"); } dprintf("\n"); } char * ReceiveStates[] = { "START", "COPY_PIPE_ELEM", "RETURN_PARTIAL", "READ_PARTIAL" }; void do_stubmsg( ULONG64 msg ) { ULONG64 tmp0; dprintf("MIDL_STUB_MESSAGE at 0x%I64x\n\n", msg); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, Buffer, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, BufferStart, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, BufferEnd, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, BufferMark, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, MemorySize, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, Memory, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, BufferLength, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, pAllocAllNodesContext, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, RpcMsg, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, SavedHandle, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, StubDesc, tmp0); PRINT_MEMBER_BOOLEAN(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, IsClient, tmp0); PRINT_MEMBER_BOOLEAN(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, ReuseBuffer, tmp0); PRINT_MEMBER_BOOLEAN(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, IgnoreEmbeddedPointers, tmp0); PRINT_MEMBER_BOOLEAN(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, fBufferValid, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, MaxCount, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, ActualCount, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, Offset, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, StackTop, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, pPresentedType, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, pTransmitType, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, pRpcChannelBuffer, tmp0); PRINT_MEMBER(msg, MIDL_STUB_MESSAGE, RPCRT4!MIDL_STUB_MESSAGE, pAsyncMsg, tmp0); } VOID do_dgaddr( ULONG64 qwAddr ) { ULONG64 tmp0; ULONG tmp1; dprintf("DG_ADDRESS at 0x%I64x\n\n", qwAddr); do_rpcaddr(qwAddr); PRINT_MEMBER(qwAddr, DG_ADDRESS, RPCRT4!DG_ADDRESS, TransInfo, tmp0); PRINT_MEMBER_SYMBOL(qwAddr, DG_ADDRESS, RPCRT4!DG_ADDRESS, TransInfo, tmp0); PRINT_MEMBER(qwAddr, DG_ADDRESS, RPCRT4!DG_ADDRESS, ActiveCallCount, tmp0); PRINT_MEMBER(qwAddr, DG_ADDRESS, RPCRT4!DG_ADDRESS, CachedConnections, tmp0); dprintf("\nendpoint data:\n"); GET_ADDRESS_OF(qwAddr, DG_ADDRESS, RPCRT4!DG_ADDRESS, Endpoint, tmp0, tmp1); do_dgep(tmp0); dprintf("\nobsolete data:\n"); PRINT_MEMBER(qwAddr, DG_ADDRESS, RPCRT4!DG_ADDRESS, TotalThreadsThisEndpoint, tmp0); PRINT_MEMBER(qwAddr, DG_ADDRESS, RPCRT4!DG_ADDRESS, ThreadsReceivingThisEndpoint, tmp0); PRINT_MEMBER(qwAddr, DG_ADDRESS, RPCRT4!DG_ADDRESS, MinimumCallThreads, tmp0); PRINT_MEMBER(qwAddr, DG_ADDRESS, RPCRT4!DG_ADDRESS, MaximumConcurrentCalls, tmp0); PRINT_ADDRESS_OF(qwAddr, DG_ADDRESS, RPCRT4!DG_ADDRESS, ScavengerTimer, tmp1); } VOID do_dgbh( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; do_bh(qwAddr); dprintf("DCE_BINDING:\n"); ULONG64 pDceBinding; GET_MEMBER(qwAddr, DG_BINDING_HANDLE, RPCRT4!DG_BINDING_HANDLE, pDceBinding, pDceBinding); do_dcebinding(pDceBinding); PRINT_MEMBER(qwAddr, DG_BINDING_HANDLE, RPCRT4!DG_BINDING_HANDLE, EndpointFlags, tmp1); PRINT_MEMBER(qwAddr, DG_BINDING_HANDLE, RPCRT4!DG_BINDING_HANDLE, Association, tmp1); PRINT_MEMBER(qwAddr, DG_BINDING_HANDLE, RPCRT4!DG_BINDING_HANDLE, ReferenceCount, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_BINDING_HANDLE, RPCRT4!DG_BINDING_HANDLE, fDynamicEndpoint, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_BINDING_HANDLE, RPCRT4!DG_BINDING_HANDLE, fContextHandle, tmp1); PRINT_MEMBER(qwAddr, DG_BINDING_HANDLE, RPCRT4!DG_BINDING_HANDLE, TransportObject, tmp1); PRINT_MEMBER(qwAddr, DG_BINDING_HANDLE, RPCRT4!DG_BINDING_HANDLE, TransportInterface, tmp1); } VOID do_dgpe( ULONG64 qwAddr ) { DG_PACKET_ENGINE *dgpe; char block[sizeof(DG_PACKET_ENGINE)]; dgpe = (DG_PACKET_ENGINE *) block; ULONG64 tmp1; ULONG tmp; if (!fUseTypeInfo) { GetData(qwAddr, &block, sizeof(DG_PACKET_ENGINE)); } PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, SequenceNumber, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, ReferenceCount, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, PacketType,tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, ActivityHint, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, TimeoutCount, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, CurrentPduSize, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, MaxFragmentSize, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, SecurityTrailerSize, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, pSavedPacket, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, SourceEndpoint, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, RemoteAddress, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, BaseConnection, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, pReceivedPackets, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, ReceiveFragmentBase, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, LastReceiveBuffer, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, pLastConsecutivePacket, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, LastReceiveBufferLength, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, ConsecutiveDataBytes, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, fReceivedAllFragments, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, Buffer, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, SendWindowBase, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, FinalSendFrag, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, BufferLength, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, SendWindowBits, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, FackSerialNumber, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, BufferFlags,tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, SendWindowSize, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, fRetransmitted, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, FirstUnsentOffset, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, SendBurstLength, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, QueuedBufferHead, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, FirstUnsentFragment, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, QueuedBufferTail, tmp1); PRINT_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, RingBufferBase, tmp1); if (!fUseTypeInfo) { dprintf(" Frag Offset Length Serial # | Frag Offset Length Serial #\n" " ---- -------- ------ -------- | ---- -------- ------ --------\n" ); } ULONG64 RingBufferBase; ULONG64 SendWindowBase; GET_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, RingBufferBase, RingBufferBase); GET_MEMBER(qwAddr, DG_PACKET_ENGINE, RPCRT4!DG_PACKET_ENGINE, SendWindowBase, SendWindowBase); unsigned short i; for (i=1; i <= MAX_WINDOW_SIZE/2; ++i) { unsigned Index1 = (i + (ULONG)RingBufferBase) % MAX_WINDOW_SIZE; unsigned Frag1 = (ULONG)SendWindowBase+i; if (Frag1 >= MAX_WINDOW_SIZE) { Frag1 -= MAX_WINDOW_SIZE; } if (!fUseTypeInfo) { dprintf(" %4x: %8lx %5hx %4hx |", Frag1, dgpe->FragmentRingBuffer[Index1].Offset, dgpe->FragmentRingBuffer[Index1].Length, dgpe->FragmentRingBuffer[Index1].SerialNumber ); } unsigned Index2 = (i+MAX_WINDOW_SIZE/2 + (ULONG)RingBufferBase) % MAX_WINDOW_SIZE; unsigned Frag2 = (ULONG)SendWindowBase+i+MAX_WINDOW_SIZE/2; if (Frag2 >= MAX_WINDOW_SIZE) { Frag2 -= MAX_WINDOW_SIZE; } if (!fUseTypeInfo) { dprintf(" %4x: %8lx %5hx %4hx \n", Frag2, dgpe->FragmentRingBuffer[Index2].Offset, dgpe->FragmentRingBuffer[Index2].Length, dgpe->FragmentRingBuffer[Index2].SerialNumber ); } } dprintf("\n"); } char * ClientState( DG_CCALL::DG_CLIENT_STATE State ) { switch (State) { case DG_CCALL::CallInit: return "init"; case DG_CCALL::CallQuiescent: return "quiescent"; case DG_CCALL::CallSend: return "sending"; case DG_CCALL::CallSendReceive: return "sendreceive"; case DG_CCALL::CallReceive: return "receiving"; case DG_CCALL::CallCancellingSend:return "cancel send"; case DG_CCALL::CallComplete: return "complete"; default: { static char scratch[40]; sprintf(scratch, "0x%lx", State); return scratch; } } } char * ServerState( DG_SCALL::CALL_STATE State ) { switch (State) { case DG_SCALL::CallInit: return "init"; case DG_SCALL::CallBeforeDispatch: return "receiving"; case DG_SCALL::CallDispatched: return "dispatched"; case DG_SCALL::CallAfterDispatch: return "after stub"; case DG_SCALL::CallSendingResponse: return "sending"; case DG_SCALL::CallComplete: return "complete"; default: { static char scratch[40]; sprintf(scratch, "0x%lx", State); return scratch; } } } char * PipeOp( PENDING_OPERATION Op ) { switch (Op) { case PWT_NONE: return "none"; case PWT_RECEIVE: return "receive"; case PWT_SEND: return "send"; case PWT_SEND_RECEIVE: return "send/recv"; default: { static char scratch[40]; sprintf(scratch, "0x%lx", Op); return scratch; } } } VOID do_dgcc( ULONG64 dgcc ) { ULONG64 State, PreviousState; ULONG64 tmp1; ULONG tmp2; dprintf("\n"); GET_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, State, State); GET_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, PreviousState, PreviousState); dprintf("state %-14s prev %-14s\n\n", ClientState((DG_CCALL::DG_CLIENT_STATE)State), ClientState((DG_CCALL::DG_CLIENT_STATE)PreviousState)); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, TimeStamp, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, TimeoutLimit, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, LastReceiveTime, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, AsyncStatus, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, CancelTime, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, EEInfo, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, ReceiveTimeout, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, WorkingCount, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, UnansweredRequestCount, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, PipeReceiveSize, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, Previous, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, Next, tmp1); PRINT_MEMBER(dgcc, DG_CCALL, RPCRT4!DG_CCALL, pAsync, tmp1); PRINT_MEMBER_BOOLEAN(dgcc, DG_CCALL, RPCRT4!DG_CCALL, StaticArgsSent, tmp1); PRINT_MEMBER_BOOLEAN(dgcc, DG_CCALL, RPCRT4!DG_CCALL, DelayedSendPending, tmp1); PRINT_MEMBER_BOOLEAN(dgcc, DG_CCALL, RPCRT4!DG_CCALL, AllArgsSent, tmp1); PRINT_MEMBER_BOOLEAN(dgcc, DG_CCALL, RPCRT4!DG_CCALL, LastSendTimedOut, tmp1); PRINT_MEMBER_BOOLEAN(dgcc, DG_CCALL, RPCRT4!DG_CCALL, CancelComplete, tmp1); PRINT_MEMBER_BOOLEAN(dgcc, DG_CCALL, RPCRT4!DG_CCALL, ForceAck, tmp1); PRINT_MEMBER_BOOLEAN(dgcc, DG_CCALL, RPCRT4!DG_CCALL, CancelPending, tmp1); PRINT_MEMBER_BOOLEAN(dgcc, DG_CCALL, RPCRT4!DG_CCALL, AutoReconnectOk, tmp1); dprintf("\n"); ULONG64 ActivityHint; GET_ADDRESS_OF(dgcc, DG_CCALL, RPCRT4!DG_CCALL, ActivityHint, ActivityHint, tmp2); do_dgpe(ActivityHint-AddressSize); } VOID do_dgep( ULONG64 ep ) { ULONG64 tmp0; ULONG tmp1; ULONG64 Stats; PRINT_MEMBER_BOOLEAN(ep, DG_ENDPOINT, RPCRT4!DG_ENDPOINT, Async, tmp0); PRINT_MEMBER(ep, DG_ENDPOINT, RPCRT4!DG_ENDPOINT, TimeStamp, tmp0); PRINT_MEMBER(ep, DG_ENDPOINT, RPCRT4!DG_ENDPOINT, Next, tmp0); PRINT_MEMBER(ep, DG_ENDPOINT, RPCRT4!DG_ENDPOINT, NumberOfCalls, tmp0); PRINT_MEMBER(ep, DG_ENDPOINT, RPCRT4!DG_ENDPOINT, TransportInterface, tmp0); PRINT_MEMBER_SYMBOL(ep, DG_ENDPOINT, RPCRT4!DG_ENDPOINT, TransportInterface, tmp0); GET_ADDRESS_OF(ep, DG_ENDPOINT, RPCRT4!DG_ENDPOINT, Stats, Stats, tmp1); PRINT_MEMBER(Stats, DG_ENDPOINT_STATS, RPCRT4!DG_ENDPOINT_STATS, PreferredPduSize, tmp0); PRINT_MEMBER(Stats, DG_ENDPOINT_STATS, RPCRT4!DG_ENDPOINT_STATS, MaxPduSize, tmp0); PRINT_MEMBER(Stats, DG_ENDPOINT_STATS, RPCRT4!DG_ENDPOINT_STATS, MaxPacketSize, tmp0); PRINT_MEMBER(Stats, DG_ENDPOINT_STATS, RPCRT4!DG_ENDPOINT_STATS, ReceiveBufferSize, tmp0); } VOID do_dgccn( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\nbase:\n"); ULONG64 ActivityNode; GET_ADDRESS_OF(qwAddr, DG_COMMON_CONNECTION, RPCRT4!DG_COMMON_CONNECTION, ActivityNode, ActivityNode, tmp2); ULONG64 Uuid; ULONG64 pPrev, pNext; GET_ADDRESS_OF(ActivityNode, UUID_HASH_TABLE_NODE, RPCRT4!UUID_HASH_TABLE_NODE, Uuid, Uuid, tmp2); GET_MEMBER(ActivityNode, UUID_HASH_TABLE_NODE, RPCRT4!UUID_HASH_TABLE_NODE, pPrev, pPrev); GET_MEMBER(ActivityNode, UUID_HASH_TABLE_NODE, RPCRT4!UUID_HASH_TABLE_NODE, pNext, pNext); dprintf(" activity ID "); PrintUuid(Uuid); dprintf(" next %I64x prev %I64x\n", pNext, pPrev ); PRINT_MEMBER(qwAddr, DG_COMMON_CONNECTION, RPCRT4!DG_COMMON_CONNECTION, TimeStamp, tmp1); PRINT_MEMBER(qwAddr, DG_COMMON_CONNECTION, RPCRT4!DG_COMMON_CONNECTION, TransportInterface, tmp1); PRINT_MEMBER(qwAddr, DG_COMMON_CONNECTION, RPCRT4!DG_COMMON_CONNECTION, ActiveSecurityContext, tmp1); PRINT_MEMBER(qwAddr, DG_COMMON_CONNECTION, RPCRT4!DG_COMMON_CONNECTION, ReferenceCount, tmp1); PRINT_MEMBER(qwAddr, DG_COMMON_CONNECTION, RPCRT4!DG_COMMON_CONNECTION, TransportInterface, tmp1); PRINT_MEMBER(qwAddr, DG_COMMON_CONNECTION, RPCRT4!DG_COMMON_CONNECTION, LowestActiveSequence, tmp1); PRINT_MEMBER(qwAddr, DG_COMMON_CONNECTION, RPCRT4!DG_COMMON_CONNECTION, LowestUnusedSequence, tmp1); PRINT_MEMBER(qwAddr, DG_COMMON_CONNECTION, RPCRT4!DG_COMMON_CONNECTION, CurrentPduSize, tmp1); PRINT_MEMBER(qwAddr, DG_COMMON_CONNECTION, RPCRT4!DG_COMMON_CONNECTION, RemoteWindowSize, tmp1); } VOID do_dgcn( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; do_dgccn(qwAddr); dprintf("\nclient:\n"); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, ActiveCallHead, tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, CurrentCall, tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, ActiveCallTail, tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, CachedCalls, tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, CachedCallCount, tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, ThreadId, tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, BindingHandle, tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, ServerResponded, tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, CallbackCompleted, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, fServerSupportsAsync, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, fSecurePacketReceived, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, fBusy, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, InConnectionTable, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, AckPending, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, AckOrphaned, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, PossiblyRunDown, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, fAutoReconnect,tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, Association, tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, AssociationKey, tmp1); PRINT_ADDRESS_OF(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, AuthInfo, tmp2); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, SecurityContextId, tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, TimeStamp, tmp1); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, LastScavengeTime, tmp1); PRINT_ADDRESS_OF(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, DelayedAckTimer, tmp2); PRINT_MEMBER(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, Next, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, fError, tmp1); PRINT_ADDRESS_OF(qwAddr, DG_CCONNECTION, RPCRT4!DG_CCONNECTION, Mutex, tmp2); } char * CallbackState( DG_SCONNECTION::CALLBACK_STATE State ) { switch (State) { case DG_SCONNECTION::NoCallbackAttempted: return "NoCallbackAttempted"; case DG_SCONNECTION::SetupInProgress: return "SetupInProgress"; case DG_SCONNECTION::MsConvWayAuthInProgress:return "MsConvWayAuthInProgress"; case DG_SCONNECTION:: ConvWayAuthInProgress:return " ConvWayAuthInProgress"; case DG_SCONNECTION::MsConvWay2InProgress: return "MsConvWay2InProgress"; case DG_SCONNECTION:: ConvWay2InProgress: return " ConvWay2InProgress"; case DG_SCONNECTION:: ConvWayInProgress: return " ConvWayInProgress"; case DG_SCONNECTION::CallbackSucceeded: return "CallbackSucceeded"; case DG_SCONNECTION::CallbackFailed: return "CallbackFailed"; default: { static char scratch[40]; sprintf(scratch, "0x%lx", State); return scratch; } } } VOID do_dgsn( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; do_dgccn(qwAddr); dprintf("\nserver:\n"); PRINT_MEMBER(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, ActiveCalls, tmp1); PRINT_MEMBER(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, CurrentCall, tmp1); PRINT_MEMBER(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, CachedCalls, tmp1); PRINT_MEMBER(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, pAddress, tmp1); PRINT_MEMBER(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, LastInterface, tmp1); PRINT_MEMBER(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, pAssocGroup, tmp1); PRINT_MEMBER(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, Next, tmp1); PRINT_MEMBER(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, ActivityHint, tmp1); PRINT_ADDRESS_OF(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, AuthInfo, tmp2); PRINT_MEMBER(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, MaxKeySeq, tmp1); PRINT_ADDRESS_OF(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, SecurityContextDict, tmp2); PRINT_ADDRESS_OF(qwAddr, DG_SCONNECTION, RPCRT4!DG_SCONNECTION, Callback, tmp2); if (!fUseTypeInfo) { uchar buff[sizeof(DG_SCONNECTION)]; GetData(qwAddr, buff, sizeof(DG_SCONNECTION)); DG_SCONNECTION * cn = (DG_SCONNECTION *) buff; dprintf( "\n" " status %-8lx binding %p datarep %-8lx \n" " scall %p client seq %-8lx \n" "\n" " token buffer %p token len %-8lx async state offset %x \n" " response buf %p response len %-8lx ThirdLegNeeded %s\n" " sec cxt %p credentials %p ksno %-8lx \n" " data index %-8lx \n", cn->Callback.Status, cn->Callback.Binding, cn->Callback.DataRep, cn->Callback.Call, cn->Callback.ClientSequence, cn->Callback.TokenBuffer, cn->Callback.TokenLength, offsetof(DG_SCONNECTION, Callback.AsyncState), cn->Callback.ResponseBuffer, cn->Callback.ResponseLength, BoolString(cn->Callback.ThirdLegNeeded), cn->Callback.SecurityContext, cn->Callback.Credentials, cn->Callback.KeySequence, cn->Callback.DataIndex ); } } VOID do_dgca( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, ReferenceCount, tmp1); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, BindingHandleReferences, tmp1); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, InternalTableIndex, tmp1); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, LastScavengeTime, tmp1); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, CurrentPduSize, tmp1); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, RemoteWindowSize, tmp1); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, TransportInterface, tmp1); dprintf("\n"); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, ServerAddress, tmp1); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, ServerBootTime, tmp1); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, ServerDataRep, tmp1); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, AssociationFlag, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, fServerSupportsAsync, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, fLoneBindingHandle, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, fErrorFlag, tmp1); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, LastReceiveTime, tmp1); PRINT_ADDRESS_OF(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, Mutex, tmp2); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, ResolvedEndpoint, tmp1); PRINT_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, KeepAliveHandle, tmp1); PRINT_ADDRESS_OF(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, ActiveConnections, tmp2); PRINT_ADDRESS_OF(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, InactiveConnections, tmp2); PRINT_ADDRESS_OF(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, InterfaceAndObjectDict, tmp2); ULONG64 pDceBinding; GET_MEMBER(qwAddr, DG_CASSOCIATION, RPCRT4!DG_CASSOCIATION, pDceBinding, pDceBinding); dprintf("DCE_BINDING:\n"); do_dcebinding(pDceBinding); } VOID do_dgsc( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); ULONG64 State; GET_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, State, State); dprintf("state - %-14s\n", ServerState((DG_SCALL::CALL_STATE)State)); ULONG64 PreviousState; GET_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, PreviousState, PreviousState); dprintf("prev state - %-14s\n", ServerState((DG_SCALL::CALL_STATE)State)); PRINT_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, TimeStamp, tmp1); PRINT_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, DispatchBuffer, tmp1); PRINT_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, AsyncStatus, tmp1); PRINT_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, pAsync, tmp1); ULONG64 PipeWaitType; GET_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, PipeWaitType, PipeWaitType); dprintf("pipe op - %-10s\n", PipeOp((PENDING_OPERATION)PipeWaitType)); PRINT_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, PipeWaitLength, tmp1); PRINT_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, PipeThreadId, tmp1); PRINT_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, Previous, tmp1); PRINT_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, Next, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, CallInProgress, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, CallWasForwarded, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, KnowClientAddress, tmp1); PRINT_MEMBER_BOOLEAN(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, TerminateWhenConvenient, tmp1); PRINT_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, AuthorizationService, tmp1); PRINT_MEMBER(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, Privileges, tmp1); dprintf("\n"); ULONG64 ActivityHint; GET_ADDRESS_OF(qwAddr, DG_SCALL, RPCRT4!DG_SCALL, ActivityHint, ActivityHint, tmp2); do_dgpe(ActivityHint-AddressSize); } VOID do_dgag( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; ULONG64 Node; GET_ADDRESS_OF(qwAddr, ASSOCIATION_GROUP, RPCRT4!ASSOCIATION_GROUP, Node, Node, tmp2); ULONG64 Uuid; GET_ADDRESS_OF(Node, UUID_HASH_TABLE_NODE, UUID_HASH_TABLE_NODE, Uuid, Uuid, tmp2); dprintf("\n" " CAG UUID: "); PrintUuid(Uuid); ULONG64 ReferenceCount; ULONG64 CurrentPduSize; ULONG64 RemoteWindowSize; ULONG64 AssociationID; ULONG64 CtxCollection; ULONG64 MutexAddr; GET_MEMBER(qwAddr, ASSOCIATION_GROUP, RPCRT4!ASSOCIATION_GROUP, ReferenceCount, ReferenceCount); GET_MEMBER(qwAddr, ASSOCIATION_GROUP, RPCRT4!ASSOCIATION_GROUP, CurrentPduSize, CurrentPduSize); GET_MEMBER(qwAddr, ASSOCIATION_GROUP, RPCRT4!ASSOCIATION_GROUP, RemoteWindowSize, RemoteWindowSize); GET_MEMBER(qwAddr, ASSOCIATION_GROUP, RPCRT4!ASSOCIATION_GROUP, AssociationID, AssociationID); GET_MEMBER(qwAddr, ASSOCIATION_GROUP, RPCRT4!ASSOCIATION_GROUP, CtxCollection, CtxCollection); GET_ADDRESS_OF(qwAddr, ASSOCIATION_GROUP, RPCRT4!ASSOCIATION_GROUP, Mutex, MutexAddr, tmp2); dprintf(" \n" " refs: %8.8x mutex at %p \n" " pdu length: %8.8x assoc ID: %x \n" " send window %8.8x CtxColl : %I64p \n", (ULONG)ReferenceCount, MutexAddr, (ULONG)CurrentPduSize, (ULONG)AssociationID, (ULONG)RemoteWindowSize, CtxCollection); } // Do some arm twisting to include pipendr.h and asyncndr. #define _NEWINTRP_ typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned long ulong; typedef unsigned int uint; #include "..\..\ndr20\pipendr.h" typedef void IAsyncManager; #define MAX_CONTEXT_HNDL_NUMBER 8 #include "..\..\ndr20\mulsyntx.h" #include "..\..\ndr20\asyncndr.h" char * PipeState( int State ) { static char buf[40]; if (State <= 3) { return ReceiveStates[State]; } sprintf(buf, "0x%x", State); return buf; } char * PipeFlags( unsigned short Flags ) { static char buf[80]; buf[0] = 0; if (Flags & NDR_IN_PIPE) { strcat(buf, "I "); } if (Flags & NDR_OUT_PIPE) { strcat(buf, "O "); } if (Flags & NDR_LAST_IN_PIPE) { strcat(buf, "LI "); } if (Flags & NDR_LAST_OUT_PIPE) { strcat(buf, "LO "); } if (Flags & NDR_OUT_ALLOCED) { strcat(buf, "ALLOC "); } if (Flags & 0xffe0) { char Excess[10]; sprintf(Excess, "%hx ", Flags & 0xffe0); strcat(buf, Excess); } return buf; } char * PipeStatusStrings[] = { "QUIET", "IN", "OUT", "DRAIN" }; char * PipeStatus( unsigned short Status ) { static char buf[40]; if (Status <= 3) { return PipeStatusStrings[Status]; } sprintf(buf, "0x%x", Status); return buf; } void do_pipestate( ULONG64 qwAddr ) { ULONG64 ElemsInChunk; ULONG64 ElemAlign; ULONG64 ElemWireSize; ULONG64 ElemMemSize; ULONG64 PartialBufferSize; ULONG64 PartialElem; ULONG64 PartialElemSize; ULONG64 PartialOffset; ULONG64 CurrentState; ULONG64 EndOfPipe; GET_MEMBER(qwAddr, NDR_PIPE_STATE, RPCRT4!NDR_PIPE_STATE, ElemsInChunk, ElemsInChunk); GET_MEMBER(qwAddr, NDR_PIPE_STATE, RPCRT4!NDR_PIPE_STATE, ElemAlign, ElemAlign); GET_MEMBER(qwAddr, NDR_PIPE_STATE, RPCRT4!NDR_PIPE_STATE, ElemWireSize, ElemWireSize); GET_MEMBER(qwAddr, NDR_PIPE_STATE, RPCRT4!NDR_PIPE_STATE, ElemMemSize, ElemMemSize); GET_MEMBER(qwAddr, NDR_PIPE_STATE, RPCRT4!NDR_PIPE_STATE, PartialBufferSize, PartialBufferSize); GET_MEMBER(qwAddr, NDR_PIPE_STATE, RPCRT4!NDR_PIPE_STATE, PartialElem, PartialElem); GET_MEMBER(qwAddr, NDR_PIPE_STATE, RPCRT4!NDR_PIPE_STATE, PartialElemSize, PartialElemSize); GET_MEMBER(qwAddr, NDR_PIPE_STATE, RPCRT4!NDR_PIPE_STATE, PartialOffset, PartialOffset); GET_MEMBER(qwAddr, NDR_PIPE_STATE, RPCRT4!NDR_PIPE_STATE, CurrentState, CurrentState); ULONG tmp2; GET_ADDRESS_OF(qwAddr, NDR_PIPE_STATE, RPCRT4!NDR_PIPE_STATE, PartialOffset, EndOfPipe, tmp2); EndOfPipe += 4; dprintf("\n"); dprintf(" elems in chunk %8lx partial buf size %8lx state %s\n", (ULONG)ElemsInChunk, (ULONG)PartialBufferSize, PipeState((ULONG)CurrentState) ); dprintf(" elem align %8lx partial element %8lx end of pipe bits %I64x\n", (ULONG)ElemAlign, (ULONG)PartialElem, EndOfPipe ); dprintf(" elem wire size %8lx partial elem size %8lx \n", (ULONG)ElemWireSize, (ULONG)PartialElemSize ); dprintf(" elem mem size %8lx partial offset %8lx \n", (ULONG)ElemMemSize, (ULONG)PartialOffset ); } void do_pipedesc( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, CurrentPipe, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, InPipes, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, OutPipes, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, TotalPipes, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, Flags, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, PipeVersion, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, pPipeMsg, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, DispatchBuffer, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, ChainingBuffer, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, DispatchBufferLength, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, ChainingBufferSize, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, LastPartialBuffer, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, BufferSave, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, LastPartialSize, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, LengthSave, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, LeftoverSize, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, RuntimeState, tmp1); PRINT_ADDRESS_OF(qwAddr, NDR_PIPE_DESC, RPCRT4!NDR_PIPE_DESC, Leftover, tmp2); do_pipestate(tmp1); } void do_pipearg( ULONG64 qwAddr ) { ULONG64 tmp1; dprintf("\n"); PRINT_MEMBER(qwAddr, GENERIC_PIPE_TYPE, RPCRT4!GENERIC_PIPE_TYPE, pfnPull, tmp1); PRINT_MEMBER(qwAddr, GENERIC_PIPE_TYPE, RPCRT4!GENERIC_PIPE_TYPE, pfnPush, tmp1); PRINT_MEMBER(qwAddr, GENERIC_PIPE_TYPE, RPCRT4!GENERIC_PIPE_TYPE, pfnAlloc, tmp1); PRINT_MEMBER(qwAddr, GENERIC_PIPE_TYPE, RPCRT4!GENERIC_PIPE_TYPE, pState, tmp1); } void do_pipemsg( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER(qwAddr, NDR_PIPE_MESSAGE, RPCRT4!NDR_PIPE_MESSAGE, Signature, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_MESSAGE, RPCRT4!NDR_PIPE_MESSAGE, PipeId, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_MESSAGE, RPCRT4!NDR_PIPE_MESSAGE, pPipeObject, tmp1); ULONG64 pPipeObject = tmp1; PRINT_MEMBER(qwAddr, NDR_PIPE_MESSAGE, RPCRT4!NDR_PIPE_MESSAGE, pStubMsg, tmp1); PRINT_MEMBER(qwAddr, NDR_PIPE_MESSAGE, RPCRT4!NDR_PIPE_MESSAGE, pTypeFormat, tmp1); ULONG64 PipeStatusVal; ULONG64 PipeFlagsVal; GET_MEMBER(qwAddr, NDR_PIPE_MESSAGE, RPCRT4!NDR_PIPE_MESSAGE, PipeStatus, PipeStatusVal); GET_MEMBER(qwAddr, NDR_PIPE_MESSAGE, RPCRT4!NDR_PIPE_MESSAGE, PipeFlags, PipeFlagsVal); dprintf("pipe status %5s\n", PipeStatus((unsigned short)PipeStatusVal)); dprintf("pipe flags %s\n", PipeFlags((unsigned short)PipeStatusVal)); do_pipearg(pPipeObject ); } void async_flags( NDR_ASYNC_CALL_FLAGS flags ) { dprintf(" flags %4x: ", *(unsigned short *)&flags ); if ( flags.ValidCallPending ) dprintf(" call pending, " ); if ( flags.ErrorPending ) dprintf(" err pending, " ); if ( flags.BadStubData ) dprintf(" BSD, " ); if ( flags.RuntimeCleanedUp ) dprintf(" rt cleaned, " ); if ( flags.HandlelessObjCall ) dprintf(" autocomplete, " ); if ( flags.Unused ) dprintf(" Unused %4x ", flags.Unused ); dprintf("-\n" ); } char * AsyncPhaseString[5] = { "zero", "prep : initialized", "set : (cl) after get buffer and ( cl | srv) register call", "call : cl after marshaling, calling send", "error : exception taken" }; void async_stub_phase( unsigned short phase ) { dprintf(" phase %4x: ", phase ); if ( 0 <= phase && phase < 5 ) dprintf(" %s\n", AsyncPhaseString[ phase ] ); else dprintf(" unknown??\n" ); } typedef struct _NDR_ASYNC_OBJ_HANDLE { void * pIAMvtble; void * pICMvtble; NDR_ASYNC_MESSAGE * _pAsyncMsg; unsigned long _Lock; unsigned long _Signature; GUID _iid; void * _InnerUnknown; unsigned long _iRef; void * _pParent; void * _pControl; void * _pSyncInner; unsigned long _fAutoComplete; } NDR_ASYNC_OBJ_HANDLE; void do_asyncdcom( ULONG64 qwAddr ) { if (fUseTypeInfo) { dprintf("Can't dump NDR_ASYNC_OBJ_HANDLE when using type info\n"); } else { BOOL b; char block[sizeof(NDR_ASYNC_OBJ_HANDLE)]; b = GetData(qwAddr, &block, sizeof(block)); if ( !b ) { dprintf("can't read %p\n", qwAddr); return; } NDR_ASYNC_OBJ_HANDLE * msg = (NDR_ASYNC_OBJ_HANDLE *) block; dprintf("\n"); dprintf(" pIAMvtble %p pICMvtble %p asyncmsg %p lock %8lx\n", msg->pIAMvtble, msg->pICMvtble, msg->_pAsyncMsg, msg->_Lock ); dprintf(" innerpUnk %p iref %8lx pParent %p pControl %p\n", msg->_InnerUnknown,msg->_iRef, msg->_pParent,msg->_pControl ); dprintf(" Signature %8lx iid ", msg->_Signature ); PrintUuidLocal( & msg->_iid );dprintf("\n"); dprintf(" innerSync %p autocompl %d\n", msg->_pSyncInner,msg->_fAutoComplete ); } } void do_asyncrpc( ULONG64 qwAddr ) { ULONG64 tmp1; dprintf("\n"); PRINT_MEMBER(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, Size, tmp1); PRINT_MEMBER(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, Signature, tmp1); PRINT_MEMBER(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, Lock, tmp1); PRINT_MEMBER(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, Flags, tmp1); PRINT_MEMBER(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, StubInfo, tmp1); PRINT_MEMBER(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, UserInfo, tmp1); PRINT_MEMBER(qwAddr, RPC_ASYNC_STATE, RPCRT4!RPC_ASYNC_STATE, RuntimeInfo, tmp1); } void do_asyncmsg( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER(qwAddr, NDR_ASYNC_MESSAGE, RPCRT4!NDR_ASYNC_MESSAGE, Signature, tmp1); PRINT_MEMBER(qwAddr, NDR_ASYNC_MESSAGE, RPCRT4!NDR_ASYNC_MESSAGE, Version, tmp1); PRINT_MEMBER(qwAddr, NDR_ASYNC_MESSAGE, RPCRT4!NDR_ASYNC_MESSAGE, AsyncHandle, tmp1); PRINT_MEMBER(qwAddr, NDR_ASYNC_MESSAGE, RPCRT4!NDR_ASYNC_MESSAGE, ProcContext, tmp1); ULONG64 Flags; GET_MEMBER(qwAddr, NDR_ASYNC_MESSAGE, RPCRT4!NDR_ASYNC_MESSAGE, Flags, Flags); async_flags( *((NDR_ASYNC_CALL_FLAGS*)&Flags) ); ULONG64 StubPhase; GET_MEMBER(qwAddr, NDR_ASYNC_MESSAGE, RPCRT4!NDR_ASYNC_MESSAGE, StubPhase, StubPhase); async_stub_phase( (unsigned short) StubPhase ); ULONG64 StubMsg; GET_MEMBER(qwAddr, NDR_ASYNC_MESSAGE, RPCRT4!NDR_ASYNC_MESSAGE, StubMsg, StubMsg); do_stubmsg( StubMsg ); } // // Datagram stuff // char * PacketFlagStrings[8] = { "forwarded ", "lastfrag ", "frag ", "nofack ", "maybe ", "idem ", "broadcast ", "flags-0x80 " }; char * PacketFlag2Strings[8] = { "fragmented ", "cancel-pending ", "flags2-0x04 ", "flags2-0x08 ", "flags2-0x10 ", "flags2-0x20 ", "flags2-0x40 ", "flags2-0x80 " }; char * PrintPacketFlags( unsigned char PacketFlags1, unsigned char PacketFlags2 ) { static char buf[160]; unsigned char Flags; unsigned i; buf[0] = 0; Flags = PacketFlags1; for (i=0; i < 8; i++) { if (Flags & 1) { strcat(buf, PacketFlagStrings[i]); } Flags >>= 1; } Flags = PacketFlags2; for (i=0; i < 8; i++) { if (Flags & 1) { strcat(buf, PacketFlag2Strings[i]); } Flags >>= 1; } return buf; } char * PacketTypes[] = { "REQ ", "PING", "RESP", "FLT ", "WORK", "NOCA", "REJ ", "ACK ", "QUIT", "FACK", "QACK" }; char * PrintPacketType( unsigned char PacketType ) { static char buf[40]; if (PacketType < sizeof(PacketTypes)/sizeof(PacketTypes[0])) { return PacketTypes[PacketType]; } sprintf(buf, "illegal packet type %x ", PacketType); return buf; } VOID do_dgpkt( ULONG64 p ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER(p, DG_PACKET, RPCRT4!DG_PACKET, MaxDataLength, tmp1); PRINT_MEMBER(p, DG_PACKET, RPCRT4!DG_PACKET, TimeReceived, tmp1); PRINT_MEMBER(p, DG_PACKET, RPCRT4!DG_PACKET, DataLength, tmp1); PRINT_MEMBER(p, DG_PACKET, RPCRT4!DG_PACKET, pNext, tmp1); PRINT_MEMBER(p, DG_PACKET, RPCRT4!DG_PACKET, pPrevious, tmp1); ULONG64 Header; GET_ADDRESS_OF(p, DG_PACKET, RPCRT4!DG_PACKET, Header, Header, tmp2); do_dgpkthdr(Header); } VOID do_dgpkthdr( ULONG64 h ) { ULONG64 tmp1; ULONG tmp2; dprintf("\n"); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, PacketType, tmp1); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, RpcVersion, tmp1); ULONG64 PacketFlags; ULONG64 PacketFlags2; GET_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, PacketFlags, PacketFlags); GET_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, PacketFlags2, PacketFlags2); dprintf("flags: %s\n", PrintPacketFlags((unsigned char)PacketFlags, (unsigned char)PacketFlags2)); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, FragmentNumber, tmp1); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, PacketBodyLen, tmp1); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, SerialLo, tmp1); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, DataRep, tmp1); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, ServerBootTime, tmp1); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, AuthProto, tmp1); dprintf(" activity "); ULONG64 ActivityId; GET_ADDRESS_OF(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, ActivityId, ActivityId, tmp2); PrintUuid(ActivityId); dprintf("\n"); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, ActivityHint, tmp1); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, SequenceNumber, tmp1); dprintf(" interface "); ULONG64 InterfaceId; GET_ADDRESS_OF(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, InterfaceId, InterfaceId, tmp2); PrintUuid(InterfaceId); dprintf("\n"); ULONG64 InterfaceVersion; GET_ADDRESS_OF(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, InterfaceVersion, InterfaceVersion, tmp2); PRINT_MEMBER(h, _RPC_VERSION, RPCRT4!_RPC_VERSION, MajorVersion, tmp1); PRINT_MEMBER(h, _RPC_VERSION, RPCRT4!_RPC_VERSION, MinorVersion, tmp1); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, InterfaceHint, tmp1); PRINT_MEMBER(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, OperationNumber, tmp1); PRINT_ADDRESS_OF(h, _NCA_PACKET_HEADER, RPCRT4!_NCA_PACKET_HEADER, ObjectId, tmp2); dprintf("\n"); } void do_assoctable( ULONG64 qwAddr ) { ULONG64 tmp1; ULONG tmp2; dprintf("DG_ASSOCIATION_TABLE at 0x%I64x:\n", qwAddr); ULONG64 CasUuid; ULONG64 fCasUuidReady; GET_MEMBER(qwAddr, DG_ASSOCIATION_TABLE, RPCRT4!DG_ASSOCIATION_TABLE, CasUuid, CasUuid); GET_MEMBER(qwAddr, DG_ASSOCIATION_TABLE, RPCRT4!DG_ASSOCIATION_TABLE, fCasUuidReady, fCasUuidReady); dprintf(" CAS: "); PrintUuid( CasUuid ); dprintf(", %svalid\n", (ULONG)fCasUuidReady ? "" : "not "); dprintf("\n"); PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, DG_ASSOCIATION_TABLE, RPCRT4!DG_ASSOCIATION_TABLE, Mutex, "&Mutex (CSharedLock)", tmp2); ULONG64 Associations; ULONG64 AssociationsLength; GET_MEMBER(qwAddr, DG_ASSOCIATION_TABLE, RPCRT4!DG_ASSOCIATION_TABLE, Associations, Associations); GET_MEMBER(qwAddr, DG_ASSOCIATION_TABLE, RPCRT4!DG_ASSOCIATION_TABLE, AssociationsLength, AssociationsLength); dprintf("association array at 0x%I64x, %x elements\n", Associations, AssociationsLength); } char * strtok( char *String ) { char * Word; static char * End; if (String) { Word = String; } else if (!End) { return 0; } else { Word = End+1; } while (*Word == ' ' || *Word == '\t') { ++Word; } if (!*Word) { End = 0; return 0; } End = Word; while (*End && *End != ' ' && *End != '\t') { ++End; } if (!*End) { End = 0; } else { *End = 0; } return Word; } BOOL IsMember( char Item, char * List ) { BOOL Mask = FALSE; if (List[0] == '~') { Mask = TRUE; } while (*List) { if (Item == *List) { return TRUE ^ Mask; } ++List; } return FALSE ^ Mask; } BOOL FetchEvent( IN ULONG_PTR RpcEvents, IN unsigned Index, IN struct RPC_EVENT * Entry ) { return GetData(RpcEvents + Index * sizeof(struct RPC_EVENT), Entry, sizeof(struct RPC_EVENT)); } BOOL FetchEventAddress( IN ULONG64 RpcEvents, IN int Index, IN PULONG64 EntryAddress ) { static ULONG EntrySize = 0; if (EntrySize == 0) { EntrySize = GetTypeSize("RPCRT4!RPC_EVENT"); if (EntrySize == 0) { return FALSE; } } *EntryAddress = RpcEvents + Index * EntrySize; return TRUE; } BOOL DoesEntryMatch( IN struct RPC_EVENT * Entry, IN char * Subjects, IN char * verbs, IN DWORD thread, IN ULONG_PTR addr, IN ULONG_PTR obj_addr ) { if (!Entry->Subject) { return FALSE; } if (Subjects && !IsMember(Entry->Subject, Subjects)) { return FALSE; } if (verbs && !IsMember(Entry->Verb, verbs)) { return FALSE; } if (thread && Entry->Thread != (unsigned short) thread) { return FALSE; } if (addr && Entry->SubjectPointer != (void *) addr) { return FALSE; } if (obj_addr && Entry->ObjectPointer != (void *) obj_addr) { return FALSE; } return TRUE; } BOOL DoesEntryAddressMatch( IN ULONG64 Entry, IN char * Subjects, IN char * verbs, IN DWORD thread, IN ULONG64 addr, IN ULONG64 obj_addr ) { ULONG64 tmp; char item; GET_MEMBER_NORET_NOSPEW(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, Subject, tmp); if (!tmp) { return FALSE; } if (Subjects && !IsMember((char)tmp, Subjects)) { return FALSE; } GET_MEMBER_NORET_NOSPEW(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, Verb, tmp); if (verbs && !IsMember((char)tmp, verbs)) { return FALSE; } GET_MEMBER_NORET_NOSPEW(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, Thread, tmp); if (thread && tmp != (unsigned short) thread) { return FALSE; } GET_MEMBER_NORET_NOSPEW(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, SubjectPointer, tmp); if (addr && tmp != addr) { return FALSE; } GET_MEMBER_NORET_NOSPEW(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, ObjectPointer, tmp); if (obj_addr && tmp != obj_addr) { return FALSE; } return TRUE; } char * DgPacketTypes[] = { "REQ", "PING", "RESP", "FAULT", "WORKING", "NOCALL", "REJECT", "ACK", "QUIT", "FACK", "QUACK", "BIND", "BIND-ACK", "BIND_NAK", "ALTER-CXT", "ALTER-RESP", "AUTH-3", "SHUTDOWN", "CANCEL", "ORPHAN" }; char * ScallStates[] = { "Init", "BeforeDispatch", "Dispatched", "DispatchedWithCompleteData", "AfterDispatch", "SendingResponse", "Complete" }; char * CcallStates[] = { "Init", "Quiescent", "Send", "SendReceive", "Receive", "CancellingSend", "Complete" }; char * HandleTypeStrings[] = { "wmsg_cas ", "wmsg_handle ", "dg_ccall ", "dg_scall ", "dg_binding ", "osf_ccall ", "osf_scall ", "osf_cconn ", "osf_sconn ", "osf_cassoc ", "osf_assoc ", "osf_address ", "lrpc_ccall ", "lrpc_scall ", "lrpc_cassoc ", "lrpc_sassoc ", "lrpc_binding ", "svr_binding ", "dg_cconn ", "dg_sconn ", "osf_binding ", "dg_callback ", "dg_address ", "lrpc_address ", "dg_assoc " }; char * GetHandleType( void * Value ) { int i; for (i=0; i < sizeof(HandleTypeStrings)/sizeof(char *); ++i) { if ((1UL << i) == PtrToUlong(Value)) { return HandleTypeStrings[i]; } } static char scratch[40]; sprintf(scratch, "refobj %p", Value); return scratch; } char * GetHandleTypeAddr( ULONG64 Pointer ) { int i; ULONG64 Value; for (i=0; i < sizeof(HandleTypeStrings)/sizeof(char *); ++i) { ReadPtr(Pointer, &Value); if ((1UL << i) == Pointer) { return HandleTypeStrings[i]; } } static char scratch[40]; sprintf(scratch, "refobj %.6x", Pointer); return scratch; } int PrintEntry( IN struct RPC_EVENT * Entry, IN ULONG index, IN BOOL ShowStack ) { char * Subject; char * Verb; BOOL Printed = FALSE; switch (Entry->Subject) { case SU_HANDLE : Subject = "binding "; break; case SU_CCONN : Subject = "cconn "; break; case SU_SCONN : Subject = "sconn "; break; case SU_CASSOC : Subject = "cassoc "; break; case SU_SASSOC : Subject = "sassoc "; break; case SU_CCALL : Subject = "ccall "; break; case SU_SCALL : Subject = "scall "; break; case SU_PACKET : Subject = "packet "; break; case SU_CENDPOINT: Subject = "endpnt "; break; case SU_ENGINE : Subject = " call "; break; case SU_ASSOC : Subject = " assoc "; break; case SU_MUTEX : Subject = "mutex "; break; case SU_STABLE : Subject = "sc tabl "; break; case SU_BCACHE : Subject = "bcache "; break; case SU_HEAP : Subject = "heap "; break; case SU_THREAD : Subject = "thread "; break; case SU_EVENT : Subject = "event "; break; case SU_TRANS_CONN:Subject = "trans conn "; break; case SU_ADDRESS : Subject = "address "; break; case SU_EXCEPT : Subject = "exception "; break; case SU_REFOBJ : { Subject = GetHandleType(Entry->ObjectPointer); break; } case SU_CTXHANDLE: Subject = "ctx handle "; break; default: { static char string[4]; Subject = string; Subject[0] = '\"'; Subject[1] = Entry->Subject; Subject[2] = '\"'; Subject[3] = '\0'; break; } } dprintf("%5x: %06.6d.%03.3d/%-4x %s %p ", index, Entry->Time /1000, Entry->Time % 1000, Entry->Thread, Subject, Entry->SubjectPointer); Verb = "(extension bug)"; switch (Entry->Verb) { case EV_CREATE : Verb = "create "; break; case EV_DELETE : Verb = "delete "; break; case EV_START : Verb = "active "; break; case EV_STOP : Verb = "inactive "; break; case EV_INC : Verb = "ref++ "; break; case EV_DEC : Verb = "ref-- "; break; case EV_ACK : Verb = "ack sent "; break; case EV_NOTIFY : Verb = "notify "; break; case EV_APC : Verb = "APC fired"; break; case EV_RESOLVED : Verb = "resolved "; break; case EV_REMOVED : Verb = "removed "; break; case EV_CLEANUP : Verb = "cleanup "; break; case EV_SEC_INIT1 : Verb = "init SC 1"; break; case EV_SEC_INIT3 : Verb = "init SC 3"; break; case EV_SEC_ACCEPT1 : Verb = "accptSC 1"; break; case EV_SEC_ACCEPT3 : Verb = "accptSC 3"; break; case EV_STATUS: { if (Entry->Subject != SU_EXCEPT) { if (Entry->ObjectPointer) { dprintf("status %lx, location %d", Entry->Data, Entry->ObjectPointer); } else { dprintf("status %lx", Entry->Data); } Printed = TRUE; break; } else { dprintf("exception info: %lx, %lx, %lx", Entry->SubjectPointer, Entry->ObjectPointer, Entry->Data); Printed = TRUE; break; } } case EV_DISASSOC : Verb = "disassoc "; break; case EV_STATE: { char * state = "----"; if (Entry->Subject == SU_CCALL) { if (Entry->Data < DG_CCALL::CallInit || Entry->Data > DG_CCALL::CallComplete ) { dprintf("unknown state 0x%x", Entry->Data); Printed = TRUE; } else { state = CcallStates[Entry->Data - DG_CCALL::CallInit]; } } else { if (Entry->Data < DG_SCALL::CallInit || Entry->Data > DG_SCALL::CallComplete ) { dprintf("unknown state 0x%x", Entry->Data); Printed = TRUE; } else { state = ScallStates[Entry->Data - DG_SCALL::CallInit]; } } if (!Printed) { dprintf("state %s", state); Printed = TRUE; } break; } case EV_POP : Verb = "pop "; break; case EV_PUSH : Verb = "push "; break; case EV_PKT_IN: { unsigned short frag = (unsigned short) (Entry->Data); unsigned short ptype = (unsigned short) (Entry->Data >> 16); char * ptypestring; if (ptype >= sizeof(DgPacketTypes)/sizeof(DgPacketTypes[0])) { dprintf("recv pkt unknown type 0x%hx", ptype); Printed = TRUE; } else { ptypestring = DgPacketTypes[ptype]; } if (!Printed) { if (Entry->ObjectPointer) { dprintf("recv pkt %s frag %hx, location %d", ptypestring, frag, Entry->ObjectPointer); } else { dprintf("recv pkt %s frag/len %hx", ptypestring, frag); } Printed = TRUE; } break; } case EV_BUFFER_IN : Verb = "buf in"; break; case EV_BUFFER_OUT: Verb = "buf out"; break; case EV_TRANSFER: Verb = "xfer call"; break; case EV_DROP: Verb = "dropped "; break; case EV_DELAY: Verb = "delayed "; break; case EV_CALLBACK: Verb = "callback "; break; default: { static char string[4]; Verb = string; Verb[0] = '\"'; Verb[1] = Entry->Verb; Verb[2] = '\"'; Verb[3] = '\0'; break; } case 'p': { if (Entry->Subject == SU_STABLE) { Verb = "prune "; } else { DWORD buf[2]; buf[0] = (DWORD) Entry->Data; buf[1] = 0; dprintf("proc %s %p", (char *) buf, Entry->ObjectPointer); Printed = TRUE; } break; } case EV_PKT_OUT: { unsigned short frag = (unsigned short) (Entry->Data); unsigned short ptype = (unsigned short) (Entry->Data >> 16); char * ptypestring; if (ptype >= sizeof(DgPacketTypes)/sizeof(DgPacketTypes[0])) { ptypestring = "???"; } else { ptypestring = DgPacketTypes[ptype]; } dprintf("sent pkt %s frag/len %hx", ptypestring, frag); Printed = TRUE; break; } } if (!Printed) { dprintf("%s %p %p", Verb, Entry->ObjectPointer, Entry->Data); } dprintf("\n"); int LinesPrinted = 1; if (ShowStack && Entry->EventStackTrace[0]) { int i; for (i = 0; Entry->EventStackTrace[i] && i < STACKTRACE_DEPTH; i++) { dprintf(" "); do_symbol((ULONG_PTR) Entry->EventStackTrace[i]); ++LinesPrinted; } } return LinesPrinted; } int PrintEntryAddress( IN ULONG64 Entry, IN int index, IN BOOL ShowStack ) { char * Subject; char * Verb; BOOL Printed = FALSE; ULONG tmp; ULONG64 Time = 0; ULONG64 Thread = 0; ULONG64 SubjectPointer = 0; ULONG64 ObjectPointer = 0; ULONG64 SubjectData = 0; ULONG64 VerbData = 0; ULONG64 Data = 0; ULONG64 EventStackTraceAddress =0 ; ULONG64 EventStackTrace_0 = 0; GET_MEMBER_NORET(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, Time, Time); GET_MEMBER_NORET(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, Thread, Thread); GET_MEMBER_NORET(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, SubjectPointer, SubjectPointer); GET_MEMBER_NORET(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, Subject, SubjectData); GET_MEMBER_NORET(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, ObjectPointer, ObjectPointer); GET_MEMBER_NORET(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, Verb, VerbData); GET_MEMBER_NORET(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, Data, Data); GET_ADDRESS_OF(Entry, RPC_EVENT, RPCRT4!RPC_EVENT, EventStackTrace, EventStackTraceAddress, tmp); ReadPtr(EventStackTraceAddress, &EventStackTrace_0); switch ((char)SubjectData) { case SU_HANDLE : Subject = "binding "; break; case SU_CCONN : Subject = "cconn "; break; case SU_SCONN : Subject = "sconn "; break; case SU_CASSOC : Subject = "cassoc "; break; case SU_SASSOC : Subject = "sassoc "; break; case SU_CCALL : Subject = "ccall "; break; case SU_SCALL : Subject = "scall "; break; case SU_PACKET : Subject = "packet "; break; case SU_CENDPOINT: Subject = "endpnt "; break; case SU_ENGINE : Subject = " call "; break; case SU_ASSOC : Subject = " assoc "; break; case SU_MUTEX : Subject = "mutex "; break; case SU_STABLE : Subject = "sc tabl "; break; case SU_BCACHE : Subject = "bcache "; break; case SU_HEAP : Subject = "heap "; break; case SU_THREAD : Subject = "thread "; break; case SU_EVENT : Subject = "event "; break; case SU_TRANS_CONN:Subject = "trans conn "; break; case SU_ADDRESS : Subject = "address "; break; case SU_EXCEPT : Subject = "exception "; break; case SU_REFOBJ : { Subject = GetHandleTypeAddr(ObjectPointer); break; } case SU_CTXHANDLE: Subject = "ctx handle "; break; case SU_EEINFO : Subject = "EEInfo "; break; default: { static char string[4]; Subject = string; Subject[0] = '\"'; Subject[1] = (char)SubjectData; Subject[2] = '\"'; Subject[3] = '\0'; break; } } dprintf("%5x: %06.6d.%03.3d/%-4x %s %I64p ", index, (ULONG)Time / 1000, (ULONG)Time % 1000, (ULONG)Thread, Subject, SubjectPointer); if (SubjectData != SU_EEINFO) { Verb = "(extension bug)"; switch ((char)VerbData) { case EV_CREATE : Verb = "create "; break; case EV_DELETE : Verb = "delete "; break; case EV_START : Verb = "active "; break; case EV_STOP : Verb = "inactive "; break; case EV_INC : Verb = "ref++ "; break; case EV_DEC : Verb = "ref-- "; break; case EV_ACK : Verb = "ack sent "; break; case EV_NOTIFY : Verb = "notify "; break; case EV_APC : Verb = "APC fired"; break; case EV_RESOLVED : Verb = "resolved "; break; case EV_REMOVED : Verb = "removed "; break; case EV_CLEANUP : Verb = "cleanup "; break; case EV_SEC_INIT1 : Verb = "init SC 1"; break; case EV_SEC_INIT3 : Verb = "init SC 3"; break; case EV_SEC_ACCEPT1 : Verb = "accptSC 1"; break; case EV_SEC_ACCEPT3 : Verb = "accptSC 3"; break; case EV_STATUS: { if ((ULONG)SubjectData != SU_EXCEPT) { if (VerbData) { dprintf("status %lx, location %d", (ULONG)Data, (ULONG)ObjectPointer); } else { dprintf("status %lx", (ULONG)Data); } Printed = TRUE; break; } else { dprintf("exception info: %lx, %lx, %lx", (ULONG)SubjectPointer, (ULONG)ObjectPointer, (ULONG)Data); Printed = TRUE; break; } } case EV_DISASSOC : Verb = "disassoc "; break; case EV_STATE: { char * state = "----"; if ((ULONG)SubjectData == SU_CCALL) { if (Data < GetExpression("rpcrt4!DG_CCALL__CallInit") || Data > GetExpression("rpcrt4!DG_CCALL__CallComplete")) { dprintf("unknown state 0x%x", Data); Printed = TRUE; } else { state = CcallStates[Data - GetExpression("rpcrt4!DG_CCALL__CallInit")]; } } else { if (Data < GetExpression("RPCRT4!DG_SCALL__CallInit") || Data > GetExpression("RPCRT4!DG_SCALL__CallComplete")) { dprintf("unknown state 0x%x", Data); Printed = TRUE; } else { state = ScallStates[Data - GetExpression("RPCRT4!DG_SCALL__CallInit")]; } } if (!Printed) { dprintf("state %s", state); Printed = TRUE; } break; } case EV_POP : Verb = "pop "; break; case EV_PUSH : Verb = "push "; break; case EV_PKT_IN: { unsigned short frag = (unsigned short) (Data); unsigned short ptype = (unsigned short) (Data >> 16); char * ptypestring; if (ptype >= sizeof(DgPacketTypes)/sizeof(DgPacketTypes[0])) { dprintf("recv pkt unknown type 0x%hx", ptype); Printed = TRUE; } else { ptypestring = DgPacketTypes[ptype]; } if (!Printed) { if (ObjectPointer) { dprintf("recv pkt %s frag %hx, location %d", ptypestring, frag, (ULONG)ObjectPointer); } else { dprintf("recv pkt %s frag/len %hx", ptypestring, frag); } Printed = TRUE; } break; } case EV_BUFFER_IN : Verb = "buf in"; break; case EV_BUFFER_OUT: Verb = "buf out"; break; case EV_TRANSFER: Verb = "xfer call"; break; case EV_DROP: Verb = "dropped "; break; case EV_DELAY: Verb = "delayed "; break; case EV_CALLBACK: Verb = "callback "; break; default: { static char string[10]; Verb = string; Verb[0] = '\"'; Verb[1] = (char)VerbData; Verb[2] = '\"'; Verb[3] = '\0'; break; } case 'p': { if (SubjectData == SU_STABLE) { Verb = "prune "; } else { DWORD buf[2]; buf[0] = (DWORD) Data; buf[1] = 0; dprintf("proc %s %I64x", (char *) buf, ObjectPointer); Printed = TRUE; } break; } case EV_PKT_OUT: { unsigned short frag = (unsigned short) (Data); unsigned short ptype = (unsigned short) ((Data >> 16) & 0xFF); unsigned short opnum = (unsigned short) (Data >> 24); ULONG CallId = (ULONG)ObjectPointer; char * ptypestring; if (ptype >= sizeof(DgPacketTypes)/sizeof(DgPacketTypes[0])) { ptypestring = "???"; } else { ptypestring = DgPacketTypes[ptype]; } if (opnum) { dprintf("sent p %s fr/len %hx op# %d cid %d", ptypestring, frag, opnum, CallId); } else { dprintf("sent p %s fr/len %hx cid %d", ptypestring, frag, CallId); } Printed = TRUE; break; } } } else { // this is an eeinfo record dprintf("GC %d St %d DL %d P#1 %d", (ULONG)VerbData, (ULONG)SubjectPointer, (ULONG)ObjectPointer, (ULONG)Data); Printed = TRUE; } if (!Printed) { dprintf("%s %I64p %I64p", Verb, ObjectPointer, Data); } dprintf("\n"); int LinesPrinted = 1; if (ShowStack && EventStackTrace_0) { int i = 0; ULONG64 StackEntry = 0; do { ReadPtr(EventStackTraceAddress + i * AddressSize, &StackEntry); dprintf(" "); do_symbol(StackEntry); ++LinesPrinted; ++i; } while (StackEntry && i < STACKTRACE_DEPTH); } return LinesPrinted; } void scan_usage() { dprintf("options:\n" "\n" " -sXYZ print entries with subject character == X or Y or Z\n" " -vXYZ print entries with verb character == X or Y or Z\n" " -s~XYZ print entries with subject character != X or Y or Z\n" " -v~XYZ print entries with verb character != X or Y or Z\n" " -t NNNN print entries for thread NNNN \n" " -a NNNN print entries for subject at address NNNN \n" " -o NNNN print entries for object at address NNNN \n" " -k or -k+ show stack traces if available\n" " -k- don't show stack traces (default)\n" " -b NNNN1 NNNN2 NNNN3 \n" " (if symbols are broken) RpcEvents is at NNNN1" " and NextEvent is NNNN2\n" " and event array length is NNNN3\n" " -NNNN print the NNNN entries ending with NextEvent (or specified base)\n" " +NNNN print the NNNN entries starting with NextEvent (or specified base)\n" " NNNN the base index is NNNN" " -f filename reads a binary version of the log and displays it as text\n" "\n" "e.g. '!scan -40 -sN' would print the last 40 DG_SCONNECTION events\n" " '!scan +30 200' would print 30 entries starting at index 200\n" ); } char VerbsToDisplay[40]; char SubjectsToDisplay[40]; DECLARE_API( scan ) { char * Subject = 0; char * verb = 0; ULONG64 addr = 0; ULONG64 obj_addr = 0; DWORD thread = 0; static ULONG64 RpcEvents = 0; static LONG EventArrayLength = 0; static LONG NextEvent = 0; int RequestCount = 30; int NextEventToPrint = 0; BOOL ForwardSearch = FALSE; BOOL ShowStackTraces = FALSE; BOOL Wrapped = FALSE; int BaseIndex = -1; int MatchCount = 0; int index; int i; BOOL fFileInput = FALSE; HANDLE hFile; struct RPC_EVENT Entry; ULONG64 EntryAddress; ULONG64 tmp; // // Interpret options. // char * arg; LPSTR lpArgumentString = (LPSTR)args; for (arg=strtok(lpArgumentString); arg; arg = strtok(0)) { if (arg[0] == '-') { ++arg; switch (arg[0]) { case 's': { if (!arg[1]) { scan_usage(); return; } if (strlen(arg+1) >= sizeof(SubjectsToDisplay)) { dprintf("-s: too many subject types proposed\n"); return; } strcpy(SubjectsToDisplay, arg+1); Subject = SubjectsToDisplay; if (Subject[0] == '*') { Subject = 0; } break; } case 'v': { if (!arg[1]) { scan_usage(); return; } if (strlen(arg+1) >= sizeof(VerbsToDisplay)) { dprintf("-v: too many verbs proposed\n"); return; } strcpy(VerbsToDisplay, arg+1); verb = VerbsToDisplay; if (verb[0] == '*') { verb = 0; } break; } case 'a': { if (arg[1]) { scan_usage(); return; } arg = strtok(0); if (!arg) { dprintf("-a: no object address specified\n"); return; } addr = GetExpression(arg); if (!addr) { dprintf("-a: can't evaluate %s\n", arg); return; } break; } case 'o': { if (arg[1]) { scan_usage(); return; } arg = strtok(0); if (!arg) { dprintf("-o: no object address specified\n"); return; } obj_addr = GetExpression(arg); if (!obj_addr) { dprintf("-o: can't evaluate %s\n", arg); return; } break; } case 't': { if (arg[1]) { scan_usage(); return; } arg = strtok(0); if (!arg) { dprintf("-t: no thread ID specified\n"); return; } thread = (DWORD) GetExpression(arg); if (!thread) { dprintf("-t: can't evaluate %s\n", arg); return; } break; } case 'b': { arg = strtok(0); if (!arg) { dprintf("-b: no base address specified\n"); return; } RpcEvents = GetExpression(arg); arg = strtok(0); if (!arg) { dprintf("-b: no NextEvent specified\n"); return; } NextEvent = (LONG) GetExpression(arg); arg = strtok(0); if (!arg) { dprintf("-b: no event array length specified\n"); return; } EventArrayLength = (long) GetExpression(arg); break; } case 'k': { if (arg[1] == '+' || arg[1] == '\0') { ShowStackTraces = TRUE; } else if (arg[1] == '-') { ShowStackTraces = FALSE; } else { dprintf("-k: use '-k' or '-k+' for stack traces, '-k-' for none\n"); return; } break; } case 'f': { arg = strtok(0); if (!arg) { dprintf("-f: no file name specified\n"); return; } hFile = CreateFileA(arg, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { dprintf("-f: Couldn't open file name %s - error %d\n", arg, GetLastError()); return; } fFileInput = TRUE; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { ForwardSearch = FALSE; RequestCount = myatol(arg); if (!RequestCount) { dprintf("-%s: zero lines specified\n", arg); return; } break; } default: { dprintf("unknown option %s\n", arg); scan_usage(); return; } } } else if (arg[0] == '+') { ++arg; RequestCount = myatol(arg); if (!RequestCount) { dprintf("+%s: zero lines specified\n", arg); return; } MatchCount = RequestCount; ForwardSearch = TRUE; } else { BaseIndex = (int) GetExpression(arg); } } if (fFileInput) { BOOL Result; DWORD NumberOfBytesRead; index = 1; while (1) { Result = ReadFile(hFile, &Entry, sizeof(Entry), &NumberOfBytesRead, NULL); if (!Result) { dprintf("-f: Error reading file: %d\n", GetLastError()); break; } if (NumberOfBytesRead < sizeof(Entry)) { dprintf("-f: EOF reached\n"); break; } PrintEntry(&Entry, index, ShowStackTraces); index ++; if ((CheckControlC)()) { CloseHandle(hFile); return; } } CloseHandle(hFile); return; } ULONG64 NextEventAddress = GetExpression("rpcrt4!NextEvent"); ULONG64 EventLengthAddress = GetExpression("rpcrt4!EventArrayLength"); // // Find the current event. // if (!RpcEvents) { RpcEvents = GetExpression("rpcrt4!RpcEvents"); if (!RpcEvents || !NextEventAddress) { dprintf("I can't find rpcrt4!RpcEvents or rpcrt4!NextEvent; use -b\n"); return; } if (!ReadMemory(NextEventAddress, &NextEvent, sizeof(DWORD), 0)) { dprintf("I can't read NextEvent from 0x%I64x\n", NextEventAddress); return; } if (EventLengthAddress) { if (!ReadMemory(EventLengthAddress, &EventArrayLength, sizeof(DWORD), 0)) { dprintf("I can't read EventArrayLength from 0x%I64x\n", EventLengthAddress); return; } if (!ReadMemory(RpcEvents, &tmp, sizeof(ULONG64), 0)) { dprintf("I can't read rpcrt4!RpcEvents at 0x%I64x\n", RpcEvents); return; } RpcEvents = tmp; } else { dprintf("rpcrt4!EventArrayLength isn't defined; probably an older build\n"); EventArrayLength = 4096; } dprintf("RpcEvents at 0x%I64x; array has %u entries; NextEvent = %lx, %s\n", RpcEvents, EventArrayLength, NextEvent, Wrapped ? "wrapped around" : ""); } if (FALSE == FetchEventAddress(RpcEvents, 0, &EntryAddress)) { dprintf("I can't read memory at 0x%I64x \n", RpcEvents); return; } GET_MEMBER(EntryAddress, RPC_EVENT, RPCRT4!RPC_EVENT, Subject, tmp); if (tmp) { Wrapped = TRUE; } if (thread || Subject || verb || addr || obj_addr) { dprintf("filter: "); } else { dprintf("no filter"); } if (thread) { dprintf("thread %x ", thread); } if (Subject) { dprintf("subjects '%s' ", Subject); } if (verb) { dprintf("verbs '%s' ", verb); } if (addr) { dprintf("address %x ", addr); } if (obj_addr) { dprintf("direct-object address 0x%I64x ", obj_addr); } dprintf(", base index = %x\n", BaseIndex); // Allow one set of debug spew to be printed if some data can't // be properly read or fields extracted. fSpew = TRUE; // // Scan backwards until we have enough matching events. // if (NextEvent > EventArrayLength) { NextEvent %= EventArrayLength; } if (ForwardSearch) { if (BaseIndex == -1) { BaseIndex = NextEventToPrint; } if (!Wrapped && BaseIndex + MatchCount > NextEvent+1) { MatchCount = NextEvent+1 - BaseIndex; } } else { if (BaseIndex == -1) { BaseIndex = NextEvent; } LONG Point = BaseIndex; for (index = Point; index >= 0 && MatchCount < RequestCount; --index ) { if (FALSE == FetchEventAddress(RpcEvents, index, &EntryAddress)) { dprintf("I can't read memory at index %x\n", index); return; } if (DoesEntryAddressMatch(EntryAddress, Subject, verb, thread, addr, obj_addr)) { ++MatchCount; BaseIndex = index; } } if (Wrapped && MatchCount < RequestCount) { for (index = EventArrayLength-1; index > Point && MatchCount < RequestCount; --index ) { ULONG64 EntryAddress; if (FALSE == FetchEventAddress(RpcEvents, index, &EntryAddress)) { dprintf("I can't read memory at index %d\n", index); return; } if (DoesEntryAddressMatch(EntryAddress, Subject, verb, thread, addr, obj_addr)) { ++MatchCount; BaseIndex = index; } } } } // // Print matching events. // index = BaseIndex; do { if (FALSE == FetchEventAddress(RpcEvents, index, &EntryAddress)) { dprintf("I can't read memory at index %x\n", index); return; } if (DoesEntryAddressMatch(EntryAddress, Subject, verb, thread, addr, obj_addr)) { PrintEntryAddress(EntryAddress, index, ShowStackTraces); --MatchCount; } ++index; index = index % EventArrayLength; if ((CheckControlC)()) { return; } } while (MatchCount && index != BaseIndex); NextEventToPrint = index; } DECLARE_API( rpcsleep ) { int nInterval; LPSTR lpArgumentString = (LPSTR)args; nInterval=atoi(lpArgumentString); if (nInterval == 0) { dprintf("Invalid wait interval %s\n", lpArgumentString); return; } Sleep(nInterval); } DECLARE_API( rpctime ) { DWORD dwCurrentTime; if (fKD) { dprintf("Cannot dump time in kd\n"); return; } dwCurrentTime = GetTickCount(); dprintf("Current time is: %06.6d.%03.3d (0x%06.6x.%03.3x)\n", dwCurrentTime / 1000, dwCurrentTime % 1000, dwCurrentTime / 1000, dwCurrentTime % 1000); } DECLARE_API( version ) { #if DBG PCSTR kind = "Checked"; #else PCSTR kind = "Free"; #endif if (fKD) { dprintf( "%s RPC Extension dll for Build %d debugging %s kernel for Build %d\n", kind, VER_PRODUCTBUILD, SavedMajorVersion == 0x0c ? "Checked" : "Free", SavedMinorVersion ); } else { dprintf( "%s RPC Extension dll for Build %d\n", kind, VER_PRODUCTBUILD ); } } DECLARE_API( bcache ) { ULONG64 tmp1; ULONG tmp2; ULONG64 StateArray = 0; // For process cache ULONG64 Cache; ULONG64 CacheAddress; BOOL b, fGuardPageMode = FALSE; // // Interpret options. // char * arg1; char * arg2; LPSTR lpArgumentString = (LPSTR)args; arg1 = strtok(lpArgumentString); arg2 = strtok(0); if (arg2) { dprintf("usage: \n" " !bcache for a thread's cache\n" " !bcache for the process cache\n" "\n"); return; } if (arg1) { ULONG64 RpcThread; ULONG64 pTeb = GetExpression(arg1); GET_MEMBER(pTeb, TEB, TEB, ReservedForNtRpc, RpcThread); GET_ADDRESS_OF(RpcThread, THREAD, RPCRT4!THREAD, BufferCache, StateArray, tmp2); } else { ULONG64 CachePointerAddress = GetExpression("rpcrt4!gBufferCache"); if (!CachePointerAddress) { dprintf("can't find rpcrt4!gBufferCache\n"); return; } b = GetData(CachePointerAddress, &CacheAddress, sizeof(PVOID)); if ( !b ) { dprintf("couldn't read process buffer cache pointer at %x\n", CacheAddress); return; } dprintf("process-wide buffer cache:\n"); ULONG64 GuardPageMode = GetExpression("rpcrt4!fGuardPageMode"); if(GuardPageMode) b = GetData(GuardPageMode, &fGuardPageMode, sizeof(fGuardPageMode)); if (!b) { dprintf("couldn't read guard page mode flag at address %p\n", GuardPageMode); return; } if (fGuardPageMode) { dprintf("---> GUARD PAGE mode enabled!\n"); } GET_ADDRESS_OF(CacheAddress, BCACHE, RPCRT4!BCACHE, _bcGlobalState, StateArray, tmp2); } // // Load the size hints. // ULONG64 HintAddress; HintAddress = GetExpression("rpcrt4!pHints"); ReadPtr(HintAddress, &HintAddress); // // Dump the buffer states. // int i; ULONG64 State = StateArray; ULONG64 Hint = HintAddress; ULONG64 cBlocks; ULONG64 pList; ULONG64 cSize; for (i=0; i < 4; ++i) { GET_MEMBER(State, BCACHE_STATE, RPCRT4!BCACHE_STATE, cBlocks, cBlocks); GET_MEMBER(State, BCACHE_STATE, RPCRT4!BCACHE_STATE, pList, pList); GET_MEMBER(Hint, BUFFER_CACHE_HINTS, RPCRT4!BUFFER_CACHE_HINTS, cSize, cSize); dprintf(" count %5u head %I64x size %5x\n", (ULONG)cBlocks, pList, (ULONG)cSize); State += GET_TYPE_SIZE(BCACHE_STATE, RPCRT4!BCACHE_STATE); Hint += GET_TYPE_SIZE(BUFFER_CACHE_HINTS, RPCRT4!BUFFER_CACHE_HINTS); } if (!arg1) { ULONG64 _bcGlobalStats; GET_ADDRESS_OF(CacheAddress, BCACHE, RPCRT4!BCACHE, _bcGlobalStats, _bcGlobalStats, tmp2); // Dump out the bcache cache stats dprintf("\nGlobal Stats:\n cap hits misses\n"); for (i = 0; i < ((fGuardPageMode) ? 2 : 4); i++) { ULONG64 cBufferCacheCap; ULONG64 cAllocationHits; ULONG64 cAllocationMisses; GET_MEMBER(_bcGlobalStats, BCACHE_STATS, RPCRT4!BCACHE_STATS, cBufferCacheCap, cBufferCacheCap); GET_MEMBER(_bcGlobalStats, BCACHE_STATS, RPCRT4!BCACHE_STATS, cAllocationHits, cAllocationHits); GET_MEMBER(_bcGlobalStats, BCACHE_STATS, RPCRT4!BCACHE_STATS, cAllocationMisses, cAllocationMisses); dprintf(" %5d %5d %5d\n", cBufferCacheCap, cAllocationHits, cAllocationMisses); _bcGlobalStats += GET_TYPE_SIZE(BCACHE_STATS, RPCRT4!BCACHE_STATS); } } } VOID CheckVersion( VOID ) { } LPEXT_API_VERSION ExtensionApiVersion( VOID ) { return &ApiVersion; } void PrintGetCallInfoUsage(void) { dprintf("Usage: \n\tgetcallinfo [CallID|0 [IfStart|0 [ProcNum|FFFF [ProcessID|0]]]]\n"); } DECLARE_API( getcallinfo ) { ULONG CallID = 0; ULONG IfStart = 0; USHORT ProcNum = RPCDBG_NO_PROCNUM_SPECIFIED; ULONG ProcessID = 0; int ArgumentNo = 0; // // Interpret options. // char * arg; if (fKD != 0) { dprintf("This extension command does not work under kd\n"); return; } LPSTR lpArgumentString = (LPSTR)args; for (arg=strtok(lpArgumentString); arg; arg = strtok(0)) { switch(ArgumentNo) { case 0: // either help or CallID if ((arg[0] == '?') || ((arg[0] == '-') && (arg[1] == '?'))) { PrintGetCallInfoUsage(); return; } else { CallID = (ULONG)GetExpression(arg); } break; case 1: IfStart = (ULONG)GetExpression(arg); break; case 2: ProcNum = (unsigned short) GetExpression(arg); break; case 3: ProcessID = (ULONG)GetExpression(arg); break; default: dprintf("Too many arguments\n"); PrintGetCallInfoUsage(); } ArgumentNo ++; } GetAndPrintCallInfo(CallID, IfStart, ProcNum, ProcessID, dprintf); } void PrintGetDbgCellUsage(void) { dprintf("Usage: \n\tgetdbgcell ProcessID CellID1.CellID2\n"); } DECLARE_API( getdbgcell ) { ULONG ProcessID = 0; int ArgumentNo = 0; DebugCellID CellID; char *DotSeparator; // // Interpret options. // char * arg; if (fKD != 0) { dprintf("This extension command does not work under kd\n"); return; } LPSTR lpArgumentString = (LPSTR)args; for (arg=strtok(lpArgumentString); arg; arg = strtok(0)) { switch(ArgumentNo) { case 0: // either help or ProcessID if ((arg[0] == '?') || ((arg[0] == '-') && (arg[1] == '?'))) { PrintGetCallInfoUsage(); return; } else { ProcessID = (ULONG)GetExpression(arg); } break; case 1: DotSeparator = strchr(arg, '.'); if (DotSeparator == NULL) { PrintGetCallInfoUsage(); return; } *DotSeparator = 0; DotSeparator ++; CellID.SectionID = (USHORT)GetExpression(arg); CellID.CellID = (USHORT)GetExpression(DotSeparator); break; default: dprintf("Too many arguments\n"); PrintGetDbgCellUsage(); } ArgumentNo ++; } GetAndPrintDbgCellInfo(ProcessID, CellID, dprintf); } void PrintGetEndpointInfoUsage(void) { dprintf("Usage: \n\tgetendpointinfo [EndpointName]\n"); } DECLARE_API( getendpointinfo ) { int ArgumentNo = 0; char *EndpointName = NULL; // // Interpret options. // char * arg; if (fKD != 0) { dprintf("This extension command does not work under kd\n"); return; } LPSTR lpArgumentString = (LPSTR)args; for (arg=strtok(lpArgumentString); arg; arg = strtok(0)) { switch(ArgumentNo) { case 0: // either help or EndpointName if ((arg[0] == '?') || ((arg[0] == '-') && (arg[1] == '?'))) { PrintGetEndpointInfoUsage(); return; } else { EndpointName = arg; } break; default: dprintf("Too many arguments\n"); PrintGetCallInfoUsage(); } ArgumentNo ++; } GetAndPrintEndpointInfo(EndpointName, dprintf); } void PrintGetThreadInfoUsage(void) { dprintf("Usage: \n\tgetthreadinfo ProcessID [ThreadID]\n"); } DECLARE_API( getthreadinfo ) { DWORD ProcessID = 0; DWORD ThreadID = 0; int ArgumentNo = 0; BOOL fFirstTime = TRUE; // // Interpret options. // char * arg; if (fKD != 0) { dprintf("This extension command does not work under kd\n"); return; } LPSTR lpArgumentString = (LPSTR)args; for (arg=strtok(lpArgumentString); arg; arg = strtok(0)) { switch(ArgumentNo) { case 0: // either help or EndpointName if ((arg[0] == '?') || ((arg[0] == '-') && (arg[1] == '?'))) { PrintGetThreadInfoUsage(); return; } else { ProcessID = (DWORD)GetExpression(arg); } fFirstTime = FALSE; break; case 1: ThreadID = (DWORD)GetExpression(arg); break; default: dprintf("Too many arguments\n"); PrintGetThreadInfoUsage(); } ArgumentNo ++; } if (fFirstTime) { dprintf("You must specify at least a process id\n"); PrintGetThreadInfoUsage(); return; } GetAndPrintThreadInfo(ProcessID, ThreadID, dprintf); } void PrintGetClientCallInfoUsage(void) { dprintf("Usage: \n\tgetclientcallinfo [CallID|0 [IfStart|0 [ProcNum|FFFF [ProcessID|0]]]]\n"); } DECLARE_API( getclientcallinfo ) { ULONG CallID = 0; ULONG IfStart = 0; USHORT ProcNum = RPCDBG_NO_PROCNUM_SPECIFIED; ULONG ProcessID = 0; int ArgumentNo = 0; // // Interpret options. // char * arg; if (fKD != 0) { dprintf("This extension command does not work under kd\n"); return; } LPSTR lpArgumentString = (LPSTR)args; for (arg=strtok(lpArgumentString); arg; arg = strtok(0)) { switch(ArgumentNo) { case 0: // either help or CallID if ((arg[0] == '?') || ((arg[0] == '-') && (arg[1] == '?'))) { PrintGetClientCallInfoUsage(); return; } else { CallID = (ULONG)GetExpression(arg); } break; case 1: IfStart = (ULONG)GetExpression(arg); break; case 2: ProcNum = (USHORT)GetExpression(arg); break; case 3: ProcessID = (ULONG)GetExpression(arg); break; default: dprintf("Too many arguments\n"); PrintGetCallInfoUsage(); } ArgumentNo ++; } GetAndPrintClientCallInfo(CallID, IfStart, ProcNum, ProcessID, dprintf); } DECLARE_API( checkrpcsym ) { PVOID FunctionPtr; DWORD Data; BOOL b; BOOL fUnsure = FALSE; const int ExpectedDataSize = 3; const DWORD ExpectedData[3] = {0x55, 0x8B, 0xEC}; const int FunctionNamesSize = 2; const char *FunctionNames[2] = {"RPCRT4!WS_NewConnection", "RPCRT4!OSF_ADDRESS__NewConnection"}; int i, FunctionNo; for (FunctionNo = 0; FunctionNo < FunctionNamesSize; FunctionNo ++) { FunctionPtr = (PVOID)GetExpression(FunctionNames[FunctionNo]); if (FunctionPtr == NULL) { dprintf("Cannot find address of %s - RPC symbols are wrong\n", FunctionNames[FunctionNo]); return; } b = GetData(HandleToUlong(FunctionPtr), &Data, sizeof(DWORD)); if (!b) { // under UM debugger this is bad symbols if (fKD == 0) { dprintf("Cannot access address %x - RPC symbols are wrong\n", FunctionPtr); return; } // in kd this is possible even with valid symbols fUnsure = TRUE; } else { for (i = 0; i < ExpectedDataSize; i ++) { if ((Data & 0xFF) != ExpectedData[i]) { dprintf("Function %s does not have expected " "contents () - non-X86 architecture or RPC symbols are wrong\n", FunctionNames[FunctionNo], Data & 0xFF, ExpectedData[i]); return; } Data >>= 8; } } } if (fUnsure) { dprintf("The correctness of RPC symbols could not be determined conclusively\n"); } else { dprintf("RPC symbols are correct\n"); } } typedef struct tagCallStackPatternMatch { const char *FunctionBase; int ValueOffset; // 0 if the value is not relative to this symbols, or // any positive/negative if the value is relative to // this symbol } CallStackPatternMatch; typedef struct tagStackGroupPattern { CallStackPatternMatch *StackPattern; int NumberOfEntries; } StackGroupPattern; CallStackPatternMatch WS_CallStack1[] = {{"kernel32!WaitForSingleObjectEx", 0}, {"rpcrt4!UTIL_WaitForSyncIO", 0}, {"rpcrt4!WS_SyncRecv", 0}, {"rpcrt4!WS_SyncRecv", 0}, {"rpcrt4!OSF_CCONNECTION__TransSendReceive", 0}, {"rpcrt4!OSF_CCONNECTION__SendFragment", 0}, {"rpcrt4!OSF_CCALL__SendNextFragment", 0}, {"rpcrt4!OSF_CCALL__FastSendReceive", 0}, {"rpcrt4!OSF_CCALL__SendReceiveHelper", 0}, {"rpcrt4!OSF_CCALL__SendReceive", 0}, {"rpcrt4!I_RpcSendReceive", 0}, {"rpcrt4!NdrSendReceive", sizeof(PVOID)}}; CallStackPatternMatch WS_CallStack2[] = {{"kernel32!WaitForSingleObjectEx", 0}, {"rpcrt4!UTIL_WaitForSyncIO", 0}, {"rpcrt4!UTIL_GetOverlappedResultEx", 0}, {"rpcrt4!WS_SyncRecv", 0}, {"rpcrt4!OSF_CCONNECTION__TransSendReceive", 0}, {"rpcrt4!OSF_CCONNECTION__SendFragment", 0}, {"rpcrt4!OSF_CCALL__SendNextFragment", 0}, {"rpcrt4!OSF_CCALL__FastSendReceive", 0}, {"rpcrt4!OSF_CCALL__SendReceiveHelper", 0}, {"rpcrt4!OSF_CCALL__SendReceive", 0}, {"rpcrt4!I_RpcSendReceive", 0}, {"rpcrt4!NdrSendReceive", sizeof(PVOID)}}; CallStackPatternMatch NMP_CallStack1[] = {{"kernel32!WaitForSingleObjectEx", 0}, {"rpcrt4!UTIL_WaitForSyncIO", 0}, {"rpcrt4!UTIL_GetOverlappedResultEx", 0}, {"rpcrt4!NMP_SyncSendRecv", 0}, {"rpcrt4!OSF_CCONNECTION__TransSendReceive", 0}, {"rpcrt4!OSF_CCONNECTION__SendFragment", 0}, {"rpcrt4!OSF_CCALL__SendNextFragment", 0}, {"rpcrt4!OSF_CCALL__FastSendReceive", 0}, {"rpcrt4!OSF_CCALL__SendReceiveHelper", 0}, {"rpcrt4!OSF_CCALL__SendReceive", 0}, {"rpcrt4!I_RpcSendReceive", 0}, {"rpcrt4!NdrSendReceive", sizeof(PVOID)}}; CallStackPatternMatch LRPC_CallStack1[] = {{"rpcrt4!LRPC_CCALL__SendReceive", 0}, {"rpcrt4!I_RpcSendReceive", 0}, {"rpcrt4!NdrSendReceive", sizeof(PVOID)}}; const int NumberOfWsCallStacks = 2; StackGroupPattern WS_CallStacks[] = {{WS_CallStack1, 12}, {WS_CallStack2, 12}}; const int NumberOfNmpCallStacks = 1; StackGroupPattern NMP_CallStacks[] = {{NMP_CallStack1, 12}}; const int NumberOfLrpcCallStacks = 1; StackGroupPattern LRPC_CallStacks[] = {{LRPC_CallStack1, 3}}; ULONG_PTR Buffer[40]; ULONG_PTR *LastPos = NULL; int BufferPos = 0; BOOL VerboseStack = FALSE; BOOL GetStackValue(ULONG_PTR *CurrentPos, ULONG_PTR *Value) { BOOL Result; // if we keep fetching the same data, and we still have data in the // buffer, keep going if (((CurrentPos - 1) == LastPos) && ((BufferPos + 1) < (sizeof(Buffer) / sizeof(Buffer[0])))) { LastPos = CurrentPos; BufferPos ++; *Value = Buffer[BufferPos]; return TRUE; } // either we started a new search, or we exhausted the fetched data - // fetch new data Result = GetData((ULONG_PTR)CurrentPos, Buffer, sizeof(Buffer)); // there may be not be enough readable data for the whole buffer - // switch to slow mode and fetch them one by one if (Result == FALSE) { Result = GetData((ULONG_PTR)CurrentPos, Value, sizeof(ULONG_PTR)); if (Result == FALSE) return FALSE; else return TRUE; } // data were successfully fetched to the buffer LastPos = CurrentPos; BufferPos = 0; *Value = Buffer[0]; return TRUE; } BOOL MatchStack(IN PVOID StackStart, IN StackGroupPattern *StackGroup, IN int NumberOfElementsInGroup, OUT ULONG_PTR *Value) { int i; BOOL Result; ULONG_PTR CurrentPos; ULONG_PTR CurrentValue; ULONG_PTR Displacement; int StackPatternPos; // the next stack entry to match ULONG_PTR FinalValue = 0; int ValueOffset; CHAR CurrentName[256]; for (i = 0; i < NumberOfElementsInGroup; i ++) { CurrentPos = (ULONG_PTR)StackStart; StackPatternPos = 0; while (TRUE) { Result = GetStackValue((ULONG_PTR *)CurrentPos, &CurrentValue); if (Result == FALSE) goto NextStack; GetSymbol((ULONG64)CurrentValue, CurrentName, (PULONG64)&Displacement); if (RpcpStringCompareA((const char *)CurrentName, StackGroup[i].StackPattern[StackPatternPos].FunctionBase) == 0) { if (VerboseStack) { dprintf("Stack: %d: Match with '%s'\n", i, CurrentName); } ValueOffset = StackGroup[i].StackPattern[StackPatternPos].ValueOffset; if (ValueOffset != 0) { Result = GetData(CurrentPos + ValueOffset, &FinalValue, sizeof(ULONG_PTR)); if (Result == FALSE) goto NextStack; } StackPatternPos ++; if (StackPatternPos >= StackGroup[i].NumberOfEntries) { // full stack match - return success ASSERT(FinalValue != 0); *Value = FinalValue; return TRUE; } } CurrentPos += sizeof(ULONG_PTR); } NextStack: ; } return FALSE; } BOOL GetDataFromRpcMessage(IN ULONG_PTR RpcMessage, OUT ULONG_PTR *CallObject, OUT DWORD *IfStart, OUT USHORT *ProcNum) { BOOL Result; union { RPC_MESSAGE RpcMessage; RPC_CLIENT_INTERFACE Interface; } MemLoc; ULONG_PTR Interface; Result = GetData(RpcMessage, (PVOID) &MemLoc.RpcMessage, sizeof(MemLoc.RpcMessage)); if (Result == FALSE) return FALSE; *CallObject = (ULONG_PTR)MemLoc.RpcMessage.Handle; *ProcNum = (USHORT)MemLoc.RpcMessage.ProcNum; Interface = (ULONG_PTR)MemLoc.RpcMessage.RpcInterfaceInformation; Result = GetData(Interface, &MemLoc.Interface, sizeof(MemLoc.Interface)); if (Result == FALSE) return FALSE; *IfStart = MemLoc.Interface.InterfaceId.SyntaxGUID.Data1; return TRUE; } BOOL PrintDceBinding(ULONG_PTR DceBindingPointer) { NO_CONSTRUCTOR_TYPE(DCE_BINDING, DceBinding); RPC_CHAR *RpcProtocolSequence; RPC_CHAR *NetworkAddress; RPC_CHAR *Endpoint; BOOL Result; Result = GetData(DceBindingPointer, DceBinding, sizeof(DCE_BINDING)); if (Result == FALSE) return FALSE; RpcProtocolSequence = ReadProcessRpcChar((ULONG64)DceBinding->RpcProtocolSequence); NetworkAddress = ReadProcessRpcChar((ULONG64)DceBinding->NetworkAddress); Endpoint = ReadProcessRpcChar((ULONG64)DceBinding->Endpoint); if ((RpcProtocolSequence == NULL) && (NetworkAddress == NULL) && (Endpoint == NULL)) { return FALSE; } dprintf("\tProtocol Sequence: \t\"%ws\"\t(Address: %p)\n", RpcProtocolSequence, DceBinding->RpcProtocolSequence); dprintf("\tNetworkAddress:\t\t\"%ws\"\t(Address: %p)\n", NetworkAddress, DceBinding->NetworkAddress); dprintf("\tEndpoint:\t\t\"%ws\" \t(Address: %p)\n", Endpoint, DceBinding->Endpoint); delete RpcProtocolSequence; delete NetworkAddress; delete Endpoint; return TRUE; } BOOL PrintOsfCallInfoFromRpcMessage(ULONG_PTR RpcMessage) { ULONG_PTR CallObject; BOOL Result; NO_CONSTRUCTOR_TYPE(OSF_CCALL, OsfCCall); DWORD CallID; DWORD IfStart; USHORT ProcNum; ULONG_PTR ConnPointer; ULONG_PTR AssocPointer; ULONG_PTR DceBindingPointer; Result = GetDataFromRpcMessage(RpcMessage, &CallObject, &IfStart, &ProcNum); if (Result == FALSE) return FALSE; Result = GetData(CallObject, OsfCCall, sizeof(OSF_CCALL)); if (Result == FALSE) return FALSE; CallID = OsfCCall->CallId; dprintf("CallID: %d\n", CallID); dprintf("IfStart: %x\n", IfStart); dprintf("ProcNum: %d\n", (int)ProcNum); ConnPointer = (ULONG_PTR)OsfCCall->Connection; // get the association pointer Result = GetData(ConnPointer + FIELD_OFFSET(OSF_CCONNECTION, Association), &AssocPointer, sizeof(ULONG_PTR)); if (Result == FALSE) return FALSE; // get the dcebinding pointer Result = GetData(AssocPointer + FIELD_OFFSET(OSF_CASSOCIATION, DceBinding), &DceBindingPointer, sizeof(ULONG_PTR)); if (Result == FALSE) return FALSE; // print the DCE binding info PrintDceBinding(DceBindingPointer); return TRUE; } BOOL PrintLrpcCallInfoFromRpcMessage(ULONG_PTR RpcMessage) { ULONG_PTR CallObject; BOOL Result; NO_CONSTRUCTOR_TYPE(LRPC_CCALL, LrpcCCall); DWORD CallID; DWORD IfStart; USHORT ProcNum; ULONG_PTR AssocPointer; ULONG_PTR DceBindingPointer; Result = GetDataFromRpcMessage(RpcMessage, &CallObject, &IfStart, &ProcNum); if (Result == FALSE) return FALSE; Result = GetData(CallObject, LrpcCCall, sizeof(LRPC_CCALL)); if (Result == FALSE) return FALSE; CallID = LrpcCCall->CallId; dprintf("CallID: %d\n", CallID); dprintf("IfStart: %x\n", IfStart); dprintf("ProcNum: %d\n", (int)ProcNum); AssocPointer = (ULONG_PTR)LrpcCCall->Association; // get the dcebinding pointer Result = GetData(AssocPointer + FIELD_OFFSET(LRPC_CASSOCIATION, DceBinding), &DceBindingPointer, sizeof(ULONG_PTR)); if (Result == FALSE) return FALSE; // print the DCE binding info PrintDceBinding(DceBindingPointer); return TRUE; } DECLARE_API (rpcreadstack) { PVOID StackStart; BOOL Result; ULONG_PTR Value; LPSTR lpArgumentString = (LPSTR)args; StackStart = (PVOID)GetExpression(lpArgumentString); // try to match the stack against the different types we support // first, try Winsock if (VerboseStack) { dprintf("Matching Winsock stacks\n"); } Result = MatchStack(StackStart, WS_CallStacks, NumberOfWsCallStacks, &Value); if (Result == TRUE) { // call the Winsock stack analysis function PrintOsfCallInfoFromRpcMessage(Value); return; } // next, try Named pipes if (VerboseStack) { dprintf("Matching named pipe stacks\n"); } Result = MatchStack(StackStart, NMP_CallStacks, NumberOfNmpCallStacks, &Value); if (Result == TRUE) { // call the named pipe stack analysis function PrintOsfCallInfoFromRpcMessage(Value); return; } // next, try LRPC if (VerboseStack) { dprintf("Matching LRPC stacks\n"); } Result = MatchStack(StackStart, LRPC_CallStacks, NumberOfLrpcCallStacks, &Value); if (Result == TRUE) { // call the Lrpc stack analysis function PrintLrpcCallInfoFromRpcMessage(Value); return; } dprintf("Not found!\n"); } DECLARE_API (rpcverbosestack) { VerboseStack = !VerboseStack; if (VerboseStack) { dprintf("Switched to ON\n"); } else { dprintf("Switched to OFF\n"); } } VOID do_eerecord( ULONG64 qwAddr ) { ULONG64 tmp0; ULONG64 tmp1; ULONG tmp2; unsigned char Buf[sizeof(ExtendedErrorInfo) + sizeof(ExtendedErrorParam) * (MaxNumberOfEEInfoParams - 1)]; ULONG64 EEInfoAddr; BOOL Result; int EEInfoSize; RPC_CHAR *ComputerNameStr; SYSTEMTIME SystemTime; int i; ULONG64 nLen; ULONG64 TimeStamp; ULONG64 ComputerName; ULONG64 Params; ULONG64 ParamType; ULONG64 ParamAddr; ULONG64 UnicodeStringAddr; ULONG64 AnsiStringAddr; ULONG64 BlobAddr; ULONG64 nLength; ULONG64 pString; char *AnsiBuf; RPC_CHAR *UnicodeBuf; dprintf("eerecord at 0x%I64x:\n", qwAddr); GET_MEMBER(qwAddr, ExtendedErrorInfo, RPCRT4!ExtendedErrorInfo, nLen, nLen); GET_MEMBER(qwAddr, ExtendedErrorInfo, RPCRT4!ExtendedErrorInfo, TimeStamp, TimeStamp); GET_ADDRESS_OF(qwAddr, ExtendedErrorInfo, RPCRT4!ExtendedErrorInfo, Params, Params, tmp2); GET_ADDRESS_OF(qwAddr, ExtendedErrorInfo, RPCRT4!ExtendedErrorInfo, ComputerName, ComputerName, tmp2); GET_MEMBER(ComputerName, EEComputerName, RPCRT4!EEComputerName, Type, tmp1); if ((ULONG)tmp1 == eecnpPresent) { GET_ADDRESS_OF(ComputerName, EEComputerName, RPCRT4!EEComputerName, Name, tmp1, tmp2); GET_MEMBER(tmp1, EEUString, RPCRT4!EEUString, pString, tmp0); ComputerNameStr = ReadProcessRpcChar(tmp0); if (ComputerNameStr != NULL) { dprintf("Computer Name: %S\n", ComputerNameStr); delete ComputerNameStr; } } else { dprintf("Computer Name: (null)\n"); } PRINT_MEMBER_DECIMAL_AND_HEX(qwAddr, ExtendedErrorInfo, RPCRT4!ExtendedErrorInfo, ProcessID, tmp0); PRINT_MEMBER_DECIMAL_AND_HEX(qwAddr, ExtendedErrorInfo, RPCRT4!ExtendedErrorInfo, Status, tmp0); // BUG dprintf ("TimeStamp=%I64x\n", TimeStamp); Result = FileTimeToSystemTime((FILETIME *)&TimeStamp, &SystemTime); if (Result) { dprintf("System Time is: %d/%d/%d %d:%d:%d:%d\n", SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds); } else { dprintf("Couldn't extract system time. Error is %d\n", GetLastError()); } PRINT_MEMBER(qwAddr, ExtendedErrorInfo, RPCRT4!ExtendedErrorInfo, GeneratingComponent, tmp0); PRINT_MEMBER_DECIMAL_AND_HEX(qwAddr, ExtendedErrorInfo, RPCRT4!ExtendedErrorInfo, Status, tmp0); PRINT_MEMBER_DECIMAL_AND_HEX(qwAddr, ExtendedErrorInfo, RPCRT4!ExtendedErrorInfo, DetectionLocation, tmp0); GET_MEMBER(qwAddr, ExtendedErrorInfo, RPCRT4!ExtendedErrorInfo, Flags, tmp0); dprintf("Flags: %S %S\n", tmp0 & EEInfoPreviousRecordsMissing ? "Previous Record Missing" : "", tmp0 & EEInfoNextRecordsMissing ? "Next Record Missing" : ""); dprintf("nLen = %d\n", (int)nLen); ParamAddr = Params; for (i = 0; i < (int)nLen; i++) { dprintf("Parameter %d:", i); GET_MEMBER(ParamAddr, tagParam, RPCRT4!tagParam, Type, ParamType); switch((ULONG)ParamType) { case eeptiAnsiString: dprintf("(Ansi string) : "); GET_ADDRESS_OF(ParamAddr, tagParam, RPCRT4!tagParam, AnsiString, AnsiStringAddr, tmp2); GET_MEMBER(AnsiStringAddr, tagEEAString, RPCRT4!tagEEAString, nLength, nLength); GET_MEMBER(AnsiStringAddr, tagEEAString, RPCRT4!tagEEAString, pString, pString); // we know the length - use GetData AnsiBuf = new char [(unsigned)nLength]; if (AnsiBuf != NULL) { Result = GetData(pString, AnsiBuf, (ULONG)nLength); if (Result) { dprintf("%s\n", AnsiBuf); } // else // error info has already been printed - nothing to do delete AnsiBuf; } break; case eeptiUnicodeString: dprintf("(Unicode string) : "); GET_ADDRESS_OF(ParamAddr, tagParam, RPCRT4!tagParam, UnicodeString, UnicodeStringAddr, tmp2); GET_MEMBER(UnicodeStringAddr, tagEEAString, RPCRT4!tagEEAString, nLength, nLength); GET_MEMBER(UnicodeStringAddr, tagEEAString, RPCRT4!tagEEAString, pString, pString); // we know the length - use GetData UnicodeBuf = new RPC_CHAR [(unsigned)nLength]; if (UnicodeBuf != NULL) { Result = GetData(pString, UnicodeBuf, (ULONG)(nLength * sizeof(RPC_CHAR))); if (Result) { dprintf("%S\n", UnicodeBuf); } // else // error info has already been printed - nothing to do delete UnicodeBuf; } break; case eeptiLongVal: PRINT_MEMBER_DECIMAL_AND_HEX(ParamAddr, tagParam, RPCRT4!tagParam, LVal, tmp0); break; case eeptiShortVal: PRINT_MEMBER_DECIMAL_AND_HEX(ParamAddr, tagParam, RPCRT4!tagParam, IVal, tmp0); break; case eeptiPointerVal: PRINT_MEMBER_DECIMAL_AND_HEX(ParamAddr, tagParam, RPCRT4!tagParam, PVal, tmp0); break; case eeptiNone: dprintf("(Truncated value)\n"); break; case eeptiBinary: dprintf("(Binary value:)\n"); GET_ADDRESS_OF(ParamAddr, tagParam, RPCRT4!tagParam, Blob, BlobAddr, tmp2); PRINT_MEMBER_DECIMAL_AND_HEX(BlobAddr, tagBinaryEEInfo, RPCRT4!tagBinaryEEInfo, nSize, tmp0); PRINT_MEMBER_DECIMAL_AND_HEX(BlobAddr, tagBinaryEEInfo, RPCRT4!tagBinaryEEInfo, pBlob, tmp0); break; default: dprintf("Invalid type: %d\n", (ULONG)ParamType); } ParamAddr += GET_TYPE_SIZE(tagParam, RPCRT4!tagParam); } } VOID do_eeinfo( ULONG64 qwAddr ) { ULONG64 PrevNextElement = qwAddr; ULONG64 NextElement = qwAddr; ULONG64 FirstElement = qwAddr; BOOL Result; do { do_eerecord(NextElement); PrevNextElement = NextElement; GET_MEMBER(qwAddr, ExtendedErrorInfo, RPCRT4!ExtendedErrorInfo, Next, NextElement); // prevent loops if (NextElement == FirstElement) { dprintf("Loop detected - exitting ...\n"); return; } dprintf("------------------------\n"); } while(NextElement != 0 && PrevNextElement != NextElement); } VOID PrintTypeinfoUsage(VOID) { dprintf("Wrong arguments to !rpcexts.typeinfo\n"); dprintf("Please use !rpcexts.typeinfo on|off\n"); } DECLARE_API (typeinfo) { LPSTR lpArgumentString = (LPSTR)args; if (strcmp(lpArgumentString, "on") == 0) fUseTypeInfo = TRUE; else if (strcmp(lpArgumentString, "off") == 0) fUseTypeInfo = FALSE; else if (strcmp(lpArgumentString, "") == 0) { if (fUseTypeInfo == TRUE) dprintf ("typeinfo use is on\n"); else dprintf ("typeinfo use is off\n"); } else PrintTypeinfoUsage(); return; } VOID PrintStackMatchUsage(VOID) { dprintf("Wrong arguments to !rpcexts.stackmatch"); dprintf("Please use !rpcexts.stackmatch start_addr [depth]\n"); } DECLARE_API( stackmatch ) { static ULONG64 Start; static ULONG Depth = 0x80; CHAR Symbol[128]; ULONG64 Displacement = 0; // // Interpret options. // ULONG ProcessID = 0; int ArgumentNo = 0; DebugCellID CellID; char *DotSeparator; // // Interpret options. // char * arg; LPSTR lpArgumentString = (LPSTR)args; for (arg=strtok(lpArgumentString); arg; arg = strtok(0)) { switch(ArgumentNo) { case 0: Start = GetExpression(arg); break; case 1: Depth = (ULONG) GetExpression(arg); break; default: dprintf("Too many arguments\n"); PrintStackMatchUsage(); } ArgumentNo ++; } for (ULONG64 Addr=Start; Addr<=Start+Depth; Addr+=AddressSize) { ULONG64 Val; ReadPtr(Addr, &Val); dprintf("%I64p %I64p", Addr, Val); GetSymbol(Val, Symbol, &Displacement); if (strcmp(Symbol, "") != 0) dprintf(" %s+%x", Symbol, Displacement); else { ULONG64 Obj; ReadPtr(Val, &Obj); if (Obj) { dprintf(" -> %I64p", Obj); GetSymbol(Obj, Symbol, &Displacement); if (strcmp(Symbol, "") != 0) dprintf(" %s+%x", Symbol, Displacement); } } dprintf("\n"); } Start = Addr; } DECLARE_API( listcalls ) { ULONG64 qwAddr; BOOL fArgSpecified = FALSE; ULONG64 ServerAddress; LPSTR lpArgumentString = (LPSTR)args; if (0 == strtok(lpArgumentString)) { lpArgumentString = "rpcrt4!GlobalRpcServer"; fArgSpecified = TRUE; } qwAddr = GetExpression(lpArgumentString); if ( !qwAddr ) { dprintf("Error: can't evaluate '%s'\n", lpArgumentString); return; } if (fArgSpecified) { if (ReadPtr(qwAddr, &ServerAddress)) { dprintf("couldn't read memory at address 0x%I64x\n", qwAddr); return; } } else ServerAddress = qwAddr; do_listcalls(ServerAddress); } VOID LoopThroughDict(ULONG64 Dict, PCHAR offset) { ULONG64 tmp0; ULONG64 tmp1; ULONG tmp2; ULONG64 cDictSize; ULONG64 cDictSlots; ULONG64 DictSlots; int j; ULONG64 DictSlot; GET_MEMBER(Dict, SIMPLE_DICT, RPCRT4!SIMPLE_DICT, cDictSize, cDictSize); GET_MEMBER(Dict, SIMPLE_DICT, RPCRT4!SIMPLE_DICT, cDictSlots, cDictSlots); if ((ULONG)cDictSize > (ULONG)cDictSlots) { dprintf("Bad dictionary\t\t- %I64p\n", Dict); return; } GET_MEMBER(Dict, SIMPLE_DICT, RPCRT4!SIMPLE_DICT, DictSlots, DictSlots); dprintf("%sPrinting %d items in dictionary: %I64p with %d slots\n\n", offset, (ULONG)cDictSize, Dict, (ULONG)cDictSlots); // Loop throught the associations. for (j = 0; j < MIN((int)cDictSize, MAX_ITEMS_IN_DICTIONARY); j++) { ReadPtr(DictSlots + j * AddressSize, &DictSlot); dprintf ("%s(%d): 0x%I64x - ", offset, j, DictSlot); ULONG64 MagicValue; ULONG64 ObjectType; ULONG64 Dict; ReadPtr(DictSlot+AddressSize, &MagicValue); ReadPtr(DictSlot+AddressSize+4, &ObjectType); if ((ULONG)MagicValue != MAGICLONG) { dprintf("Bad or deleted object at %p\n", DictSlot); } switch (((ULONG)ObjectType) & (~OBJECT_DELETED)) { case DG_ADDRESS_TYPE: dprintf("DG_ADDRESS\n"); break; case OSF_ADDRESS_TYPE: dprintf("OSF_ADDRESS\n"); GET_ADDRESS_OF(DictSlot, OSF_ADDRESS, RPCRT4!OSF_ADDRESS, Associations, Dict, tmp2); LoopThroughDict(Dict, "\t\t"); break; case LRPC_ADDRESS_TYPE: dprintf("LRPC_ADDRESS\n"); GET_ADDRESS_OF(DictSlot, LRPC_ADDRESS, RPCRT4!LRPC_ADDRESS, AssociationDictionary, Dict, tmp2); LoopThroughDict(Dict, "\t\t"); break; case OSF_ASSOCIATION_TYPE: dprintf("OSF_ASSOCIATION_TYPE\n"); break; case LRPC_SASSOCIATION_TYPE: dprintf("LRPC_SASSOCIATION_TYPE\n"); break; default: dprintf("The RPC object type is 0x%lx and I don't recognize it.\n", (ObjectType) & ~(OBJECT_DELETED)); } } } VOID do_listcalls( ULONG64 qwAddr ) { ULONG64 tmp0; ULONG64 tmp1; ULONG tmp2; dprintf("\n"); dprintf("RPC_SERVER at 0x%I64x\n", qwAddr); ULONG64 RpcAddressDictionary; GET_ADDRESS_OF(qwAddr, RPC_SERVER, RPCRT4!RPC_SERVER, RpcAddressDictionary, RpcAddressDictionary, tmp2); dprintf("&RpcAddressDictionary(RPC_SIMPLE_DICT) - 0x%I64x\n", RpcAddressDictionary); LoopThroughDict(RpcAddressDictionary, "\t"); dprintf("\n"); }