?? disassembler.c
字號:
/****************************************************************************** * * Copyright (c) 2003 Gerhard W. Gruber * * PROJECT: pICE * $Source: /cvsroot/pice/pice/module/disassembler.c,v $ * $Revision: 1.3 $ * $Date: 2004/02/17 23:07:36 $ * $Author: lightweave $ * $Name: $ * * $Log: disassembler.c,v $ * Revision 1.3 2004/02/17 23:07:36 lightweave * * Improved the DEBUG facillity and replaced the configuration handler with a * new code which now can read MS Windows INI style files. See CHANGES.txt for * more details. * Also added a macro which prevents compiling for kernels before 2.4.19. * * Revision 1.2 2003/06/18 22:00:22 lightweave * DEBUG and DEBUG_SERIAL added * * *****************************************************************************/static char *ident = "$Header: /cvsroot/pice/pice/module/disassembler.c,v 1.3 2004/02/17 23:07:36 lightweave Exp $";/*++Copyright (c) 2000-2001 Goran Devic Modified (c) 2001 Klaus P. GerlicherModule Name: disassembler.cAbstract: line disassemblerEnvironment: LINUX 2.2.X Kernel mode onlyAuthor: Goran Devic Revision History: 17-Mar-2000: Original (Goran Devic) 26-Apr-2000: Major rewrite, added coprocessor instructions (Goran Devic) 04-Nov-2000: Modified for LinIce (Goran Devic) 05-Jan-2001: Modified for pICE (Klaus P. Gerlicher)Copyright notice: This file may be distributed under the terms of the GNU Public License.--*//******************************************************************************** Include Files *******************************************************************************/#include "remods.h"#include "precomp.h"#include "disassemblerdata.h" // Include its own data/******************************************************************************** This structure is used to pass parameters and options to the* line disassembler.*******************************************************************************/typedef struct{ ULONG dwFlags; // Generic flags (described below) USHORT wSel; // Selector to use to fetch code UCHAR *bpTarget; // Target pointer to disassemble UCHAR *szDisasm; // String where to put ascii result UCHAR Codes[20]; // Buffer where to store code UCHARs UCHAR bAsciiLen; // Length of the ascii result UCHAR bInstrLen; // Instruction lenght in UCHARs int nDisplacement; // Scanner: possible constant displacement int nScanEnum; // Scanner: specific flags SCAN_*} TDisassembler;// dwFlags contains a set of boolean flags with the following functionality#define DIS_DATA32 0x0001 // Data size 16/32 bits (0/1)#define DIS_GETDATASIZE(flags) ((flags)&DIS_DATA32)#define DIS_ADDRESS32 0x0002 // Address size 16/32 bits (0/1)#define DIS_GETADDRSIZE(flags) (((flags)&DIS_ADDRESS32)?1:0)#define DIS_SEGOVERRIDE 0x0004 // Default segment has been overriden#define DIS_REP 0x0100 // Return: REP prefix found (followed by..)#define DIS_REPNE 0x0200 // Return: REPNE prefix found#define DIS_GETREPENUM(flags) (((flags)>>8)&3)#define DIS_ILLEGALOP 0x8000 // Return: illegal opcode/******************************************************************************* ** Global Variables ** *******************************************************************************//******************************************************************************* ** External functions (optional) ** *******************************************************************************//******************************************************************************* ** Local Defines, Variables and Macros ** *******************************************************************************/UCHAR GetUCHAR(ULONG addr){ if(IsAddressValid(addr)) return *(PUCHAR)addr; else return 0x82; // INVALID OPCODE}static UCHAR GetNextUCHAR(USHORT sel, UCHAR *offset, UCHAR *pCode){ pCode[0] = GetUCHAR((ULONG) offset + 0) & 0xFF; return( pCode[0] );} static USHORT GetNextUSHORT(USHORT sel, UCHAR *offset, UCHAR *pCode){ pCode[0] = GetUCHAR((ULONG) offset + 0) & 0xFF; pCode[1] = GetUCHAR((ULONG) offset + 1) & 0xFF; return( *(USHORT *) pCode );} static ULONG GetNextULONG(USHORT sel, UCHAR *offset, UCHAR *pCode){ pCode[0] = GetUCHAR((ULONG) offset + 0) & 0xFF; pCode[1] = GetUCHAR((ULONG) offset + 1) & 0xFF; pCode[2] = GetUCHAR((ULONG) offset + 2) & 0xFF; pCode[3] = GetUCHAR((ULONG) offset + 3) & 0xFF; return( *(ULONG *) pCode );} #define NEXTUCHAR GetNextUCHAR( pDis->wSel, bpTarget, bpCode); bpCode += 1; bpTarget += 1; bInstrLen += 1#define NEXTUSHORT GetNextUSHORT( pDis->wSel, bpTarget, bpCode); bpCode += 2; bpTarget += 2; bInstrLen += 2#define NEXTULONG GetNextULONG(pDis->wSel, bpTarget, bpCode); bpCode += 4; bpTarget += 4; bInstrLen += 4/******************************************************************************* ** Functions ** *******************************************************************************//******************************************************************************* ** UCHAR Disassembler( TDisassembler *pDis ); ** ********************************************************************************** This is a generic Intel line disassembler.** Where:* TDisassembler:* bpTarget is the address of instruction to disassemble* szDisasm is the address of the buffer to print a line into* dwFlags contains the default operand and address bits* pCode is the address to store code UCHARs (up to 16)** Disassembled instruction is stored as an ASCIIZ string pointed by* szDisasm pointer (from the pDis structure).** Returns:* TDisassembler:* *szDisasm contains the disassembled instruction string* bAsciiLen is set to the length of the printed string* bInstrLen is set to instruction length in UCHARs* dwFlags - has operand and address size flags adjusted* - DIS_ILLEGALOP set if that was illegal instruction* UCHAR - instruction length in UCHARs*******************************************************************************/UCHAR Disassembler( TDisassembler *pDis ){ TOpcodeData *p; // Pointer to a current instruction record UCHAR *bpTarget; // Pointer to the target code to be disassembled UCHAR *bpCode; // Pointer to code UCHARs ULONG arg; // Argument counter char *sPtr; // Message selection pointer int nPos; // Printing position in the output string UCHAR *pArg; // Pointer to record where instruction arguments are ULONG dwULONG; // Temporary ULONG storage USHORT wUSHORT; // Temporary USHORT storage UCHAR bUCHAR; // Temporary UCHAR storage UCHAR bInstrLen; // Current instruction lenght in UCHARs UCHAR bOpcode; // Current opcode that is being disassembled UCHAR bSegOverride; // 0 default segment. >0, segment index UCHAR bMod=0; // Mod field of the instruction UCHAR bReg=0; // Register field of the instruction UCHAR bRm=0; // R/M field of the instruction UCHAR bW; // Width bit for the register selection UCHAR bSib; // S-I-B UCHAR for the instruction UCHAR bSs; // SS field of the s-i-b UCHAR UCHAR bIndex; // Index field of the s-i-b UCHAR UCHAR bBase; // Base field of the s-i-b UCHAR LPSTR pSymbolName; // used to symbolic name of value bInstrLen = 0; // Reset instruction lenght to zero bSegOverride = 0; // Set default segment (no override) nPos = 0; // Reset printing position sPtr = NULL; // Points to no message by default bpTarget = pDis->bpTarget; // Set internal pointer to a target address bpCode = pDis->Codes; // Set internal pointer to code UCHARs do { bOpcode = NEXTUCHAR; // Get the first opcode UCHAR from the target address p = &Op1[bOpcode]; // Get the address of the instruction record if( p->flags & DIS_SPECIAL ) { // Opcode is one of the special ones, so do what needs to be done there switch( p->name ) { case _EscD8: case _EscD9: case _EscDA: case _EscDB: case _EscDC: case _EscDD: case _EscDE: case _EscDF: // Coprocessor escape: UCHARs D8 - DF bOpcode = NEXTUCHAR; // Get the modRM UCHAR of the instruction if( bOpcode < 0xC0 ) { // Opcodes 00-BF use Coproc1 table bReg = (bOpcode >> 3) & 7; p = &Coproc1[ p->name - _EscD8 ][ bReg ]; goto StartInstructionParseMODRM; } // Opcodes C0-FF use Coproc2 table p = &Coproc2[ p->name - _EscD8 ][ bOpcode - 0xC0 ]; goto StartInstructionNoMODRM; case _S_ES: // Segment override case _S_CS: case _S_SS: case _S_DS: case _S_FS: case _S_GS: bSegOverride = p->name - _S_ES + 1; continue; case _OPSIZ: // Operand size override - toggle pDis->dwFlags ^= DIS_DATA32; continue; case _ADSIZ: // Address size override - toggle pDis->dwFlags ^= DIS_ADDRESS32; continue; case _REPNE: // REPNE/REPNZ prefix pDis->dwFlags |= DIS_REPNE; continue; case _REP: // REP/REPE/REPZ prefix pDis->dwFlags |= DIS_REP; continue; case _2BESC: // 2 UCHAR escape code 0x0F bOpcode = NEXTUCHAR; // Get the second UCHAR of the instruction p = &Op2[bOpcode]; // Get the address of the instruction record if( !(p->flags & DIS_SPECIAL) ) goto StartInstruction; if( p->name < _GRP6 ) goto IllegalOpcode; case _GRP1a: // Additional groups of instructions case _GRP1b: case _GRP1c: case _GRP2a: case _GRP2b: case _GRP2c: case _GRP2d: case _GRP2e: case _GRP2f: case _GRP3a: case _GRP3b: case _GRP4: case _GRP5: case _GRP6: case _GRP7: case _GRP8: case _GRP9: bOpcode = NEXTUCHAR; // Get the Mod R/M UCHAR whose... // bits 3,4,5 select instruction bReg = (bOpcode >> 3) & 7; p = &Groups[p->name - _GRP1a][ bReg ]; if( !(p->flags & DIS_SPECIAL) ) goto StartInstructionParseMODRM; case _NDEF : // Not defined or illegal opcode goto IllegalOpcode; default :; // Should not happen } } else goto StartInstruction; } while( bInstrLen < 15 );IllegalOpcode: nPos += PICE_sprintf( pDis->szDisasm+nPos, "---"); pDis->dwFlags |= DIS_ILLEGALOP; goto DisEnd;StartInstruction: // If this instruction needs additional Mod R/M UCHAR, fetch it if( p->flags & DIS_MODRM ) { // Get the next UCHAR (modR/M bit field) bOpcode = NEXTUCHAR; bReg = (bOpcode >> 3) & 7;StartInstructionParseMODRM: // Parse that UCHAR and get mod, reg and rm fields bMod = bOpcode >> 6; bRm = bOpcode & 7; }StartInstructionNoMODRM: // Print the possible repeat prefix followed by the instruction if( p->flags & DIS_COPROC ) nPos += PICE_sprintf( pDis->szDisasm+nPos, "%-6s ", sCoprocNames[ p->name ]); else nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s%-6s ", sRep[DIS_GETREPENUM(pDis->dwFlags)], sNames[ p->name + (DIS_GETNAMEFLAG(p->flags) & DIS_GETDATASIZE(pDis->dwFlags)) ] ); // Do instruction argument processing, up to 3 times pArg = &p->dest;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -