Показать сообщение отдельно

  #3  
Старый 07.09.2007, 19:39
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию

Код:
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;
 
Ответить с цитированием