#define TARGET_i386 #include #include #include #include #include #include #include "dumpexam.h" #define GetContext(p,c) GetContextX86(p,c) #define MAX_STACK_FRAMES 100 #define SAVE_EBP(f) f.Reserved[0] #define TRAP_TSS(f) f.Reserved[1] #define TRAP_EDITED(f) f.Reserved[1] #define SAVE_TRAP(f) f.Reserved[2] extern FILE *FileOut; VOID PrintRegisters( ULONG Processor, PCONTEXT Context, PKSPECIAL_REGISTERS SpecialRegContext ); static DWORD GetStackTrace( PDUMP_HEADER DmpHeader, ULONG Processor, LPSTACKFRAME Frames, ULONG MaxFrames, ULONG ProgramCounter, ULONG FramePointer, ULONG StackPointer ) { BOOL rVal; STACKFRAME StackFrame; DWORD FrameCnt; ZeroMemory( &StackFrame, sizeof(STACKFRAME) ); // // setup the program counter // StackFrame.AddrPC.Offset = ProgramCounter; StackFrame.AddrPC.Mode = AddrModeFlat; // // setup the frame pointer // StackFrame.AddrFrame.Offset = FramePointer; StackFrame.AddrFrame.Mode = AddrModeFlat; // // setup the stack pointer // StackFrame.AddrStack.Offset = StackPointer; StackFrame.AddrStack.Mode = AddrModeFlat; FrameCnt = 0; do { rVal = StackWalk( IMAGE_FILE_MACHINE_I386, (HANDLE)DmpHeader, (HANDLE)Processor, &StackFrame, NULL, SwReadMemory, SwFunctionTableAccess, SwGetModuleBase, NULL ); if (rVal) { CopyMemory( &Frames[FrameCnt], &StackFrame, sizeof(STACKFRAME) ); FrameCnt += 1; } } while( rVal && FrameCnt < MaxFrames ); return FrameCnt; } static VOID PrintStackTrace( PDUMP_HEADER DmpHeader, ULONG Processor, LPSTACKFRAME StackFrames, ULONG FrameCnt ) { PFPO_DATA pFpoData; PIMAGEHLP_SYMBOL Symbol; ULONG i; ULONG Displacement; CHAR SymBuf[512]; PrintHeading( "Stack Trace" ); fprintf( FileOut, "ChildEBP RetAddr Args to Child\n" ); for (i=0; iName ); } else { sprintf( SymBuf, "0x%08x", StackFrames[i].AddrPC.Offset ); } fprintf( FileOut, "%08x %08x %08x %08x %08x %s", StackFrames[i].AddrFrame.Offset, StackFrames[i].AddrReturn.Offset, StackFrames[i].Params[0], StackFrames[i].Params[1], StackFrames[i].Params[2], SymBuf ); if (Displacement) { fprintf( FileOut, "+0x%x", Displacement ); } if (StackFrames[i].FuncTableEntry) { pFpoData = (PFPO_DATA)StackFrames[i].FuncTableEntry; switch (pFpoData->cbFrame) { case FRAME_FPO: if (pFpoData->fHasSEH) { fprintf( FileOut, "(FPO: [SEH])" ); } else { fprintf( FileOut, " (FPO:" ); if (pFpoData->fUseBP) { fprintf( FileOut, " [EBP 0x%08x]", SAVE_EBP(StackFrames[i]) ); } fprintf( FileOut, " [%d,%d,%d])", pFpoData->cdwParams, pFpoData->cdwLocals, pFpoData->cbRegs ); } break; case FRAME_TRAP: fprintf( FileOut, " (FPO: [%d,%d] TrapFrame%s @ %08lx)", pFpoData->cdwParams, pFpoData->cdwLocals, TRAP_EDITED(StackFrames[i]) ? "" : "-EDITED", SAVE_TRAP(StackFrames[i]) ); break; case FRAME_TSS: fprintf( FileOut, " (FPO: TaskGate %lx:0)", TRAP_TSS(StackFrames[i]) ); break; default: fprintf( FileOut, "(UKNOWN FPO TYPE)" ); break; } } fprintf( FileOut, "\n" ); } fprintf( FileOut, "\n" ); } VOID PrintStackTraceX86( PDUMP_HEADER DmpHeader, ULONG Processor ) { PFPO_DATA pFpoData; CONTEXT Context; STACKFRAME StackFrames[MAX_STACK_FRAMES]; ULONG FrameCnt; ULONG i; CHAR buf[32]; GetContext( Processor, &Context ); FrameCnt = GetStackTrace( DmpHeader, Processor, StackFrames, MAX_STACK_FRAMES, Context.Eip, Context.Ebp, Context.Esp ); PrintStackTrace( DmpHeader, Processor, StackFrames, FrameCnt ); for (i=0; icbFrame == FRAME_TRAP) { sprintf( buf, "%08x", SAVE_TRAP(StackFrames[i]) ); DoExtension( "trap", buf, Processor, (DWORD)GetRegisterValue( &Context, REG_IP ) ); fprintf( FileOut, "\n" ); } } } } VOID BugCheckHeuristicsX86( PDUMP_HEADER DmpHeader, ULONG Processor ) { STACKFRAME StackFrames[MAX_STACK_FRAMES]; ULONG FrameCnt; PIMAGEHLP_SYMBOL Symbol; ULONG i; ULONG cb; ULONG Ptrs[2]; CHAR buf[32]; CONTEXT Context; if (DmpHeader->BugCheckCode == KMODE_EXCEPTION_NOT_HANDLED) { PrintHeading( "Dump Analysis Heuristics for Bugcode %s", GetBugText(DmpHeader->BugCheckCode) ); fprintf( FileOut, "Exception Code: 0x%08x\n", DmpHeader->BugCheckParameter1 ); fprintf( FileOut, "Address of Exception: 0x%08x\n", DmpHeader->BugCheckParameter2 ); fprintf( FileOut, "Parameter #0: 0x%08x\n", DmpHeader->BugCheckParameter3 ); fprintf( FileOut, "Parameter #1: 0x%08x\n\n", DmpHeader->BugCheckParameter4 ); if (!SymGetSymFromName( DmpHeader, "PspUnhandledExceptionInSystemThread", sym )) { return; } GetContext( Processor, &Context ); FrameCnt = GetStackTrace( DmpHeader, Processor, StackFrames, MAX_STACK_FRAMES, Context.Eip, Context.Ebp, Context.Esp ); for (i=0; i= sym->Address && StackFrames[i].AddrPC.Offset < sym->Address + sym->Size) { break; } } if (i == FrameCnt) { return; } cb = DmpReadMemory( (PVOID)StackFrames[i].Params[0], Ptrs, sizeof(Ptrs) ); if (cb != sizeof(Ptrs)) { return; } GetContext( Processor, &Context ); sprintf( buf, "%08x", Ptrs[0] ); DoExtension( "exr", buf, Processor, (DWORD)GetRegisterValue( &Context, REG_IP ) ); cb = DmpReadMemory( (PVOID)Ptrs[1], &Context, sizeof(Context) ); if (cb != sizeof(Context)) { return; } PrintRegisters( Processor, &Context, NULL ); FrameCnt = GetStackTrace( DmpHeader, Processor, StackFrames, MAX_STACK_FRAMES, Context.Eip, Context.Ebp, Context.Esp ); PrintStackTrace( DmpHeader, Processor, StackFrames, FrameCnt ); DoDisassemble( Context.Eip ); } if (DmpHeader->BugCheckCode == IRQL_NOT_LESS_OR_EQUAL) { PrintHeading( "Dump Analysis Heuristics for Bugcode %s", GetBugText(DmpHeader->BugCheckCode) ); fprintf( FileOut, "Invalid Address Referenced: 0x%08x\n", DmpHeader->BugCheckParameter1 ); fprintf( FileOut, "IRQL: %d\n", DmpHeader->BugCheckParameter2 ); fprintf( FileOut, "Access Type: %s\n", DmpHeader->BugCheckParameter3 ? "Read" : "Write" ); fprintf( FileOut, "Code Address: 0x%08x\n\n", DmpHeader->BugCheckParameter4 ); sprintf( buf, "%08x", DmpHeader->BugCheckParameter1 ); GetContext( Processor, &Context ); DoExtension( "pool", buf, Processor, (DWORD)GetRegisterValue( &Context, REG_IP ) ); } } ULONGLONG GetRegisterValueX86( PCONTEXT Context, ULONG Register ) { ULONG Value = 0; switch( Register ) { case REG_IP: Value = Context->Eip; break; case REG_FP: Value = Context->Ebp; break; case REG_SP: Value = Context->Esp; break; } return (LONG)Value; } VOID GetContextX86( ULONG Processor, PVOID Context ) { DmpGetContext( Processor, Context ); } #define FLAGIOPL 1 #define FLAGVIP 2 #define FLAGVIF 3 #define FLAGOF 4 #define FLAGDF 5 #define FLAGIF 6 #define FLAGSF 7 #define FLAGZF 8 #define FLAGAF 9 #define FLAGPF 10 #define FLAGCF 11 static ULONG GetFlag( ULONG FlagsReg, ULONG Flag ) { switch( Flag ) { case FLAGIOPL: return ((FlagsReg >> 12) & 3); case FLAGVIP: return ((FlagsReg >> 20) & 1); case FLAGVIF: return ((FlagsReg >> 19) & 1); case FLAGOF: return ((FlagsReg >> 11) & 1); case FLAGDF: return ((FlagsReg >> 10) & 1); case FLAGIF: return ((FlagsReg >> 9) & 1); case FLAGSF: return ((FlagsReg >> 7) & 1); case FLAGZF: return ((FlagsReg >> 6) & 1); case FLAGAF: return ((FlagsReg >> 4) & 1); case FLAGPF: return ((FlagsReg >> 2) & 1); case FLAGCF: return ((FlagsReg >> 0) & 1); } return 0; } VOID PrintRegistersX86( ULONG Processor ) { CONTEXT Context; KSPECIAL_REGISTERS SpecialRegContext; ULONG cb; GetContext( Processor, &Context ); DmpReadControlSpace( (USHORT)Processor, (PVOID)sizeof(CONTEXT), (PVOID)&SpecialRegContext, sizeof(KSPECIAL_REGISTERS), &cb ); PrintRegisters( Processor, &Context, &SpecialRegContext ); } static VOID PrintRegisters( ULONG Processor, PCONTEXT Context, PKSPECIAL_REGISTERS SpecialRegContext ) { PrintHeading( "Register Dump For Processor #%d", Processor ); fprintf( FileOut, "eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n", Context->Eax, Context->Ebx, Context->Ecx, Context->Edx, Context->Esi, Context->Edi ); fprintf( FileOut, "eip=%08x esp=%08x ebp=%08x ", Context->Eip, Context->Esp, Context->Ebp ); fprintf( FileOut, "iopl=%1x %s %s %s %s %s %s %s %s %s %s\n", GetFlag(FLAGIOPL,Context->EFlags), GetFlag(FLAGVIP,Context->EFlags) ? "vip" : " ", GetFlag(FLAGVIF,Context->EFlags) ? "vif" : " ", GetFlag(FLAGOF,Context->EFlags) ? "ov" : "nv", GetFlag(FLAGDF,Context->EFlags) ? "dn" : "up", GetFlag(FLAGIF,Context->EFlags) ? "ei" : "di", GetFlag(FLAGSF,Context->EFlags) ? "ng" : "pl", GetFlag(FLAGZF,Context->EFlags) ? "zr" : "nz", GetFlag(FLAGAF,Context->EFlags) ? "ac" : "na", GetFlag(FLAGPF,Context->EFlags) ? "po" : "pe", GetFlag(FLAGCF,Context->EFlags) ? "cy" : "nc" ); fprintf( FileOut, "cs=%04x ss=%04x ds=%04x es=%04x fs=%04x gs=%04x efl=%08x\n", Context->SegCs, Context->SegSs, Context->SegDs, Context->SegEs, Context->SegFs, Context->SegGs, Context->EFlags ); if (SpecialRegContext) { fprintf( FileOut, "cr0=%08x cr2=%08x cr3=%08x ", SpecialRegContext->Cr0, SpecialRegContext->Cr2, SpecialRegContext->Cr3 ); fprintf( FileOut, "dr0=%08x dr1=%08x dr2=%08x\n", SpecialRegContext->KernelDr0, SpecialRegContext->KernelDr1, SpecialRegContext->KernelDr2 ); fprintf( FileOut, "dr3=%08x dr6=%08x dr7=%08x cr4=%08x\n", SpecialRegContext->KernelDr3, SpecialRegContext->KernelDr6, SpecialRegContext->KernelDr7, SpecialRegContext->Cr4 ); fprintf( FileOut, "gdtr=%08lx gdtl=%04lx idtr=%08lx idtl=%04lx tr=%04lx ldtr=%04x\n", SpecialRegContext->Gdtr.Base, SpecialRegContext->Gdtr.Limit, SpecialRegContext->Idtr.Base, SpecialRegContext->Idtr.Limit, SpecialRegContext->Tr, SpecialRegContext->Ldtr ); } fprintf( FileOut, "\n" ); }