|
|
#include "precomp.h"
//
// The ExtensionApis is a mandatory global variable, which should
// have this exact name. All definitions of callbacks to the windbg
// are using this variable.
//
WINDBG_EXTENSION_APIS ExtensionApis; USHORT g_MajorVersion; USHORT g_MinorVersion;
//
// Prototypes
//
VOID PrintCf( PCF_BLOCK pCf );
VOID PrintClient( PCLIENT_BLOCK pClient );
VOID PrintBlob( PBLOB_BLOCK pBlob );
VOID PrintPattern( PPATTERN_BLOCK pPattern );
VOID PrintStat( PGPC_STAT pStat );
BOOL GetDwordExpr( char* expr, DWORD* pdwAddress, DWORD* pValue );
//
// API's
//
LPEXT_API_VERSION ExtensionApiVersion( void )
/*++
Function Description:
Windbg calls this function to match between the version of windbg and the extension. If the versions doesn't match, windbg will not load the extension.
--*/
{ static EXT_API_VERSION ApiVersion = { 3, 5, EXT_API_VERSION_NUMBER, 0 };
return &ApiVersion; }
void WinDbgExtensionDllInit( PWINDBG_EXTENSION_APIS lpExtensionApis, USHORT MajorVersion, USHORT MinorVersion )
/*++
Function Description:
When windbg loads the extension, it first call this function. You can perform various intialization here.
Arguments:
lpExtensionApis - A structure that contains the callbacks to functions that I can use to do standard operation. I must store this in a global variable called 'ExtensionApis'.
MajorVersion - Indicates if target machine is running checked build or free. 0x0C - Checked build. 0x0F - Free build.
MinorVersion - The Windows NT build number (for example, 1381 for NT4).
--*/
{ ExtensionApis = *lpExtensionApis;
g_MajorVersion = MajorVersion; g_MinorVersion = MinorVersion; }
DECLARE_API( version ) { #if DBG
PCHAR DebuggerType = "Checked"; #else
PCHAR DebuggerType = "Free"; #endif
dprintf("KDGPC: %s Extension dll for Build %d debugging %s kernel for Build %d\n", DebuggerType, VER_PRODUCTBUILD, g_MajorVersion == 0x0c ? "Checked" : "Free", g_MinorVersion ); }
VOID CheckVersion( VOID )
/*++
Function Description:
This function is called before every command. It gives the extension a chance to compare between the versions of the target and the extension. In this demo, I don't do much with that.
--*/
{ #if DBG
if ((g_MajorVersion != 0x0c) || (g_MinorVersion != VER_PRODUCTBUILD)) { dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n", (VER_PRODUCTBUILD, g_MinorVersion, g_MajorVersion==0x0f) ? "Free" : "Checked" ); } #else
// if ((g_MajorVersion != 0x0f) || (g_MinorVersion != VER_PRODUCTBUILD)) {
// dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n",
// (VER_PRODUCTBUILD, g_MinorVersion, (g_MajorVersion==0x0f) ? "Free" : "Checked" );
// }
#endif
}
DECLARE_API( help )
/*++
Function Description:
This is the implementation of the '!help' extension command. It lists all available command in this debugger extension.
--*/
{ dprintf( "help - shows this list\n" "cf - print the CF list\n" "client [addr] - print the client block" "blob [addr] - print the blob list for the QoS CF, or the specified blob\n" "pattern [addr] - print the pattern block\n" "stat - print the statistics" ); }
DECLARE_API( cf )
/*++
Function Description:
This function prints all the CF in the list. If args is specified, only that CF will be printed. Currently these are supported:
0 - for CF_QOS
--*/
{ DWORD TargetGlobalData; GLOBAL_BLOCK LocalGlobalData; PLIST_ENTRY pHead, pEntry; DWORD TargetCf; CF_BLOCK LocalCf; ULONG result; ULONG CfIndex = (-1); char *lerr;
TargetGlobalData = GetExpression( "MSGPC!glData" );
if( !TargetGlobalData ) { dprintf( "Can't find the address of 'glData'" ); return; }
//
if ( !ReadMemory( TargetGlobalData, &LocalGlobalData, sizeof(LocalGlobalData), &result )) {
dprintf( "Can't read memory from 0x%x", TargetGlobalData ); return; }
//
//
//
if ( args ) CfIndex = strtol( args, &lerr, 10 );
pHead = (PLIST_ENTRY)((PUCHAR)TargetGlobalData + FIELD_OFFSET(GLOBAL_BLOCK, CfList)); pEntry = LocalGlobalData.CfList.Flink;
while ( pHead != pEntry ) {
TargetCf = (DWORD)CONTAINING_RECORD( pEntry, CF_BLOCK, Linkage );
if ( !ReadMemory( TargetCf, &LocalCf, sizeof(LocalCf), &result ) ) {
dprintf( "Can't read memory from 0x%x", TargetCf );
} else if ( CfIndex == (-1) || LocalCf.AssignedIndex == CfIndex ) {
PrintCf( &LocalCf ); }
pEntry = LocalCf.Linkage.Flink;
}
}
DECLARE_API( blob )
/*++
Function Description:
This function prints all the blob in the QoS CF list. If args is specified it is used as the blob addr.
--*/
{ DWORD TargetGlobalData; GLOBAL_BLOCK LocalGlobalData; PLIST_ENTRY pHead, pEntry; DWORD TargetCf; CF_BLOCK LocalCf; ULONG result; ULONG TargetBlob = 0; BLOB_BLOCK LocalBlob; char *lerr;
if ( args ) TargetBlob = GetExpression( args );
if (TargetBlob) {
if ( !ReadMemory( TargetBlob, &LocalBlob, sizeof(LocalBlob), &result ) ) {
dprintf( "Can't read memory from 0x%x", TargetBlob );
} else {
PrintBlob( &LocalBlob ); } return; }
#if 0
//
// scan the blob list for the QoS CF
//
TargetGlobalData = GetExpression( "MSGPC!glData" );
if( !TargetGlobalData ) { dprintf( "Can't find the address of 'glData'" ); return; }
//
if ( !ReadMemory( TargetGlobalData, &LocalGlobalData, sizeof(LocalGlobalData), &result )) {
dprintf( "Can't read memory from 0x%x", TargetGlobalData ); return; }
//
//
//
pHead = (PLIST_ENTRY)((PUCHAR)TargetGlobalData + FIELD_OFFSET(GLOBAL_BLOCK, CfList)); pEntry = LocalGlobalData.CfList.Flink;
while ( pHead != pEntry ) {
TargetCf = (DWORD)CONTAINING_RECORD( pEntry, CF_BLOCK, Linkage );
if ( !ReadMemory( TargetCf, &LocalCf, sizeof(LocalCf), &result ) ) {
dprintf( "Can't read memory from 0x%x", TargetCf );
} else if ( CfIndex == (-1) || LocalCf.AssignedIndex == CfIndex ) {
PrintCf( &LocalCf ); }
pEntry = LocalCf.Linkage.Flink;
} #endif
}
DECLARE_API( client )
/*++
Function Description:
This function prints either the client addr or all the clients
--*/
{ DWORD TargetGlobalData; GLOBAL_BLOCK LocalGlobalData; PLIST_ENTRY pHead, pEntry; PLIST_ENTRY pHead1, pEntry1; DWORD TargetCf; CF_BLOCK LocalCf; ULONG result; ULONG TargetClient = 0; CLIENT_BLOCK LocalClient; int i = 0;
if ( args ) TargetClient = GetExpression( args );
if (TargetClient) {
if ( !ReadMemory( TargetClient, &LocalClient, sizeof(LocalClient), &result ) ) {
dprintf( "Can't read memory from 0x%x", TargetClient );
} else {
dprintf( "Client = 0x%X: ", TargetClient ); PrintClient( &LocalClient ); } return; }
//
// scan the client list for the QoS CF
//
TargetGlobalData = GetExpression( "MSGPC!glData" );
if( !TargetGlobalData ) { dprintf( "Can't find the address of 'glData'" ); return; }
//
if ( !ReadMemory( TargetGlobalData, &LocalGlobalData, sizeof(LocalGlobalData), &result )) {
dprintf( "Can't read memory from 0x%x", TargetGlobalData ); return; }
//
//
//
pHead = (PLIST_ENTRY)((PUCHAR)TargetGlobalData + FIELD_OFFSET(GLOBAL_BLOCK, CfList)); pEntry = LocalGlobalData.CfList.Flink;
while ( pHead != pEntry ) {
TargetCf = (DWORD)CONTAINING_RECORD( pEntry, CF_BLOCK, Linkage );
if ( !ReadMemory( TargetCf, &LocalCf, sizeof(LocalCf), &result ) ) {
dprintf( "Can't read memory from 0x%x", TargetCf ); return;
} else {
dprintf( "\nClients for CF=%d\n", LocalCf.AssignedIndex );
pHead1 = (PLIST_ENTRY)((PUCHAR)TargetCf + FIELD_OFFSET(CF_BLOCK, ClientList)); pEntry1 = LocalCf.ClientList.Flink;
while ( pHead1 != pEntry1 ) {
TargetClient = (DWORD)CONTAINING_RECORD( pEntry1, CLIENT_BLOCK, ClientLinkage );
if ( !ReadMemory( TargetClient, &LocalClient, sizeof(LocalClient), &result ) ) {
dprintf( "Can't read memory from 0x%x", TargetClient ); return;
} else {
dprintf( "Client [%d] = 0x%X: ", i++, TargetClient ); PrintClient( &LocalClient ); } pEntry1 = LocalClient.ClientLinkage.Flink; } }
pEntry = LocalCf.Linkage.Flink;
} }
BOOL GetDwordExpr( char* expr, DWORD* pdwAddress, DWORD* pValue )
/*++
Function Description:
This function gets as an argument a string which represent a DWORD variable. The funciton finds its address (if the symbols are loaded), and then grab the dword value from that address.
Arguments:
expr [in] - A null terminated string, represent the variable.
pdwAddress [out, optional] - Optinally return the address of the variable.
pValue [out] - returns the value of the DWORD variable.
Return Value:
true/false, if the function succeeded or failed.
--*/
{ ULONG result; DWORD dwAddress;
if( pdwAddress ) *pdwAddress = 0; *pValue = 0;
dwAddress = GetExpression( expr ); if( !dwAddress ) return FALSE;
if( !ReadMemory( dwAddress, pValue, sizeof(DWORD), &result ) ) return FALSE;
if( pdwAddress ) *pdwAddress = dwAddress;
return TRUE; }
VOID PrintCf( PCF_BLOCK pCf )
/*++
Function Description:
This function gets as an argument a CF block pointer, and does a pretty print.
Arguments:
pCf - pointer to CF block
Return Value:
none
--*/
{ int i;
dprintf( " Linkage = { 0x%X, 0x%X }\n", pCf->Linkage.Flink, pCf->Linkage.Blink ); dprintf( " ClientList = { 0x%X, 0x%X }\n", pCf->ClientList.Flink, pCf->ClientList.Blink ); dprintf( " BlobList = { 0x%X, 0x%X }\n", pCf->BlobList.Flink, pCf->BlobList.Blink ); dprintf( " NumberOfClients = %d\n", pCf->NumberOfClients ); dprintf( " AssignedIndex = 0x%x\n", pCf->AssignedIndex ); dprintf( " ClientIndexes = %d\n", pCf->ClientIndexes ); dprintf( " MaxPriorities = %d\n", pCf->MaxPriorities ); dprintf( " arpGenericDb = 0x%X\n", &pCf->arpGenericDb );
for ( i = GPC_PROTOCOL_TEMPLATE_IP; i < GPC_PROTOCOL_TEMPLATE_MAX; i++ ) {
dprintf( " [%d] = %d\n", i, (ULONG)pCf->arpGenericDb[i] );
} }
VOID PrintBlob( PBLOB_BLOCK pBlob )
/*++
Function Description:
This function gets as an argument a BLOB block pointer, and does a pretty print.
Arguments:
pBlob - pointer to BLOB block
Return Value:
none
--*/
{ int i;
dprintf( " ObjectType = %d\n", pBlob->ObjectType ); dprintf( " ClientLinkage = { 0x%X, 0x%X }\n", pBlob->ClientLinkage.Flink, pBlob->ClientLinkage.Blink ); dprintf( " PatternList = { 0x%X, 0x%X }\n", pBlob->PatternList.Flink, pBlob->PatternList.Blink ); dprintf( " CfLinkage = { 0x%X, 0x%X }\n", pBlob->CfLinkage.Flink, pBlob->CfLinkage.Blink ); dprintf( " RefCount = %d\n", pBlob->RefCount ); dprintf( " State = 0x%x\n", pBlob->State );
dprintf( " arClientCtx[]:\n" ); for ( i = 0; i < MAX_CLIENTS_CTX_PER_BLOB; i++ ) {
dprintf( " [%d] = 0x%x\n", i, (ULONG)pBlob->arClientCtx[i] );
}
}
VOID PrintClient( PCLIENT_BLOCK pClient )
/*++
Function Description:
This function gets as an argument a CLIENT block pointer, and does a pretty print.
Arguments:
pClient - pointer to CLIENT block
Return Value:
none
--*/
{ DWORD TargetCf; CF_BLOCK LocalCf; ULONG result;
TargetCf = (DWORD)pClient->pCfBlock;
if ( !ReadMemory( TargetCf, &LocalCf, sizeof(LocalCf), &result ) ) {
dprintf( "Can't read memory from 0x%x", TargetCf ); return; }
if (pClient->Flags & GPC_FLAGS_USERMODE_CLIENT) { dprintf( " User Mode Client\n" ); } else { if (GetExpression( "PSCHED!AddCfInfoNotify" ) == (DWORD)pClient->FuncList.ClAddCfInfoNotifyHandler && (LocalCf.AssignedIndex == GPC_CF_QOS || LocalCf.AssignedIndex == GPC_CF_CLASS_MAP)) { dprintf( " Probably PSCHED client\n" ); } else if (GetExpression( "TCPIP!GPCcfInfoAddNotify" ) == (DWORD)pClient->FuncList.ClAddCfInfoNotifyHandler && (LocalCf.AssignedIndex == GPC_CF_QOS || LocalCf.AssignedIndex == GPC_CF_IPSEC)) { dprintf( " Probably TCPIP client\n" ); } else if (GetExpression( "ATMARPC!AtmArpGpcAddCfInfoComplete" ) == (DWORD)pClient->FuncList.ClAddCfInfoNotifyHandler && (LocalCf.AssignedIndex == GPC_CF_QOS)) { dprintf( " Probably ATMARPC client\n" ); } else if (0 == (DWORD)pClient->FuncList.ClAddCfInfoNotifyHandler && (LocalCf.AssignedIndex == GPC_CF_IPSEC)) { dprintf( " Probably IPSEC client\n" ); } else { dprintf( " Unknown client\n" ); } }
dprintf( " ObjectType = %d\n", pClient->ObjectType ); dprintf( " ClientLinkage = { 0x%X, 0x%X }\n", pClient->ClientLinkage.Flink, pClient->ClientLinkage.Blink ); dprintf( " BlobList = { 0x%X, 0x%X }\n", pClient->BlobList.Flink, pClient->BlobList.Blink ); dprintf( " Parrent CF = 0x%X\n", pClient->pCfBlock ); dprintf( " Client Ctx = 0x%X\n", pClient->ClientCtx ); dprintf( " AssignedIndex = %d\n", pClient->AssignedIndex ); dprintf( " Flags = 0x%X %s %s \n", pClient->Flags, (pClient->Flags & GPC_FLAGS_USERMODE_CLIENT)?"UserMode":"" , (pClient->Flags & GPC_FLAGS_FRAGMENT)?"Handle Fragments":"" ); dprintf( " State = %d\n", pClient->State ); dprintf( " RefCount = %d\n", pClient->RefCount ); dprintf( " File Object = 0x%X\n", pClient->pFileObject ); dprintf( " Client Handle = %d\n", pClient->ClHandle );
dprintf( " Client Handlers:\n" ); dprintf( " Add Notify = 0x%X\n", pClient->FuncList.ClAddCfInfoCompleteHandler ); dprintf( " Add Complete = 0x%X\n", pClient->FuncList.ClAddCfInfoNotifyHandler ); dprintf( " Modify Notify = 0x%X\n", pClient->FuncList.ClModifyCfInfoCompleteHandler ); dprintf( " Modify Complete = 0x%X\n", pClient->FuncList.ClModifyCfInfoNotifyHandler ); dprintf( " Remove Notify = 0x%X\n", pClient->FuncList.ClRemoveCfInfoCompleteHandler ); dprintf( " Remove Complete = 0x%X\n", pClient->FuncList.ClRemoveCfInfoNotifyHandler ); dprintf( " Get CfInfo Name = 0x%X\n", pClient->FuncList.ClGetCfInfoName );
}
VOID PrintPattern( PPATTERN_BLOCK pPattern )
/*++
Function Description:
This function gets as an argument a PATTERN block pointer, and does a pretty print.
Arguments:
pPattern - pointer to PATTERN block
Return Value:
none
--*/
{ int i;
dprintf( " ObjectType = %d\n", pPattern->ObjectType ); dprintf( " BlobLinkage[]:\n" ); for ( i = 0; i < GPC_CF_MAX; i++ ) {
dprintf( " [%d] = {0x%X,0x%X}\n", i, pPattern->BlobLinkage[i].Flink, pPattern->BlobLinkage[i].Blink ); } dprintf( " TimerLinkage = { 0x%X, 0x%X }\n", pPattern->TimerLinkage.Flink, pPattern->TimerLinkage.Blink ); dprintf( " Owner client = 0x%X\n", pPattern->pClientBlock ); dprintf( " Auto client = 0x%X\n", pPattern->pAutoClient ); dprintf( " Classification block = 0x%X\n", pPattern->pClassificationBlock ); dprintf( " Ref Count = %d\n", pPattern->RefCount ); dprintf( " Client Ref Count = %d\n", pPattern->ClientRefCount ); dprintf( " Flags = 0x%x %s %s \n", pPattern->Flags , (pPattern->Flags & PATTERN_SPECIFIC)?"Specific":"", (pPattern->Flags & PATTERN_AUTO)?"Auto":"" ); dprintf( " Priority = %d\n", pPattern->Priority ); dprintf( " Client handle = 0x%x\n", pPattern->ClHandle ); dprintf( " Protocol = 0x%x\n", pPattern->ProtocolTemplate ); }
VOID PrintStat( PGPC_STAT pStat )
/*++
Function Description:
Prints the GPC stat structure
Arguments:
pStat - pointer to GPC stat strucutre
Return Value:
none
--*/
{ PPROTOCOL_STAT pProtocol; int i;
dprintf( "Created CF = %d\n", pStat->CreatedCf ); dprintf( "Deleted Cf = %d\n", pStat->DeletedCf ); dprintf( "Rejected Cf = %d\n", pStat->RejectedCf ); dprintf( "Current Cf = %d\n", pStat->CurrentCf ); dprintf( "Inserted HF= %d\n", pStat->InsertedHF ); dprintf( "Removed HF= %d\n", pStat->RemovedHF );
for( i = 0; i < GPC_CF_MAX; i++) {
dprintf( "CF[%d] info:\n", i); dprintf( " Created Blobs = %d\n", pStat->CfStat[i].CreatedBlobs ); dprintf( " Modified Blobs = %d\n", pStat->CfStat[i].ModifiedBlobs ); dprintf( " Deleted Blobs = %d\n", pStat->CfStat[i].DeletedBlobs ); dprintf( " Rejected Blobs = %d\n", pStat->CfStat[i].RejectedBlobs ); dprintf( " Current Blobs = %d\n", pStat->CfStat[i].CurrentBlobs ); dprintf( " Deref Blobs to zero = %d\n", pStat->CfStat[i].DerefBlobs2Zero ); dprintf( "\n" ); }
pProtocol = &pStat->ProtocolStat[GPC_PROTOCOL_TEMPLATE_IP]; dprintf( "IP stats: Specific Patterns Generic Patterns Auto Patterns\n" ); dprintf( " Created = %8d %8d %8d\n", pProtocol->CreatedSp, pProtocol->CreatedGp, pProtocol->CreatedAp ); dprintf( " Deleted = %8d %8d %8d\n", pProtocol->DeletedSp, pProtocol->DeletedGp, pProtocol->DeletedAp ); dprintf( " Rejected = %8d %8d %8d\n", pProtocol->RejectedSp, pProtocol->RejectedGp, pProtocol->RejectedAp ); dprintf( " Current = %8d %8d %8d\n", pProtocol->CurrentSp, pProtocol->CurrentGp, pProtocol->CurrentAp ); dprintf( "\n" ); dprintf( " Classification Requests = %d\n", pProtocol->ClassificationRequests ); dprintf( " Patterns Classified = %d\n", pProtocol->PatternsClassified ); dprintf( " Packets Classified = %d\n", pProtocol->PacketsClassified ); dprintf( "\n" ); dprintf( " Deref Patterns to zero = %d\n", pProtocol->DerefPattern2Zero ); dprintf( " First Frags Count = %d\n", pProtocol->FirstFragsCount ); dprintf( " Last Frags Count = %d\n", pProtocol->LastFragsCount ); dprintf( "\n" ); dprintf( " Inserted PH= %d\n", pProtocol->InsertedPH ); dprintf( " Removed PH= %d\n", pProtocol->RemovedPH ); dprintf( " Inserted Rz= %d\n", pProtocol->InsertedRz ); dprintf( " Removed Rz= %d\n", pProtocol->RemovedRz ); dprintf( " Inserted CH= %d\n", pProtocol->InsertedCH ); dprintf( " Removed CH= %d\n", pProtocol->RemovedCH );
}
DECLARE_API( pattern )
/*++
Function Description:
This function prints all the pattern in the QoS CF list. If args is specified it is used as the blob addr.
--*/
{ DWORD TargetGlobalData; GLOBAL_BLOCK LocalGlobalData; PLIST_ENTRY pHead, pEntry; DWORD TargetCf; CF_BLOCK LocalCf; ULONG result; ULONG TargetPattern = 0; PATTERN_BLOCK LocalPattern; char *lerr;
if ( args ) TargetPattern = GetExpression( args );
if (TargetPattern) {
if ( !ReadMemory( TargetPattern, &LocalPattern, sizeof(LocalPattern), &result ) ) {
dprintf( "Can't read memory from 0x%x", TargetPattern );
} else {
PrintPattern( &LocalPattern ); } return; }
#if 0
//
// scan the blob list for the QoS CF
//
TargetGlobalData = GetExpression( "MSGPC!glData" );
if( !TargetGlobalData ) { dprintf( "Can't find the address of 'glData'" ); return; }
//
if ( !ReadMemory( TargetGlobalData, &LocalGlobalData, sizeof(LocalGlobalData), &result )) {
dprintf( "Can't read memory from 0x%x", TargetGlobalData ); return; }
//
//
//
pHead = (PLIST_ENTRY)((PUCHAR)TargetGlobalData + FIELD_OFFSET(GLOBAL_BLOCK, CfList)); pEntry = LocalGlobalData.CfList.Flink;
while ( pHead != pEntry ) {
TargetCf = (DWORD)CONTAINING_RECORD( pEntry, CF_BLOCK, Linkage );
if ( !ReadMemory( TargetCf, &LocalCf, sizeof(LocalCf), &result ) ) {
dprintf( "Can't read memory from 0x%x", TargetCf );
} else if ( CfIndex == (-1) || LocalCf.AssignedIndex == CfIndex ) {
PrintCf( &LocalCf ); }
pEntry = LocalCf.Linkage.Flink;
} #endif
}
DECLARE_API( stat )
/*++
Function Description:
This function prints all the stat structure
--*/
{ DWORD TargetStat; GPC_STAT LocalStat; PLIST_ENTRY pHead, pEntry; DWORD TargetCf; CF_BLOCK LocalCf; ULONG result;
TargetStat = GetExpression( "MSGPC!glStat" );
if( !TargetStat ) { dprintf( "Can't find the address of 'glStat'" ); return; }
if ( !ReadMemory( TargetStat, &LocalStat, sizeof(LocalStat), &result ) ) {
dprintf( "Can't read memory from 0x%x", TargetStat );
} else {
PrintStat( &LocalStat ); }
}
DECLARE_API( autopatterns )
/*++
Function Description:
This function prints all the CF in the list. If args is specified, only that CF will be printed. Currently these are supported:
0 - for CF_QOS
--*/
{ DWORD TargetGlobalData, TargetProtocolBlock; GLOBAL_BLOCK LocalGlobalData; PROTOCOL_BLOCK LocalProtocolBlock; PLIST_ENTRY pHead, pEntry; LIST_ENTRY listentry; DWORD TargetPattern; PATTERN_BLOCK LocalPattern; ULONG result; INT i, j; ULONG CfIndex = (-1); char *lerr;
TargetGlobalData = GetExpression( "MSGPC!glData" );
if( !TargetGlobalData ) { dprintf( "Can't find the address of 'glData'" ); return; }
//
if ( !ReadMemory( TargetGlobalData, &LocalGlobalData, sizeof(LocalGlobalData), &result )) {
dprintf( "Can't read memory from 0x%x", TargetGlobalData ); return; }
//
//
//
TargetProtocolBlock = (DWORD) LocalGlobalData.pProtocols; if ( !ReadMemory( TargetProtocolBlock, &LocalProtocolBlock, sizeof(LocalProtocolBlock), &result )) {
dprintf( "Can't read memory from 0x%x", TargetProtocolBlock ); return; }
for (i = 0; i < NUMBER_OF_WHEELS; i++) {
j = 0;
pHead = (PLIST_ENTRY) ((DWORD)TargetProtocolBlock + (i * sizeof(listentry))); pEntry = LocalProtocolBlock.TimerPatternList[i].Flink; dprintf("Printing TimerWheel %d Head = %X and pEntry = %X ******************\n", i, pHead, pEntry);
while ( (pHead != pEntry) && (j < 1000) ) {
j++; TargetPattern = (DWORD)CONTAINING_RECORD( pEntry, PATTERN_BLOCK, TimerLinkage );
if ( !ReadMemory( TargetPattern, &LocalPattern, sizeof(LocalPattern), &result ) ) {
dprintf( "Can't read memory from 0x%x", TargetPattern );
} else {
dprintf("Pattern = %X and ClassificationBlock = %X\n", TargetPattern, LocalPattern.pClassificationBlock); // PrintPattern( &LocalPattern );
}
pEntry = LocalPattern.TimerLinkage.Flink;
} } dprintf("Done printing all Timer Wheels\n");
}
|