/*++ Copyright (c) 1990 Microsoft Corporation Module Name: vdmexts.h Abstract: This file header defines most of the stuff used in VDMEXTS Revision History: Neil Sandlin (NeilSa) 15-Jan-1996 Merged with vdmexts --*/ // // Pointers to WINDBG api // extern PNTSD_OUTPUT_ROUTINE Print; extern PNTSD_GET_EXPRESSION GetExpression; extern PNTSD_GET_SYMBOL GetSymbol; //extern PNTSD_DISASM Disassemble; extern PNTSD_CHECK_CONTROL_C CheckCtrlC; extern PWINDBG_READ_PROCESS_MEMORY_ROUTINE ReadMem; extern PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE WriteMem; extern fWinDbg; extern HANDLE hCurrentProcess; extern HANDLE hCurrentThread; extern LPSTR lpArgumentString; #define PRINTF (* Print) #define EXPRESSION (* GetExpression) #define ReadDword(x) read_dword((ULONG)x, FALSE) #define ReadWord(x) read_word ((ULONG)x, FALSE) #define ReadByte(x) read_byte ((ULONG)x, FALSE) #define ReadDwordSafe(x) read_dword((ULONG)x, TRUE) #define ReadWordSafe(x) read_word ((ULONG)x, TRUE) #define ReadByteSafe(x) read_byte ((ULONG)x, TRUE) #define ReadGNode32(x,p) read_gnode32((ULONG)x,p,FALSE) #define ReadGNode32Safe(x,p) read_gnode32((ULONG)x,p,TRUE) /****** macros common to all versions *******/ #define CMD_ARGLIST HANDLE CurrentProcess, \ HANDLE CurrentThread, \ DWORD CurrentPc, \ PWINDBG_EXTENSION_APIS pXApis, \ LPSTR ArgumentString #define CMD_INIT() \ UNREFERENCED_PARAMETER(CurrentPc); \ hCurrentProcess = CurrentProcess; \ hCurrentThread = CurrentThread; \ lpArgumentString = ArgumentString; \ \ Print = pXApis->lpOutputRoutine; \ GetSymbol = pXApis->lpGetSymbolRoutine; \ GetExpression = pXApis->lpGetExpressionRoutine; \ CheckCtrlC = pXApis->lpCheckControlCRoutine; \ \ if (pXApis->nSize >= sizeof(WINDBG_EXTENSION_APIS)) { \ fWinDbg = TRUE; \ ReadMem = pXApis->lpReadProcessMemoryRoutine; \ WriteMem = pXApis->lpWriteProcessMemoryRoutine; \ } else { \ fWinDbg = FALSE; \ } #define READMEM( addr, buff, size ) ReadProcessMem(addr, buff, size) #define WRITEMEM( addr, buff, size ) WriteProcessMem(addr, buff, size) #define READMEM_XRET(buff, addr)\ try {\ READMEM( (LPVOID)(addr), (LPVOID)&(buff), sizeof(buff));\ } except (EXCEPTION_EXECUTE_HANDLER) {\ Print("ReadProcessMemory Failed !\n");\ return;\ } #define READMEM_XRETV(buff, addr, ret)\ try {\ READMEM((LPVOID) (addr), (LPVOID)&(buff), sizeof(buff));\ } except (EXCEPTION_EXECUTE_HANDLER) {\ Print("ReadProcessMemory Failed !\n");\ return ret;\ } #define WRITEMEM_XRET(addr, buff)\ try {\ WRITEMEM((LPVOID)(addr), (LPVOID)&(buff), sizeof(buff));\ } except (EXCEPTION_EXECUTE_HANDLER) {\ Print("WriteProcessMemory Failed !\n");\ return;\ } #define WRITEMEM_N_XRET(addr, buff, n)\ try {\ WRITEMEM((LPVOID)(addr), (LPVOID)(buff), n);\ } except (EXCEPTION_EXECUTE_HANDLER) {\ Print("WriteProcessMemory Failed !\n");\ return;\ } #define GETEXPRVALUE(dst, expr, typ) \ {\ if (fWinDbg) {\ dst = (typ)GetExpression(expr);\ } else {\ PVOID lpA = (PVOID)GetExpression(expr);\ READMEM_XRET(dst, lpA);\ }\ } #define GETEXPRADDR(dst, expr) \ {\ if (fWinDbg) {\ LPSTR lps = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, strlen(expr)+2);\ *lps = '&';\ strcpy(lps+1, expr);\ dst = (PVOID)GetExpression(lps);\ HeapFree(GetProcessHeap(), 0, lps);\ } else {\ dst = (PVOID)GetExpression(expr);\ }\ } #define ASSERT_WOW_PRESENT { \ if (!EXPRESSION("wow32!gptdTaskHead")) { \ PRINTF("Could not resolve needed symbols for WOW32\n"); \ return; \ } \ } #define ASSERT_CHECKED_WOW_PRESENT { \ if (!EXPRESSION("wow32!iCircBuffer")) { \ PRINTF("Could not resolve needed symbols for checked WOW32\n"); \ return; \ } \ } #define BEFORE 0 #define AFTER 1 #define RPL_MASK 0x78 #define V86_BITS 0x20000 #define SELECTOR_LDT 0x04 #define SELECTOR_RPL 0x03 #define V86_MODE 0 #define PROT_MODE 1 #define FLAT_MODE 2 #define NOT_LOADED 3 #define CALL_NEAR_RELATIVE 0xE8 #define CALL_NEAR_INDIRECT 0xFF #define INDIRECT_NEAR_TYPE 0x02 #define CALL_FAR_ABSOLUTE 0x9A #define CALL_FAR_INDIRECT 0xFF #define INDIRECT_FAR_TYPE 0x03 #define PUSH_CS 0x0E #define ADD_SP 0xC483 #define TYPE_BITS 0x38 #define TYPE0 0x00 #define TYPE1 0x08 #define TYPE2 0x10 #define TYPE3 0x18 #define TYPE4 0x20 #define TYPE5 0x28 #define TYPE6 0x30 #define TYPE7 0x38 #define MOD_BITS 0xC0 #define MOD0 0x00 #define MOD1 0x40 #define MOD2 0x80 #define MOD3 0xC0 #define RM_BITS 0x07 #define RM0 0x00 #define RM1 0x01 #define RM2 0x02 #define RM3 0x03 #define RM4 0x04 #define RM5 0x05 #define RM6 0x06 #define RM7 0x07 #define FLAG_OVERFLOW 0x0800 #define FLAG_DIRECTION 0x0400 #define FLAG_INTERRUPT 0x0200 #define FLAG_SIGN 0x0080 #define FLAG_ZERO 0x0040 #define FLAG_AUXILLIARY 0x0010 #define FLAG_PARITY 0x0004 #define FLAG_CARRY 0x0001 typedef struct _SELECTORINFO { DWORD Base; DWORD Limit; BOOL bCode; BOOL bSystem; BOOL bPresent; BOOL bWrite; BOOL bAccessed; BOOL bBig; } SELECTORINFO; typedef struct _segentry { int type; LPSTR path_name; WORD selector; WORD segment; DWORD ImgLen; } SEGENTRY; #define SEGTYPE_AVAILABLE 0 #define SEGTYPE_V86 1 #define SEGTYPE_PROT 2 #define MAXSEGENTRY 1024 #pragma pack(1) typedef struct _GNODE32 { // GlobalArena DWORD pga_next ; // next arena entry (last points to self) DWORD pga_prev ; // previous arena entry (first points to self) DWORD pga_address ; // 32 bit linear address of memory DWORD pga_size ; // 32 bit size in bytes WORD pga_handle ; // back link to handle table entry WORD pga_owner ; // Owner field (current task) BYTE pga_count ; // lock count for movable segments BYTE pga_pglock ; // # times page locked BYTE pga_flags ; // 1 word available for flags BYTE pga_selcount ; // Number of selectors allocated DWORD pga_lruprev ; // Previous entry in lru chain DWORD pga_lrunext ; // Next entry in lru chain } GNODE32; typedef GNODE32 UNALIGNED *PGNODE32; typedef struct _GHI32 { WORD hi_check ; // arena check word (non-zero enables heap checking) WORD hi_freeze ; // arena frozen word (non-zero prevents compaction) WORD hi_count ; // #entries in arena WORD hi_first ; // first arena entry (sentinel, always busy) WORD hi_res1 ; // reserved WORD hi_last ; // last arena entry (sentinel, always busy) WORD hi_res2 ; // reserved BYTE hi_ncompact ; // #compactions done so far (max of 3) BYTE hi_dislevel ; // current discard level DWORD hi_distotal ; // total amount discarded so far WORD hi_htable ; // head of handle table list WORD hi_hfree ; // head of free handle table list WORD hi_hdelta ; // #handles to allocate each time WORD hi_hexpand ; // address of near procedure to expand handles for this arena WORD hi_pstats ; // address of statistics table or zero } GHI32; typedef GHI32 UNALIGNED *PGHI32; typedef struct _HEAPENTRY { GNODE32 gnode; DWORD CurrentEntry; DWORD NextEntry; WORD Selector; int SegmentNumber; char OwnerName[9]; char FileName[9]; char ModuleArg[9]; } HEAPENTRY; typedef struct _NEHEADER { WORD ne_magic ; BYTE ne_ver ; BYTE ne_rev ; WORD ne_enttab ; WORD ne_cbenttab ; DWORD ne_crc ; WORD ne_flags ; WORD ne_autodata ; WORD ne_heap ; WORD ne_stack ; DWORD ne_csip ; DWORD ne_sssp ; WORD ne_cseg ; WORD ne_cmod ; WORD ne_cbnrestab ; WORD ne_segtab ; WORD ne_rsrctab ; WORD ne_restab ; WORD ne_modtab ; WORD ne_imptab ; DWORD ne_nrestab ; WORD ne_cmovent ; WORD ne_align ; WORD ne_cres ; BYTE ne_exetyp ; BYTE ne_flagsothers ; WORD ne_pretthunks ; WORD ne_psegrefbytes; WORD ne_swaparea ; WORD ne_expver ; } NEHEADER; typedef NEHEADER UNALIGNED *PNEHEADER; #pragma pack() #ifndef i386 // // Structures in 486 cpu for obtaining registers (FROM NT_CPU.C) // typedef struct NT_CPU_REG { ULONG *nano_reg; /* where the nano CPU keeps the register */ ULONG *reg; /* where the light compiler keeps the reg */ ULONG *saved_reg; /* where currently unused bits are kept */ ULONG universe_8bit_mask;/* is register in 8-bit form? */ ULONG universe_16bit_mask;/* is register in 16-bit form? */ } NT_CPU_REG; typedef struct NT_CPU_INFO { /* Variables for deciding what mode we're in */ BOOL *in_nano_cpu; /* is the Nano CPU executing? */ ULONG *universe; /* the mode that the CPU is in */ /* General purpose register pointers */ NT_CPU_REG eax, ebx, ecx, edx, esi, edi, ebp; /* Variables for getting SP or ESP. */ BOOL *stack_is_big; /* is the stack 32-bit? */ ULONG *nano_esp; /* where the Nano CPU keeps ESP */ UCHAR **host_sp; /* ptr to variable holding stack pointer as a host address */ UCHAR **ss_base; /* ptr to variables holding base of SS as a host address */ ULONG *esp_sanctuary; /* top 16 bits of ESP if we're now using SP */ ULONG *eip; /* Segment registers. */ USHORT *cs, *ds, *es, *fs, *gs, *ss; ULONG *flags; /* CR0, mainly to let us figure out if we're in real or protect mode */ ULONG *cr0; } NT_CPU_INFO; #endif // i386 BOOL WINAPI ReadProcessMem( LPVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize ); BOOL WINAPI WriteProcessMem( LPVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize ); BOOL CheckGlobalHeap( BOOL bVerbose ); int GetContext( VDMCONTEXT* lpContext ); ULONG GetInfoFromSelector( WORD selector, int mode, SELECTORINFO *si ); BOOL FindHeapEntry( HEAPENTRY *he, UINT FindMethod, BOOL bVerbose ); #define FHE_FIND_ANY 0 #define FHE_FIND_SEL_ONLY 1 #define FHE_FIND_MOD_ONLY 2 #define FHE_FIND_QUIET FALSE #define FHE_FIND_VERBOSE TRUE BOOL FindAddress( LPSTR sym_text, LPSTR filename, WORD *psegment, WORD *pselector, LONG *poffset, int *pmode, BOOL bDumpAll ); BOOL FindSymbol( WORD selector, LONG offset, LPSTR sym_text, LONG *dist, int direction, int mode ); int unassemble_one( BYTE *pInstrStart, BOOL bDefaultBig, WORD wInstrSeg, DWORD dwInstrOff, char *pchOutput, char *pchExtra, VDMCONTEXT *pThreadContext, int mode ); ULONG GetIntelBase( VOID ); DWORD read_dword( ULONG lpAddress, BOOL bSafe ); WORD read_word( ULONG lpAddress, BOOL bSafe ); BYTE read_byte( ULONG lpAddress, BOOL bSafe ); BOOL read_gnode32( ULONG lpAddress, PGNODE32 p, BOOL bSafe ); BOOL GetNextToken( VOID ); ULONG EvaluateToken( VOID ); VOID helpAPIProfDmp( VOID ); VOID helpMsgProfDmp( VOID ); BOOL ParseIntelAddress( int *pMode, WORD *pSelector, PULONG pOffset ); VOID ParseModuleName( LPSTR szName, LPSTR szPath ); BOOL SkipToNextWhiteSpace( VOID ); BOOL IsTokenHex( VOID ); VOID Drp (VOID); VOID Erp (VOID); VOID EventInfop (VOID); VOID ProfDumpp (VOID); VOID ProfIntp (VOID); VOID ProfStartp (VOID); VOID ProfStopp (VOID); VOID VdmTibp (VOID); VOID Fpup (VOID);