PyObject * wipe_CheckControlC(PyObject * self, PyObject * args) { if (!PyArg_ParseTuple(args, "")) { return NULL; } return Py_BuildValue("k", CheckControlC()); }
__inline VOID CheckForBreak() /*++ Purpose: Encapsulate control c checking code Arguments: None Return: None, raises if break is needed --*/ { if ( CheckControlC() ) { RaiseException(0, EXCEPTION_NONCONTINUABLE, 0, NULL); } }
VOID InOrderTraversal(ULONG_PTR pNode) { HRESULT hRes=S_OK; PULONG pOffset=NULL; BYTE* pBuffer=NULL; ULONG ulData=0; ULONG ulLeft=0; ULONG ulRight=0; if(CheckControlC()==TRUE) { dprintf ("Control C hit, canceling command\n" ); return; } if(!pNode) { return; } if(FAILED(hRes=GetNodeValues(pNode, &ulData, &ulLeft, &ulRight))) { return; } if(ulLeft) { InOrderTraversal(ulLeft); delete[] pBuffer; } PrintNode(ulLeft, ulData, ulRight); if(ulRight) { InOrderTraversal(ulRight); delete[] pBuffer; } }
VOID EnumSockets( PENUM_SOCKETS_CALLBACK Callback, LPVOID Context ) /*++ Routine Description: Enumerates all sockets in the target process, invoking the specified callback for each socket. Arguments: Callback - Points to the callback to invoke for each socket. Context - An uninterpreted context value passed to the callback routine. Return Value: None. --*/ { PSOCKET_INFORMATION sockInfo; LIST_ENTRY listEntry; PLIST_ENTRY nextEntry; ULONG listHead; ULONG result; DWORD i; SOCKET_INFORMATION localSocket; listHead = GetExpression( "msafd!SocketListHead" ); if( listHead == 0 ) { dprintf( "cannot find msafd!SocketListHead\n" ); return; } if( !ReadMemory( (DWORD)listHead, &listEntry, sizeof(listEntry), &result ) ) { dprintf( "EnumSockets: cannot read msafd!SocketListHead @ %08lx\n", listHead ); } nextEntry = listEntry.Flink; while( nextEntry != (PLIST_ENTRY)listHead ) { if( CheckControlC() ) { break; } sockInfo = CONTAINING_RECORD( nextEntry, SOCKET_INFORMATION, SocketListEntry ); if( !ReadMemory( (DWORD)sockInfo, &localSocket, sizeof(localSocket), &result ) ) { dprintf( "EnumSockets: cannot read SOCKET_INFORMATION @ %08lx\n", sockInfo ); return; } nextEntry = localSocket.SocketListEntry.Flink; if( !(Callback)( &localSocket, (DWORD)sockInfo, Context ) ) { break; } } } // EnumSockets
VOID DumpDevice( PVOID DeviceAddress, BOOLEAN FullDetail ) /*++ Routine Description: Displays the driver name for the device object if FullDetail == FALSE. Otherwise displays more information about the device and the device queue. Arguments: DeviceAddress - address of device object to dump. FullDetail - TRUE means the device object name, driver name, and information about Irps queued to the device. Return Value: None --*/ { ULONG result; ULONG i; PUCHAR buffer; DEVICE_OBJECT deviceObject; UNICODE_STRING unicodeString; PLIST_ENTRY nextEntry; PVOID queueAddress; PIRP irp; KDEVICE_QUEUE_ENTRY queueEntry; POBJECT_HEADER pObjectHeader; OBJECT_HEADER objectHeader; POBJECT_HEADER_NAME_INFO pNameInfo; OBJECT_HEADER_NAME_INFO NameInfo; if ((!ReadMemory( (DWORD)DeviceAddress, &deviceObject, sizeof(deviceObject), &result)) || (result < sizeof(deviceObject))) { dprintf("%08lx: Could not read device object\n", DeviceAddress); return; } if (deviceObject.Type != IO_TYPE_DEVICE) { dprintf("%08lx: is not a device object\n", DeviceAddress); return; } if (FullDetail == TRUE) { // // Dump the device name if present. // pObjectHeader = OBJECT_TO_OBJECT_HEADER(DeviceAddress); if (ReadMemory( (DWORD)pObjectHeader, &objectHeader, sizeof(objectHeader), &result) && (result == sizeof(objectHeader))) { pNameInfo = KD_OBJECT_HEADER_TO_NAME_INFO( pObjectHeader, &objectHeader ); if (ReadMemory((DWORD)pNameInfo, &NameInfo, sizeof(NameInfo), &result) && (result == sizeof(NameInfo))) { buffer = LocalAlloc(LPTR, NameInfo.Name.MaximumLength); if (buffer != NULL) { unicodeString.MaximumLength = NameInfo.Name.MaximumLength; unicodeString.Length = NameInfo.Name.Length; unicodeString.Buffer = (PWSTR)buffer; if (ReadMemory((DWORD)NameInfo.Name.Buffer, buffer, unicodeString.Length, &result) && (result == unicodeString.Length)) { dprintf(" %wZ", &unicodeString); } LocalFree(buffer); } } } } DumpDriver((PVOID) deviceObject.DriverObject, FALSE); if (FullDetail == TRUE) { // // Dump Irps related to driver. // dprintf(" DriverObject %08lx\n", deviceObject.DriverObject); dprintf("Current Irp %08lx RefCount %d Type %08lx ", deviceObject.CurrentIrp, deviceObject.ReferenceCount, deviceObject.DeviceType); if (deviceObject.AttachedDevice) { dprintf("AttachedDev %08lx ", deviceObject.AttachedDevice); } if (deviceObject.Vpb) { dprintf("Vpb %08lx ", deviceObject.Vpb); } dprintf("DevExt %08lx\n", deviceObject.DeviceExtension); if (deviceObject.DeviceQueue.Busy) { if (IsListEmpty(&deviceObject.DeviceQueue.DeviceListHead)) { dprintf("Device queue is busy -- Queue empty\n"); } else { dprintf("DeviceQueue: "); nextEntry = deviceObject.DeviceQueue.DeviceListHead.Flink; i = 0; while ((PCH) nextEntry != (PCH) ((PCH) DeviceAddress + ((PCH) &deviceObject.DeviceQueue.DeviceListHead.Flink - (PCH) &deviceObject))) { queueAddress = CONTAINING_RECORD(nextEntry, KDEVICE_QUEUE_ENTRY, DeviceListEntry); if ((!ReadMemory((DWORD)queueAddress, &queueEntry, sizeof(queueEntry), &result)) || (result < sizeof(queueEntry))) { dprintf("%08lx: Could not read queue entry\n", DeviceAddress); return; } irp = CONTAINING_RECORD(&queueEntry, IRP, Tail.Overlay.DeviceQueueEntry); dprintf("%08lx%s", irp, (i & 0x03) == 0x03 ? "\n\t " : " "); if (CheckControlC()) { break; } } dprintf("\n"); } } else { dprintf("Device queue is not busy.\n"); } } }
VOID DumpFcb ( IN ULONG Address, IN ULONG Options ) /*++ Routine Description: Dump a specific fcb. Arguments: Address - Gives the address of the fcb to dump Return Value: None --*/ { PLIST_ENTRY Head; LIST_ENTRY ListEntry; PLIST_ENTRY Next; ULONG Result; PFCB pFcb; FCB Fcb; PFCB_DATA pFcbData; FCB_DATA FcbData; PSCB pScb; PLCB pLcb; dprintf( "\n Fcb @ %08lx", Address ); pFcb = (PFCB) Address; if ( !ReadMemory( (DWORD) pFcb, &Fcb, sizeof( Fcb ), &Result) ) { dprintf( "%08lx: Unable to read pFcb\n", pFcb ); return; } // // Before we get into too much trouble, make sure this looks like an fcb. // // // Type of an fcb record must be NTFS_NTC_FCB // if (Fcb.NodeTypeCode != NTFS_NTC_FCB) { dprintf( "\nFCB signature does not match, probably not an FCB" ); return; } // // Having established that this looks like an fcb, let's dump the // interesting parts. // PrintState( FcbState, Fcb.FcbState ); DUMP_WITH_OFFSET( FCB, Fcb, CleanupCount, "CleanupCount: " ); DUMP_WITH_OFFSET( FCB, Fcb, CloseCount, "CloseCount: " ); DUMP_WITH_OFFSET( FCB, Fcb, ReferenceCount, "ReferenceCount: " ); DUMP_WITH_OFFSET( FCB, Fcb, FcbState, "FcbState: " ); DUMP_WITH_OFFSET( FCB, Fcb, FcbDenyDelete, "FcbDenyDelete: " ); DUMP_WITH_OFFSET( FCB, Fcb, FcbDeleteFile, "FcbDeleteFile: " ); DUMP_WITH_OFFSET( FCB, Fcb, BaseExclusiveCount, "BaseExclusiveCount: " ); DUMP_WITH_OFFSET( FCB, Fcb, EaModificationCount, "EaModificationCount:" ); DUMP_WITH_OFFSET( FCB, Fcb, InfoFlags, "InfoFlags: " ); DUMP_WITH_OFFSET( FCB, Fcb, LinkCount, "LinkCount: " ); DUMP_WITH_OFFSET( FCB, Fcb, TotalLinks, "TotalLinks: " ); DUMP_WITH_OFFSET( FCB, Fcb, CurrentLastAccess, "CurrentLastAccess: " ); DUMP_WITH_OFFSET( FCB, Fcb, CreateSecurityCount, "CreateSecurityCount:" ); DUMP_WITH_OFFSET( FCB, Fcb, DelayedCloseCount, "DelayedCloseCount: " ); // // walk the queue of links for this file // if ( !ReadMemory( (DWORD) &(pFcb->LcbQueue), &ListEntry, sizeof( ListEntry ), &Result) ) { dprintf( "%08lx: Unable to read pFcb->LcbQueue\n", pFcb->LcbQueue ); return; } dprintf( "\n Links:" ); Head = &(pFcb->LcbQueue); Next = ListEntry.Flink; while (Next != Head) { if ( !ReadMemory( (DWORD)Next, &ListEntry, sizeof( ListEntry ), &Result) ) { dprintf( "%08lx: Unable to read list\n", Next ); return; } pLcb = CONTAINING_RECORD( Next, LCB, FcbLinks ); if (Options >= 1) { DumpLcb( (ULONG) pLcb, Options - 1 ); } else { dprintf( "\n Lcb: %08lx", (DWORD) pLcb ); } if (CheckControlC()) { return; } Next = ListEntry.Flink; } dprintf( "\n" ); // // Walk the queue of streams for this file. // if ( !ReadMemory( (DWORD) &(pFcb->ScbQueue), &ListEntry, sizeof( ListEntry ), &Result) ) { dprintf( "%08lx: Unable to read pFcb->ScbQueue\n", pFcb->ScbQueue ); return; } dprintf( "\n Streams:" ); Head = &(pFcb->ScbQueue); Next = ListEntry.Flink; while (Next != Head) { if ( !ReadMemory( (DWORD)Next, &ListEntry, sizeof( ListEntry ), &Result) ) { dprintf( "%08lx: Unable to read list\n", Next ); return; } pScb = CONTAINING_RECORD( Next, SCB, FcbLinks ); if (Options >= 1) { DumpScb( (ULONG) pScb, Options - 1 ); } else { dprintf( "\n Scb: %08lx", (DWORD) pScb ); } if (CheckControlC()) { return; } Next = ListEntry.Flink; } dprintf( "\n" ); return; }
VOID DumpNtfsData ( IN ULONG Address, IN ULONG Options ) /*++ Routine Description: Dump the list of Vcbs for the global NtfsData. Arguments: Address - Gives the address of the NtfsData to dump Options - If 1, we recurse into the Vcbs and dump them Return Value: None --*/ { PLIST_ENTRY Head; ULONG Result; LIST_ENTRY ListEntry; PLIST_ENTRY Next; PNTFS_DATA pNtfsData; NTFS_DATA NtfsData; PVCB pVcb; dprintf( "\n NtfsData @ %08lx", Address ); pNtfsData = (PNTFS_DATA) Address; if ( !ReadMemory( (DWORD) pNtfsData, &NtfsData, sizeof( NtfsData ), &Result) ) { dprintf( "%08lx: Unable to read pNtfsData\n", pNtfsData ); return; } if (NtfsData.NodeTypeCode != NTFS_NTC_DATA_HEADER) { dprintf( "\nNtfsData signature does not match, probably not an NtfsData" ); return; } if ( !ReadMemory( (DWORD) &(pNtfsData->VcbQueue), &ListEntry, sizeof( ListEntry ), &Result) ) { dprintf( "%08lx: Unable to read pNtfsData->VcbQueue\n", pNtfsData->VcbQueue ); return; } dprintf( "\n Mounted volumes:" ); Head = &(pNtfsData->VcbQueue); Next = ListEntry.Flink; while (Next != Head) { if ( !ReadMemory( (DWORD)Next, &ListEntry, sizeof( ListEntry ), &Result) ) { dprintf( "%08lx: Unable to read list\n", Next ); return; } pVcb = CONTAINING_RECORD( Next, VCB, VcbLinks ); if (Options >= 1) { DumpVcb( (ULONG) pVcb, Options - 1 ); } else { dprintf( "\n Vcb: %08lx", (DWORD) pVcb ); } if (CheckControlC()) { return; } Next = ListEntry.Flink; } dprintf( "\n" ); return; }
VOID DumpAfdConnectionReferenceDebug( PAFD_REFERENCE_DEBUG ReferenceDebug, DWORD ActualAddress ) /*++ Routine Description: Dumps the AFD_REFERENCE_DEBUG structures associated with an AFD_CONNECTION object. Arguments: ReferenceDebug - Points to an array of AFD_REFERENCE_DEBUG structures. There are assumed to be MAX_REFERENCE entries in this array. ActualAddress - The actual address where the array resides on the debugee. Return Value: None. --*/ { ULONG i; ULONG result; LPSTR fileName; CHAR filePath[MAX_PATH]; CHAR action[16]; dprintf( "AFD_REFERENCE_DEBUG @ %08lx\n", ActualAddress ); for( i = 0 ; i < MAX_REFERENCE ; i++, ReferenceDebug++ ) { if( CheckControlC() ) { break; } if( ReferenceDebug->Info1 == NULL && ReferenceDebug->Info2 == NULL && ReferenceDebug->Action == 0 && ReferenceDebug->NewCount == 0 ) { break; } if( ReferenceDebug->Action == 0 || ReferenceDebug->Action == 1 || ReferenceDebug->Action == (ULONG)-1L ) { sprintf( action, "%ld", ReferenceDebug->Action ); } else { sprintf( action, "%08lx", ReferenceDebug->Action ); } switch( (DWORD)ReferenceDebug->Info1 ) { case 0xafdafd02 : dprintf( " %3lu: Buffered Send, IRP @ %08lx [%s] -> %lu\n", i, ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0xafdafd03 : dprintf( " %3lu: Nonbuffered Send, IRP @ %08lx [%s] -> %lu\n", i, ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0xafd11100 : case 0xafd11101 : dprintf( " %3lu: AfdRestartSend (%08lx), IRP @ %08lx [%s] -> %lu\n", i, ReferenceDebug->Info1, ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0xafd11102 : case 0xafd11103 : case 0xafd11104 : case 0xafd11105 : dprintf( " %3lu: AfdRestartBufferSend (%08lx), IRP @ %08lx [%s] -> %lu\n", i, ReferenceDebug->Info1, ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0 : if( ReferenceDebug->Info2 == NULL ) { dprintf( " %3lu: AfdDeleteConnectedReference (%08lx)\n", i, ReferenceDebug->Action ); break; } else { // // Fall through to default case. // } default : if( ReadMemory( (DWORD)ReferenceDebug->Info1, filePath, sizeof(filePath), &result ) ) { fileName = strrchr( filePath, '\\' ); if( fileName != NULL ) { fileName++; } else { fileName = filePath; } } else { sprintf( filePath, "%08lx", ReferenceDebug->Info1 ); fileName = filePath; } dprintf( " %3lu: %s:%lu [%s] -> %lu\n", i, fileName, ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; } } } // DumpAfdConnectionReferenceDebug
BOOL DumpAfdGlobalReferenceDebug( PAFD_GLOBAL_REFERENCE_DEBUG ReferenceDebug, DWORD ActualAddress, DWORD CurrentSlot, DWORD StartingSlot, DWORD NumEntries, DWORD CompareAddress ) /*++ Routine Description: Dumps the AFD_GLOBAL_REFERENCE_DEBUG structures. Arguments: ReferenceDebug - Points to an array of AFD_GLOBAL_REFERENCE_DEBUG structures. There are assumed to be MAX_GLOBAL_REFERENCE entries in this array. ActualAddress - The actual address where the array resides on the debugee. CurrentSlot - The last slot used. CompareAddress - If zero, then dump all records. Otherwise, only dump those records with a matching connection pointer. Return Value: None. --*/ { ULONG result; LPSTR fileName; CHAR decoration; CHAR filePath[MAX_PATH]; CHAR action[16]; BOOL foundEnd = FALSE; ULONG lowTick; if( StartingSlot == 0 ) { dprintf( "AFD_GLOBAL_REFERENCE_DEBUG @ %08lx, Current Slot = %lu\n", ActualAddress, CurrentSlot ); } for( ; NumEntries > 0 ; NumEntries--, StartingSlot++, ReferenceDebug++ ) { if( CheckControlC() ) { foundEnd = TRUE; break; } if( ReferenceDebug->Info1 == NULL && ReferenceDebug->Info2 == NULL && ReferenceDebug->Action == 0 && ReferenceDebug->NewCount == 0 && ReferenceDebug->Connection == NULL ) { foundEnd = TRUE; break; } if( CompareAddress != 0 && ReferenceDebug->Connection != (PVOID)CompareAddress ) { continue; } if( ReferenceDebug->Action == 0 || ReferenceDebug->Action == 1 || ReferenceDebug->Action == (ULONG)-1L ) { sprintf( action, "%ld", ReferenceDebug->Action ); } else { sprintf( action, "%08lx", ReferenceDebug->Action ); } decoration = ( StartingSlot == CurrentSlot ) ? '>' : ' '; lowTick = ReferenceDebug->TickCounter.LowPart; switch( (DWORD)ReferenceDebug->Info1 ) { case 0xafdafd02 : dprintf( "%c %3lu: %08lx (%8lu) Buffered Send, IRP @ %08lx [%s] -> %lu\n", decoration, StartingSlot, ReferenceDebug->Connection, lowTick, ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0xafdafd03 : dprintf( "%c %3lu: %08lx (%8lu) Nonbuffered Send, IRP @ %08lx [%s] -> %lu\n", decoration, StartingSlot, ReferenceDebug->Connection, lowTick, ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0xafd11100 : case 0xafd11101 : dprintf( "%c %3lu: %08lx (%8lu) AfdRestartSend (%08lx), IRP @ %08lx [%s] -> %lu\n", decoration, StartingSlot, ReferenceDebug->Connection, lowTick, ReferenceDebug->Info1, ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0xafd11102 : case 0xafd11103 : case 0xafd11104 : case 0xafd11105 : dprintf( "%c %3lu: %08lx (%8lu) AfdRestartBufferSend (%08lx), IRP @ %08lx [%s] -> %lu\n", decoration, StartingSlot, ReferenceDebug->Connection, lowTick, ReferenceDebug->Info1, ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; case 0 : if( ReferenceDebug->Info2 == NULL ) { dprintf( "%c %3lu: %08lx (%8lu) AfdDeleteConnectedReference (%08lx)\n", decoration, StartingSlot, ReferenceDebug->Connection, lowTick, ReferenceDebug->Action ); break; } else { // // Fall through to default case. // } default : if( ReadMemory( (DWORD)ReferenceDebug->Info1, filePath, sizeof(filePath), &result ) ) { fileName = strrchr( filePath, '\\' ); if( fileName != NULL ) { fileName++; } else { fileName = filePath; } } else { sprintf( filePath, "%08lx", ReferenceDebug->Info1 ); fileName = filePath; } dprintf( "%c %3lu: %08lx (%8lu) %s:%lu [%s] -> %lu\n", decoration, StartingSlot, ReferenceDebug->Connection, lowTick, fileName, ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); break; } } return foundEnd; } // DumpAfdGlobalReferenceDebug
VOID DumpAfdEndpointReferenceDebug( PAFD_REFERENCE_DEBUG ReferenceDebug, DWORD ActualAddress ) /*++ Routine Description: Dumps the AFD_REFERENCE_DEBUG structures associated with an AFD_ENDPOINT object. Arguments: ReferenceDebug - Points to an array of AFD_REFERENCE_DEBUG structures. There are assumed to be MAX_REFERENCE entries in this array. ActualAddress - The actual address where the array resides on the debugee. Return Value: None. --*/ { ULONG i; ULONG result; LPSTR fileName; CHAR filePath[MAX_PATH]; CHAR action[16]; dprintf( "AFD_REFERENCE_DEBUG @ %08lx\n", ActualAddress ); for( i = 0 ; i < MAX_REFERENCE ; i++, ReferenceDebug++ ) { if( CheckControlC() ) { break; } if( ReferenceDebug->Info1 == NULL && ReferenceDebug->Info2 == NULL && ReferenceDebug->Action == 0 && ReferenceDebug->NewCount == 0 ) { break; } if( ReferenceDebug->Action == 0 || ReferenceDebug->Action == 1 || ReferenceDebug->Action == (ULONG)-1L ) { sprintf( action, "%ld", ReferenceDebug->Action ); } else { sprintf( action, "%08lx", ReferenceDebug->Action ); } if( ReadMemory( (DWORD)ReferenceDebug->Info1, filePath, sizeof(filePath), &result ) ) { fileName = strrchr( filePath, '\\' ); if( fileName != NULL ) { fileName++; } else { fileName = filePath; } } else { sprintf( filePath, "%08lx", ReferenceDebug->Info1 ); fileName = filePath; } dprintf( " %3lu: %s:%lu [%s] -> %ld\n", i, fileName, ReferenceDebug->Info2, action, ReferenceDebug->NewCount ); } } // DumpAfdEndpointReferenceDebug
VOID EnumEndpoints( PENUM_ENDPOINTS_CALLBACK Callback, LPVOID Context ) /*++ Routine Description: Enumerates all AFD_ENDPOINT structures in the system, invoking the specified callback for each endpoint. Arguments: Callback - Points to the callback to invoke for each AFD_ENDPOINT. Context - An uninterpreted context value passed to the callback routine. Return Value: None. --*/ { PAFD_ENDPOINT endpoint; LIST_ENTRY listEntry; PLIST_ENTRY nextEntry; ULONG listHead; ULONG result; DWORD i; AFD_ENDPOINT localEndpoint; listHead = GetExpression( "afd!AfdEndpointListHead" ); if( listHead == 0 ) { dprintf( "cannot find afd!AfdEndpointlistHead\n" ); return; } if( !ReadMemory( (DWORD)listHead, &listEntry, sizeof(listEntry), &result ) ) { dprintf( "EnumEndpoints: cannot read afd!AfdEndpointlistHead @ %08lx\n", listHead ); } nextEntry = listEntry.Flink; while( nextEntry != (PLIST_ENTRY)listHead ) { if( CheckControlC() ) { break; } endpoint = CONTAINING_RECORD( nextEntry, AFD_ENDPOINT, GlobalEndpointListEntry ); if( !ReadMemory( (DWORD)endpoint, &localEndpoint, sizeof(localEndpoint), &result ) ) { dprintf( "EnumEndpoints: cannot read AFD_ENDPOINT @ %08lx\n", endpoint ); return; } nextEntry = localEndpoint.GlobalEndpointListEntry.Flink; if( !(Callback)( &localEndpoint, (DWORD)endpoint, Context ) ) { break; } } } // EnumEndpoints