537 lines
17 KiB
C++
537 lines
17 KiB
C++
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1997 - 2001
|
|
|
|
Module Name:
|
|
|
|
NtTrans.cxx
|
|
|
|
Abstract:
|
|
|
|
NTSD/KD extensions for debugging Windows NT transport interface
|
|
data structures.
|
|
|
|
Author:
|
|
|
|
Mario Goertzel [MarioGo]
|
|
|
|
Revision History:
|
|
|
|
MarioGo 3/21/1997 Bits 'n pieces
|
|
|
|
GrigoriK Mar 2001 Added support for type info.
|
|
|
|
--*/
|
|
|
|
#undef _RPCRT4_
|
|
|
|
#define KDEXT_64BIT
|
|
|
|
#define private public
|
|
|
|
#include "..\trans\Common\precomp.hxx"
|
|
#include "..\mtrt\precomp.hxx"
|
|
#include <stddef.h>
|
|
#include <wdbgexts.h>
|
|
#include <rpcexts.hxx>
|
|
|
|
VOID do_trans(ULONG64);
|
|
VOID do_protocols(ULONG64);
|
|
VOID do_overlap(ULONG64);
|
|
VOID do_addrvect(ULONG64);
|
|
|
|
MY_DECLARE_API(trans);
|
|
MY_DECLARE_API(overlap);
|
|
MY_DECLARE_API(addrvect);
|
|
|
|
const char *Protocols[] =
|
|
{
|
|
"INVALID",
|
|
"TCP/IP",
|
|
#ifdef SPX_ON
|
|
"SPX",
|
|
#else
|
|
"Invalid",
|
|
#endif
|
|
"Named pipes",
|
|
#ifdef NETBIOS_ON
|
|
"NetBEUI",
|
|
"Netbios(TCP)",
|
|
"Netbios(IPX)",
|
|
#else
|
|
"Invalid",
|
|
"Invalid",
|
|
"Invalid",
|
|
#endif
|
|
#ifdef APPLETALK_ON
|
|
"Appletalk DSP",
|
|
#else
|
|
"Invalid",
|
|
#endif
|
|
"Invalid", // former "Vines SPP",
|
|
"HTTP",
|
|
"UDP/IP",
|
|
#ifdef IPX_ON
|
|
"IPX",
|
|
#else
|
|
"Invalid",
|
|
#endif
|
|
"CDP",
|
|
#ifdef NCADG_MQ_ON
|
|
"MSMQ",
|
|
#else
|
|
"Invalid",
|
|
#endif
|
|
"TCP/IPv6"
|
|
};
|
|
const INT cProtocols = sizeof(Protocols)/sizeof(char *);
|
|
|
|
|
|
VOID
|
|
do_trans(
|
|
ULONG64 qwAddr
|
|
)
|
|
{
|
|
char const *pszProtocol;
|
|
|
|
ULONG64 tmp1;
|
|
ULONG tmp2;
|
|
|
|
DWORD protocol;
|
|
|
|
ULONG64 id;
|
|
ULONG64 type;
|
|
|
|
GET_MEMBER(qwAddr, BASE_ASYNC_OBJECT, RPCRT4!BASE_ASYNC_OBJECT, id, id);
|
|
GET_MEMBER(qwAddr, BASE_ASYNC_OBJECT, RPCRT4!BASE_ASYNC_OBJECT, type, type);
|
|
|
|
// Display protocol
|
|
if ((ULONG)id <= 0 ||
|
|
(ULONG)id >= cProtocols)
|
|
{
|
|
dprintf("Invalid protocol ID %d\n", id);
|
|
return;
|
|
}
|
|
protocol = (ULONG)id;
|
|
pszProtocol = Protocols[protocol];
|
|
|
|
dprintf("Object (0x%p), protocol\t - %s\n", qwAddr, pszProtocol);
|
|
|
|
switch(type & PROTO_MASK)
|
|
{
|
|
case CONNECTION:
|
|
{
|
|
|
|
if ((type & TYPE_MASK) == CLIENT)
|
|
{
|
|
dprintf("Client-side connection\t\t - (%p)\n", type);
|
|
}
|
|
else if (type & SERVER)
|
|
{
|
|
dprintf("Server-side connection\t\t - (%p)\n", type);
|
|
}
|
|
else
|
|
{
|
|
dprintf("Unknown type %d\n", type);
|
|
break;
|
|
}
|
|
|
|
PRINT_ADDRESS_OF(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, Conn, tmp2);
|
|
PRINT_MEMBER_BOOLEAN(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, fAborted, tmp1);
|
|
PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, StartingReadIo, tmp1);
|
|
PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, StartingWriteIo, tmp1);
|
|
PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, iPostSize, tmp1);
|
|
|
|
ULONG64 Read;
|
|
GET_ADDRESS_OF(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, Read, Read, tmp2);
|
|
|
|
do_overlap(Read);
|
|
|
|
PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, pReadBuffer, tmp1);
|
|
PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, maxReadBuffer, tmp1);
|
|
PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, iLastRead, tmp1);
|
|
|
|
ULONG64 pAddress;
|
|
|
|
if (protocol == NMP)
|
|
{
|
|
GET_MEMBER(qwAddr, NMP_CONNECTION, RPCRT4!NMP_CONNECTION, pAddress, pAddress);
|
|
dprintf("Associated address\t\t - 0x%I64x\n", pAddress);
|
|
}
|
|
else if (protocol == TCP)
|
|
{
|
|
GET_MEMBER(qwAddr, WS_CONNECTION, RPCRT4!WS_CONNECTION, pAddress, pAddress);
|
|
dprintf("Associated address\t\t - 0x%I64x\n", pAddress);
|
|
}
|
|
else
|
|
{
|
|
GET_MEMBER(qwAddr, WS_CONNECTION, RPCRT4!WS_CONNECTION, saClientAddress, pAddress);
|
|
|
|
dprintf("Winsock sockaddr (server)\t - 0x%I64x\n", pAddress);
|
|
|
|
#ifdef NETBIOS_ON
|
|
if ( protocol == NBF
|
|
|| protocol == NBT
|
|
|| protocol == NBI)
|
|
{
|
|
ULONG64 SequenceNumber;
|
|
GET_MEMBER(qwAddr, NB_CONNECTION, RPCRT4!NB_CONNECTION, SequenceNumber, SequenceNumber);
|
|
// Netbios based connection has more state
|
|
dprintf("Netbios sequence number\t\t - %d\n", (ULONG)SequenceNumber);
|
|
}
|
|
else
|
|
#endif
|
|
if ((type & TYPE_MASK) == CLIENT)
|
|
{
|
|
// Client-side non-netbios connections have more state
|
|
PRINT_MEMBER(qwAddr, WS_CLIENT_CONNECTION, RPCRT4!WS_CLIENT_CONNECTION, fCallStarted, tmp1);
|
|
PRINT_MEMBER(qwAddr, WS_CLIENT_CONNECTION, RPCRT4!WS_CLIENT_CONNECTION, fShutdownReceived, tmp1);
|
|
PRINT_MEMBER(qwAddr, WS_CLIENT_CONNECTION, RPCRT4!WS_CLIENT_CONNECTION, fReceivePending, tmp1);
|
|
PRINT_MEMBER(qwAddr, WS_CLIENT_CONNECTION, RPCRT4!WS_CLIENT_CONNECTION, dwLastCallTime, tmp1);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case ADDRESS:
|
|
case DATAGRAM|ADDRESS:
|
|
{
|
|
dprintf("Address type\t\t\t - (%p)", type);
|
|
|
|
if (type & ~(PROTO_MASK | TYPE_MASK | IO_MASK))
|
|
{
|
|
dprintf(" unknown bits 0x%lx\n", type & ~(PROTO_MASK | TYPE_MASK | IO_MASK));
|
|
}
|
|
else
|
|
{
|
|
if (type & DATAGRAM)
|
|
dprintf(" d/g");
|
|
else
|
|
dprintf(" c/o");
|
|
|
|
if (type & SERVER)
|
|
dprintf(" server");
|
|
else
|
|
dprintf(" client or bit not set");
|
|
|
|
dprintf("\n");
|
|
}
|
|
|
|
ULONG64 Endpoint;
|
|
GET_MEMBER(qwAddr, BASE_ADDRESS, RPCRT4!BASE_ADDRESS, Endpoint, Endpoint);
|
|
|
|
if (Endpoint)
|
|
{
|
|
dprintf("Endpoint\t\t\t - %ws\n", ReadProcessRpcChar(Endpoint));
|
|
}
|
|
else
|
|
{
|
|
dprintf("Endpoint\t\t\t - (null)\n");
|
|
}
|
|
|
|
ULONG64 pAddressVector;
|
|
GET_MEMBER(qwAddr, BASE_ADDRESS, RPCRT4!BASE_ADDRESS, pAddressVector, pAddressVector);
|
|
|
|
if (pAddressVector)
|
|
{
|
|
do_addrvect(pAddressVector);
|
|
}
|
|
else
|
|
{
|
|
dprintf("No address vector\n");
|
|
}
|
|
|
|
ULONG64 SubmitListen;
|
|
GET_MEMBER(qwAddr, BASE_ADDRESS, RPCRT4!BASE_ADDRESS, SubmitListen, SubmitListen);
|
|
|
|
dprintf("SubmitListen (pfn)\t\t - 0x%I64x %s\n", SubmitListen,
|
|
MapSymbol(SubmitListen));
|
|
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, BASE_ADDRESS, RPCRT4!BASE_ADDRESS, pNext, "Next\t\t\t\t", tmp1);
|
|
|
|
if (
|
|
#ifdef IPX_ON
|
|
protocol != IPX &&
|
|
#endif
|
|
protocol != UDP &&
|
|
protocol != CDP)
|
|
{
|
|
GET_OFFSET_OF(CO_ADDRESS, RPCRT4!CO_ADDRESS, Listen, &tmp2);
|
|
do_overlap(qwAddr+tmp2);
|
|
|
|
ULONG64 NewConnection;
|
|
GET_MEMBER(qwAddr, CO_ADDRESS, RPCRT4!CO_ADDRESS, NewConnection, NewConnection);
|
|
|
|
dprintf("NewConnection (pfn)\t\t - 0x%I64x %s\n", NewConnection, MapSymbol(NewConnection));
|
|
}
|
|
|
|
#ifdef NETBIOS_ON
|
|
BOOL fNetbios = FALSE;
|
|
#endif
|
|
|
|
switch(protocol)
|
|
{
|
|
#ifdef NETBIOS_ON
|
|
case NBI:
|
|
case NBT:
|
|
case NBF:
|
|
fNetbios = TRUE;
|
|
// Fall into winsock case
|
|
#endif
|
|
|
|
case TCP:
|
|
#ifdef SPX_ON
|
|
case SPX:
|
|
#endif
|
|
|
|
#ifdef APPLETALK_ON
|
|
case DSP:
|
|
#endif
|
|
{
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, pFirstAddress, "Real address\t\t\t", tmp1);
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, pNextAddress, "Next address\t\t\t", tmp1);
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, ListenSocket, "Listen socket\t\t\t", tmp1);
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, ConnectionSocket, "Connect socket\t\t\t", tmp1);
|
|
|
|
#ifdef NETBIOS_ON
|
|
ULONG64 dwProtocolMultiplier;
|
|
GET_MEMBER(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, dwProtocolMultiplier, dwProtocolMultiplier);
|
|
|
|
if (dwProtocolMultiplier != 1
|
|
&& !fNetbios)
|
|
{
|
|
|
|
dprintf("Invalid protocol multipler (%d) for winsock address\n", (ULONG)dwProtocolMultiplier);
|
|
}
|
|
else
|
|
{
|
|
dprintf("Multipler\t\t\t - %d\n", (ULONG)dwProtocolMultiplier);
|
|
}
|
|
#endif
|
|
PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, AcceptBuffer, "AcceptBuffer\t\t\t", tmp2);
|
|
break;
|
|
}
|
|
|
|
case NMP:
|
|
{
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, NMP_ADDRESS, RPCRT4!NMP_ADDRESS, hConnectPipe, "Connect pipe\t\t\t", tmp1);
|
|
PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, NMP_ADDRESS, RPCRT4!NMP_ADDRESS, sparePipes, "Spare pipes\t\t\t", tmp2);
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, NMP_ADDRESS, RPCRT4!NMP_ADDRESS, SecurityDescriptor, "Security descriptor\t\t", tmp1);
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, NMP_ADDRESS, RPCRT4!NMP_ADDRESS, LocalEndpoint, "Local Endpoint\t\t\t", tmp1);
|
|
break;
|
|
}
|
|
|
|
case UDP:
|
|
#ifdef IPX_ON
|
|
case IPX:
|
|
#endif
|
|
case CDP:
|
|
{
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM_ENDPOINT, RPCRT4!WS_DATAGRAM_ENDPOINT, Socket, "The socket\t\t\t", tmp1);
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM_ENDPOINT, RPCRT4!WS_DATAGRAM_ENDPOINT, cPendingIos, "Pending recvs\t\t\t", tmp1);
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM_ENDPOINT, RPCRT4!WS_DATAGRAM_ENDPOINT, cMinimumIos, "Min recvs\t\t\t", tmp1);
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM_ENDPOINT, RPCRT4!WS_DATAGRAM_ENDPOINT, cMaximumIos, "Max recvs\t\t\t", tmp1);
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM_ENDPOINT, RPCRT4!WS_DATAGRAM_ENDPOINT, aDatagrams, "Array of datagrams\t\t", tmp1);
|
|
}
|
|
default:
|
|
{
|
|
dprintf("ERROR: Invalid/unknown protocol\n");
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case DATAGRAM:
|
|
{
|
|
dprintf("Datagram\t\t\t - (%p)\n", type);
|
|
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM, RPCRT4!WS_DATAGRAM, pEndpoint, "Pointer to owning address\t", tmp1);
|
|
PRINT_MEMBER_BOOLEAN_WITH_LABEL(qwAddr, WS_DATAGRAM, RPCRT4!WS_DATAGRAM, Busy, "Busy\t\t\t\t", tmp1);
|
|
PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM, RPCRT4!WS_DATAGRAM, AddressPair, "AddrPair\t\t\t", tmp1);
|
|
PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, WS_DATAGRAM, RPCRT4!WS_DATAGRAM, Packet, "Packet", tmp2);
|
|
|
|
GET_OFFSET_OF(WS_DATAGRAM, RPCRT4!WS_DATAGRAM, Read, &tmp2)
|
|
|
|
do_overlap(qwAddr + tmp2);
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
dprintf("Unknown type %d\n", type);
|
|
break;
|
|
}
|
|
|
|
dprintf("\n");
|
|
|
|
return;
|
|
}
|
|
|
|
char *strtok(char *String);
|
|
|
|
DECLARE_API( protocols )
|
|
{
|
|
ULONG64 qwAddr;
|
|
BOOL fArgNotSpecified = FALSE;
|
|
ULONG64 ProtocolArrayAddress;
|
|
|
|
LPSTR lpArgumentString = (LPSTR)args;
|
|
|
|
if (0 == strtok(lpArgumentString))
|
|
{
|
|
lpArgumentString = "rpcrt4!TransportProtocolArray";
|
|
fArgNotSpecified = TRUE;
|
|
}
|
|
|
|
qwAddr = GetExpression(lpArgumentString);
|
|
if ( !qwAddr )
|
|
{
|
|
dprintf("Error: can't evaluate '%s'\n", lpArgumentString);
|
|
return;
|
|
}
|
|
|
|
if (fArgNotSpecified)
|
|
{
|
|
if (ReadPtr(qwAddr, &ProtocolArrayAddress))
|
|
{
|
|
dprintf("couldn't read memory at address %I64x\n", qwAddr);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
ProtocolArrayAddress = qwAddr;
|
|
|
|
do_protocols(ProtocolArrayAddress);
|
|
}
|
|
|
|
const char *ProtocolStateNames[] = {"ProtocolNotLoaded", "ProtocolLoadedWithoutAddress" ,
|
|
"ProtocolWasLoadedOrNeedsAct.", "ProtocolLoaded",
|
|
"ProtocolWasLoadedOrNAWithoutAddr",
|
|
"ProtocolLoadedAndMonitored"};
|
|
|
|
VOID
|
|
do_protocols(
|
|
ULONG64 qwAddr
|
|
)
|
|
{
|
|
ULONG64 pTransportProtocol;
|
|
const char *pProtStateName;
|
|
ULONG64 ListHead;
|
|
ULONG64 ObjectEntry;
|
|
ULONG64 pCurrentObject;
|
|
int i;
|
|
BOOL fFirstObject;
|
|
BOOL b;
|
|
|
|
ULONG64 tmp1;
|
|
ULONG tmp2;
|
|
|
|
dprintf(" Protocol State AddrChngSock AddrChngOl\n");
|
|
dprintf("-----------------------------------------------------------------------\n");
|
|
|
|
pTransportProtocol = qwAddr;
|
|
|
|
for (i = 1; i < MAX_PROTOCOLS; i++)
|
|
{
|
|
fFirstObject = TRUE;
|
|
|
|
ULONG64 State;
|
|
ULONG64 addressChangeSocket;
|
|
ULONG64 addressChangeOverlapped;
|
|
|
|
GET_MEMBER(pTransportProtocol, TransportProtocol, RPCRT4!TransportProtocol, State, State);
|
|
GET_ADDRESS_OF(pTransportProtocol, TransportProtocol, RPCRT4!TransportProtocol, addressChangeSocket, addressChangeSocket, tmp2);
|
|
GET_ADDRESS_OF(pTransportProtocol, TransportProtocol, RPCRT4!TransportProtocol, addressChangeOverlapped, addressChangeOverlapped, tmp2);
|
|
|
|
if ((ULONG)State >= sizeof(ProtocolStateNames)/sizeof(ProtocolStateNames[0]))
|
|
pProtStateName = "INVALID";
|
|
else
|
|
pProtStateName = ProtocolStateNames[(ULONG)State];
|
|
|
|
dprintf("%13s%31s%15I64x%12I64x\n", Protocols[i], pProtStateName,
|
|
addressChangeSocket, addressChangeOverlapped);
|
|
|
|
GET_OFFSET_OF(TransportProtocol, RPCRT4!TransportProtocol, ObjectList, &tmp2);
|
|
ListHead = pTransportProtocol;
|
|
ListHead += tmp2;
|
|
|
|
ULONG64 ObjectList;
|
|
GET_ADDRESS_OF(pTransportProtocol, TransportProtocol, RPCRT4!TransportProtocol, ObjectList, ObjectList, tmp2);
|
|
ULONG64 Flink;
|
|
GET_MEMBER(ObjectList, _LIST_ENTRY, RPCRT4!_LIST_ENTRY, Flink, Flink);
|
|
|
|
ObjectEntry = Flink;
|
|
|
|
while (ObjectEntry != ListHead)
|
|
{
|
|
GET_OFFSET_OF(BASE_ASYNC_OBJECT, RPCRT4!BASE_ASYNC_OBJECT, ObjectList, &tmp2);
|
|
pCurrentObject = ObjectEntry;
|
|
pCurrentObject -= tmp2;
|
|
|
|
if (fFirstObject)
|
|
{
|
|
dprintf("Object List:\n");
|
|
fFirstObject = FALSE;
|
|
}
|
|
dprintf("%8lX\n", pCurrentObject);
|
|
// move to the next element in the list
|
|
GET_ADDRESS_OF(pCurrentObject, BASE_ASYNC_OBJECT, RPCRT4!BASE_ASYNC_OBJECT, ObjectList, ObjectList, tmp2);
|
|
GET_MEMBER(ObjectList, _LIST_ENTRY, RPCRT4!_LIST_ENTRY, Flink, Flink);
|
|
}
|
|
|
|
pTransportProtocol += GET_TYPE_SIZE(TransportProtocol, RPCRT4!TransportProtocol);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
do_overlap(
|
|
ULONG64 qwAddr
|
|
)
|
|
{
|
|
ULONG64 tmp1;
|
|
ULONG tmp2;
|
|
|
|
PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, BASE_OVERLAPPED, RPCRT4!BASE_OVERLAPPED, pAsyncObject, "Overlapped\t\t\t", tmp2);
|
|
|
|
ULONG64 ol;
|
|
GET_ADDRESS_OF(qwAddr, BASE_OVERLAPPED, RPCRT4!BASE_OVERLAPPED, ol, ol, tmp2);
|
|
|
|
PRINT_MEMBER_WITH_LABEL(ol, _OVERLAPPED, RPCRT4!_OVERLAPPED, Pointer, "Overlapped, containing object\t", tmp1);
|
|
|
|
PRINT_MEMBER_WITH_LABEL(ol, _OVERLAPPED, RPCRT4!_OVERLAPPED, Internal, "ol.Internal (status)\t\t", tmp1);
|
|
PRINT_MEMBER_WITH_LABEL(ol, _OVERLAPPED, RPCRT4!_OVERLAPPED, InternalHigh, "ol.InternalHigh\t\t\t", tmp1);
|
|
PRINT_MEMBER_WITH_LABEL(ol, _OVERLAPPED, RPCRT4!_OVERLAPPED, hEvent, "ol.hEvent\t\t\t", tmp1);
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
do_addrvect(
|
|
ULONG64 qwAddr
|
|
)
|
|
{
|
|
DWORD count;
|
|
BOOL b;
|
|
ULONG64 p;
|
|
|
|
GetData(qwAddr, &count, sizeof(count));
|
|
|
|
dprintf("Address vector entries\t\t - %d\n", count);
|
|
for (unsigned i = 0; i < count; i++)
|
|
{
|
|
ULONG64 tmp;
|
|
tmp = qwAddr + (i + 1) * AddressSize;
|
|
ReadPtr(tmp, &p);
|
|
dprintf("NetworkAddress[%d]\t\t - (0x%I64x) %ws\n",
|
|
i,
|
|
p,
|
|
ReadProcessRpcChar(p));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|