|
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме: 5339610
Репутация:
4360
|
|
Код:
struct CONST_DESCRIPTION {
ULONG Value;
LPSTR Desc;
#define DEFINE_STRING(x) { x, #x }
#define TABLE_END { 0, 0 }
};
CONST_DESCRIPTION MachineTypes[] = {
DEFINE_STRING( IMAGE_FILE_MACHINE_I386 ),
DEFINE_STRING( IMAGE_FILE_MACHINE_IA64 ),
TABLE_END
};
CONST_DESCRIPTION DumpTypes[] = {
DEFINE_STRING( DUMP_TYPE_TRIAGE ),
DEFINE_STRING( DUMP_TYPE_SUMMARY ),
DEFINE_STRING( DUMP_TYPE_FULL ),
TABLE_END
};
// Bugcheck descriptions
typedef ULONG NTSTATUS;
#include "D:\Progs\driverdev\bcdesc.h" // багчек коды бсодов, я не прилагаю этот файл, скажу лишь что там лежит функция BugCheckDescf, получающая имя бсода по его номеру.
// Получение имени константы по значению
LPSTR LookupConstDesc( CONST_DESCRIPTION* Table, ULONG Value )
{
while( Table->Desc ) {
if( Table->Value == Value ) {
return Table->Desc;
}
Table ++;
}
return "(unknown)";
}
void ExtractDumpHeader( MappedCrashDump* CrashDump, char* saveto )
{
HANDLE hFile = CreateFile( saveto, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0 );
DWORD wr;
WriteFile( hFile, CrashDump->lpMapping, 0x1000, &wr, 0 );
SetEndOfFile( hFile );
CloseHandle( hFile );
}
int AnalyseDump( char* filename )
{
MappedCrashDump CrashDump = {0};
CrashDump.hFile = INVALID_HANDLE_VALUE;
__try
{
CrashDump.hFile = CreateFile( filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0 );
if( CrashDump.hFile == INVALID_HANDLE_VALUE )
return 0;
CrashDump.hMapping = CreateFileMapping( CrashDump.hFile, 0, PAGE_READONLY, 0, 0, NULL );
if( CrashDump.hMapping == NULL )
return 0;
CrashDump.lpMapping = (PBYTE) MapViewOfFile( CrashDump.hMapping, FILE_MAP_READ, 0, 0, 0x10000 ); //0x12000 );
if( CrashDump.lpMapping == NULL )
return 0;
PDUMP_HEADER hdr = CrashDump.DumpHeader;
if( hdr->ValidDump != 'PMUD' || hdr->Signature != 'EGAP' ) {
printf("Invalid dump header\n");
return 0;
}
printf("Crash dump '%s' analysing started. Version: %d.%d\n\n", filename, hdr->MajorVersion, hdr->MinorVersion);
// Header
printf("CR3 = 0x%08x PfnDatabase = 0x%08x\n"
"PsLoadedModuleList = 0x%08x PsActiveProcessHead = 0x%08x\n", hdr->DirectoryTableBase, (ULONG_PTR)hdr->PfnDataBase,
(ULONG_PTR)hdr->PsLoadedModuleList, (ULONG_PTR)hdr->PsActiveProcessHead );
printf("Machine type: %s, NumberProcessors: %d\n", LookupConstDesc( MachineTypes, hdr->MachineImageType ), hdr->NumberProcessors);
printf("PaeEnabled = %d, KdDebuggerDataBlock = 0x%08x\n", hdr->PaeEnabled, (ULONG_PTR)hdr->KdDebuggerDataBlock);
printf("\n");
// Bug check
printf("Bugcheck code %s (0x%08x)\n", BugCheckDescf(hdr->BugCheckCode), hdr->BugCheckCode);
printf("Arguments[0] = 0x%08x\n", hdr->BugCheckParameter1);
printf("Arguments[1] = 0x%08x\n", hdr->BugCheckParameter2);
printf("Arguments[2] = 0x%08x\n", hdr->BugCheckParameter3);
printf("Arguments[3] = 0x%08x\n", hdr->BugCheckParameter4);
printf("\n");
// Data blocks
ULONG* block = CrashDump.DataBlocks;
// Dump type & size
CrashDump.DumpType = &block[ DH_DUMP_TYPE ];
CrashDump.DumpFlags = &block[ DH_DUMP_TYPE + 1 ];
CrashDump.DumpSize = (PLARGE_INTEGER) &block[ DH_REQUIRED_DUMP_SPACE ];
printf( "Dump type: %s, DumpSize: %d bytes (0x%08x)\n",
LookupConstDesc( DumpTypes, *CrashDump.DumpType ),
CrashDump.DumpSize->LowPart,
CrashDump.DumpSize->LowPart );
printf("\n");
// Physical memory descriptor
CrashDump.PhysicalMemoryDescriptor = (PPHYSICAL_MEMORY_DESCRIPTOR)( &block[DH_PHYSICAL_MEMORY_BLOCK] );
if( CrashDump.PhysicalMemoryDescriptor->NumberOfRuns == 'EGAP' )
{
printf("PPHYSICAL_MEMORY_DESCRIPTOR: Invalid\n");
}
else
{
printf( "PPHYSICAL_MEMORY_DESCRIPTOR:\nNumberOfRuns = 0x%08x NumberOfPages = 0x%08x\n",
CrashDump.PhysicalMemoryDescriptor->NumberOfRuns,
CrashDump.PhysicalMemoryDescriptor->NumberOfPages );
for( ULONG i=0;i<CrashDump.PhysicalMemoryDescriptor->NumberOfRuns;i++ )
{
printf( "PPHYSICAL_MEMORY_RUN[%d]: BasePage = 0x%08x PageCount = 0x%08x\n",
i,
CrashDump.PhysicalMemoryDescriptor->Run[i].BasePage,
CrashDump.PhysicalMemoryDescriptor->Run[i].PageCount );
}
}
printf("\n");
// Context record:
CrashDump.Context = (PCONTEXT)( &block[DH_CONTEXT_RECORD] );
printf( "Context record:\nEip = 0x%08x ESP = 0x%08x EBP = 0x%08x\n",
CrashDump.Context->Eip,
CrashDump.Context->Esp,
CrashDump.Context->Ebp );
printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x ESI=%08x EDI=%08x\n",
CrashDump.Context->Eax,
CrashDump.Context->Ebx,
CrashDump.Context->Ecx,
CrashDump.Context->Edx,
CrashDump.Context->Esi,
CrashDump.Context->Edi,
CrashDump.Context->Eax);
printf("\n");
// Analyse dump
if( *CrashDump.DumpType == DUMP_TYPE_TRIAGE )
{
//
// Minidump
//
CrashDump.pTriageDumpHeader = (PTRIAGE_DUMP_HEADER)( CrashDump.lpMapping + 0x1000 );
printf("Analysing triage dump header\n");
printf("[-] Not implemented\n");
__asm nop;
}
else if( *CrashDump.DumpType == DUMP_TYPE_SUMMARY )
{
//
// Kernel summary dump - only kernel address space available
//
CrashDump.pSummaryDumpHeader = (PSUMMARY_DUMP_HEADER) ( CrashDump.lpMapping + 0x1000 );
CrashDump.KernelMemoryMap.SizeOfBitMap = CrashDump.pSummaryDumpHeader->BitmapSize;
CrashDump.KernelMemoryMap.Buffer = (PULONG) ( CrashDump.pSummaryDumpHeader + 1 );
if( CrashDump.pSummaryDumpHeader->ValidDump != 'PMUD' ) {
printf("Invalid summary dump header\n");
return 0;
}
printf("Analyzing summary dump header\n");
printf( "HeaderSize = 0x%08x BitmapSize = 0x%08x\n",
CrashDump.pSummaryDumpHeader->HeaderSize,
CrashDump.pSummaryDumpHeader->BitmapSize );
printf( "Number of kernel pages in dump: 0x%08x\n\n",
CrashDump.pSummaryDumpHeader->Pages );
ULONG Virtual = CrashDump.Context->Eip;
ULONGLONG Physical;
Physical = VirtualToPhysical( &CrashDump, Virtual );
printf("Translating virtual address [0x%08x]: 0x%08x\n", Virtual, Physical);
PBYTE MappedEIP = (PBYTE)RetrieveDumpData( &CrashDump, (void*)(ULONG_PTR)CrashDump.Context->Eip );
if( MappedEIP )
{
printf("Bytes at [EIP=%08x]: %02x %02x %02x %02x %02x %02x %02x %02x\n", CrashDump.Context->Eip,
MappedEIP[0], MappedEIP[1], MappedEIP[2], MappedEIP[3],
MappedEIP[4], MappedEIP[5], MappedEIP[6], MappedEIP[7] );
}
else printf("Memory pointed by EIP is not present\n");
__asm nop;
}
else if( *CrashDump.DumpType == DUMP_TYPE_COMPLETE )
{
//
// Complete memory dump - full address space available
//
ULONG Virtual = CrashDump.Context->Eip;
ULONGLONG Physical;
Physical = VirtualToPhysical( &CrashDump, Virtual );
printf("Translating virtual address [0x%08x]: 0x%08x\n", Virtual, Physical);
PBYTE MappedEIP = (PBYTE)RetrieveDumpData( &CrashDump, (void*)(ULONG_PTR)CrashDump.Context->Eip );
printf("Bytes at [EIP=%08x]: %02x %02x %02x %02x %02x %02x %02x %02x\n", CrashDump.Context->Eip,
MappedEIP[0], MappedEIP[1], MappedEIP[2], MappedEIP[3],
MappedEIP[4], MappedEIP[5], MappedEIP[6], MappedEIP[7] );
ExtractDumpHeader( &CrashDump, "crashdump.hdr" );
__asm nop;
}
printf("\nDump analysis finished\n");
}
__finally
{
if( CrashDump.lpMapping )
UnmapViewOfFile( CrashDump.lpMapping );
if( CrashDump.hMapping )
CloseHandle( CrashDump.hMapping );
if( CrashDump.hFile != INVALID_HANDLE_VALUE )
CloseHandle( CrashDump.hFile );
Sleep(INFINITE);
}
return 0;
}
int main()
{
AnalyseDump( "C:\\gr8lkd.dmp" );
//AnalyseDump( "D:\\memory.dmp" );
return 0;
}
В нем уже забит путь к моему крешдампу c:\gr8lkd.dmp от моей утилиты gr8lkd.
Вывод примерно следующий:
Crash dump 'C:\gr8lkd.dmp' analysing started. Version: 15.2600
CR3 = 0x00373000 PfnDatabase = 0x80557b48
PsLoadedModuleList = 0x805531a0 PsActiveProcessHead = 0x80559258
Machine type: IMAGE_FILE_MACHINE_I386, NumberProcessors: 1
PaeEnabled = 1, KdDebuggerDataBlock = 0x80544ce0
Bugcheck code KMODE_EXCEPTION_NOT_HANDLED (0x0000001e)
Arguments[0] = 0x80000004
Arguments[1] = 0xf3b21315
Arguments[2] = 0x00000000
Arguments[3] = 0x00000000
Dump type: DUMP_TYPE_FULL, DumpSize: 536403968 bytes (0x1ff8e000)
PPHYSICAL_MEMORY_DESCRIPTOR:
NumberOfRuns = 0x00000003 NumberOfPages = 0x0001ff8d
PPHYSICAL_MEMORY_RUN[0]: BasePage = 0x00000001 PageCount = 0x0000009e
PPHYSICAL_MEMORY_RUN[1]: BasePage = 0x00000100 PageCount = 0x00000eff
PPHYSICAL_MEMORY_RUN[2]: BasePage = 0x00001000 PageCount = 0x0001eff0
Context record:
Eip = 0xf3b21315 ESP = 0xf8ab4928 EBP = 0xf8ab4c1c
EAX=00000000 EBX=816b7000 ECX=00000000 EDX=00004e24 ESI=00000000 EDI=f8ab4c00
Translating virtual address [0xf3b21315]: 0x1d9ac315
Bytes at [EIP=f3b21315]: 58 89 85 d0 fd ff ff 9c
Dump analysis finished
III. Создание собственного дампа.
Мы подошли к самому интересному моменту, а именно к созданию собственного файда дампа.
Сперва стоит описать недокументированную структуру KdDebuggerDataBlock, поскольку она нам очень поможет при создании дампа. Итак, по адресу KdDebuggerDataBlock лежит следующее:
Код:
template <class T>
struct PFUNC {
T VirtualAddress;
ULONG ZeroField;
};
typedef struct _KD_DEBUGGER_DATA_BLOCK {
ULONG Unknown1[4];
ULONG ValidBlock; // 'GBDK'
ULONG Size; // 0x290
PFUNC<PVOID> _imp__VidInitialize;
PFUNC<PVOID> RtlpBreakWithStatusInstruction;
ULONG Unknown2[4];
PFUNC<PVOID> KiCallUserMode;
ULONG Unknown3[2];
PFUNC<PVOID> PsLoadedModuleList;
PFUNC<PVOID> PsActiveProcessHead;
PFUNC<PVOID> PspCidTable;
PFUNC<PVOID> ExpSystemResourcesList;
PFUNC<PVOID> ExpPagedPoolDescriptor;
PFUNC<PVOID> ExpNumberOfPagedPools;
PFUNC<PVOID> KeTimeIncrement;
PFUNC<PVOID> KeBugCheckCallbackListHead;
PFUNC<PVOID> KiBugCheckData;
PFUNC<PVOID> IopErrorLogListHead;
PFUNC<PVOID> ObpRootDirectoryObject;
PFUNC<PVOID> ObpTypeObjectType;
PFUNC<PVOID> MmSystemCacheStart;
PFUNC<PVOID> MmSystemCacheEnd;
PFUNC<PVOID> MmSystemCacheWs;
PFUNC<PVOID> MmPfnDatabase;
PFUNC<PVOID> MmSystemPtesStart;
PFUNC<PVOID> MmSystemPtesEnd;
PFUNC<PVOID> MmSubsectionBase;
PFUNC<PVOID> MmNumberOfPagingFiles;
PFUNC<PVOID> MmLowestPhysicalPage;
PFUNC<PVOID> MmHighestPhysicalPage;
PFUNC<PVOID> MmNumberOfPhysicalPages;
PFUNC<PVOID> MmMaximumNonPagedPoolInBytes;
PFUNC<PVOID> MmNonPagedSystemStart;
PFUNC<PVOID> MmNonPagedPoolStart;
PFUNC<PVOID> MmNonPagedPoolEnd;
PFUNC<PVOID> MmPagedPoolStart;
PFUNC<PVOID> MmPagedPoolEnd;
PFUNC<PVOID> MmPagedPoolInfo;
PFUNC<PVOID> Unknown4;
PFUNC<PVOID> MmSizeOfPagedPoolInBytes;
PFUNC<PVOID> MmTotalCommitLimit;
PFUNC<PVOID> MmTotalCommittedPages;
PFUNC<PVOID> MmSharedCommit;
PFUNC<PVOID> MmDriverCommit;
PFUNC<PVOID> MmProcessCommit;
PFUNC<PVOID> MmPagedPoolCommit;
PFUNC<PVOID> Unknown5;
PFUNC<PVOID> MmZeroedPageListHead;
PFUNC<PVOID> MmFreePageListHead;
PFUNC<PVOID> MmStandbyPageListHead;
PFUNC<PVOID> MmModifiedPageListHead;
PFUNC<PVOID> MmModifiedNoWritePageListHead;
PFUNC<PVOID> MmAvailablePages;
PFUNC<PVOID> MmResidentAvailablePages;
PFUNC<PVOID> PoolTrackTable;
PFUNC<PVOID> NonPagedPoolDescriptor;
PFUNC<PVOID> MmHighestUserAddress;
PFUNC<PVOID> MmSystemRangeStart;
PFUNC<PVOID> MmUserProbeAddress;
PFUNC<PVOID> KdPrintCircularBuffer;
PFUNC<PVOID> KdPrintWritePointer;
PFUNC<PVOID> KdPrintWritePointer2;
PFUNC<PVOID> KdPrintRolloverCount;
PFUNC<PVOID> MmLoadedUserImageList;
PFUNC<PVOID> NtBuildLab;
PFUNC<PVOID> Unknown6;
PFUNC<PVOID> KiProcessorBlock;
PFUNC<PVOID> MmUnloadedDrivers;
PFUNC<PVOID> MmLastUnloadedDriver;
PFUNC<PVOID> MmTriageActionTaken;
PFUNC<PVOID> MmSpecialPoolTag;
PFUNC<PVOID> KernelVerifier;
PFUNC<PVOID> MmVerifierData;
PFUNC<PVOID> MmAllocateNonPagedPool;
PFUNC<PVOID> MmPeakCommitment;
PFUNC<PVOID> MmTotalCommitLimitMaximum;
PFUNC<PVOID> CmNtCSDVersion;
PFUNC<PPHYSICAL_MEMORY_DESCRIPTOR*> MmPhysicalMemoryBlock;
PFUNC<PVOID> MmSessionBase;
PFUNC<PVOID> MmSessionSize;
PFUNC<PVOID> Unknown7;
} KD_DEBUGGER_DATA_BLOCK, *PKD_DEBUGGER_DATA_BLOCK;
|