📄 disasm.cpp
字号:
/*---------------------------------------------------------------------------*/
// DisC Decompilation Wizard
// written by
// Satish Kumar S
// satish@miel.mot.com
//
// Copyright 1999-2001 Satish Kumar S
//
// Permission is granted to use this software for research purposes as
// long as this notice stays attached to this software.
/*---------------------------------------------------------------------------*/
#include <conio.h>
#include <stdio.h>
#include <dos.h>
#include "Disasm.h"
#define AddOffset(str) { CurInst.Data11 = (Word)(regIP + Len + (int)Ip[1]); \
str += CurInst.Data11; }
#define AddOnlyOffset() CurInst.Data11 = (Word)(regIP + Len + (int)Ip[1])
#define Register(W,R) (W*8 + R)
#define SegmentReg(R) (16 + R)
char Regstr[2][8][3] = {"AL","CL","DL","BL","AH","CH","DH","BH",\
"AX","CX","DX","BX","SP","BP","SI","DI"};
char SRegstr[][3] = {"ES","CS","SS","DS"};
char Effaddrstr[8][6] = {"BX+SI","BX+DI","BP+SI","BP+DI","SI","DI","BP","BX"};
char ArithOperstr[][5] = {"ADD ","OR ","ADC ","SBB ","AND ","SUB ","XOR ","CMP "};
char SecArithOperstr[][6] = {"TEST ","","NOT ","NEG ","MUL ","IMUL ","DIV ","IDIV "};
char LogOperstr[][5] = {"ROL ","ROR ","RCL ","RCR ","SHL ","SHR ","SAL ","SAR "};
char ByteorWordPtr[][10]= {"BYTE PTR ","WORD PTR "};
int ArithOpers[] = {ADD, OR, ADC, SBB, AND, SUB, XOR, CMP };
int SecArithOpers[] = {TEST, UNKNOWN, NOT, NEG, MUL, IMUL, DIV, IDIV };
int LogOpers[] = {ROL, ROR, RCL, RCR, SHL, SHR, SAL, SAR };
Disasm::Disasm()
{
CodePtr = NULL;
regIP = 0;
}
void Disasm::SetCodePtr(Byte far *Ptr)
{
regIP = 0;
CodePtr = Ptr;
}
void Disasm::SetregIP(Word IP)
{
regIP = IP;
}
void Disasm::UpdateCodePtr(Byte far *Ptr)
{
regIP = (Ptr - CodePtr); // Update IP for new position.
CodePtr = Ptr;
}
Byte Disasm::GetImmediateByte(int Offset /* = 0 */)
{
return (*(Byte far *)(Ip + Offset));
}
Word Disasm::GetImmediateWord(int Offset /* = 0 */)
{
return (*(Word far *)(Ip + Offset));
}
SByte Disasm::GetImmediateSByte(int Offset /* = 0 */)
{
return (*(SByte far *)(Ip + Offset));
}
Sword Disasm::GetImmediateSWord(int Offset /* = 0 */)
{
return (*(Sword far *)(Ip + Offset));
}
String &Disasm::ImmediateByte(int Offset /* = 0 */)
{
static String tmp;
tmp=(*(Byte far *)(Ip+Offset));
return tmp;
}
String &Disasm::ImmediateWord(int Offset /* = 0 */)
{
static String tmp;
tmp=(*(Word far *)(Ip+Offset));
return tmp;
}
String &Disasm::Immediate(int Offset /* = 0 */)
{
Len = Offset + 1 + W;
if (W) return ImmediateWord(Offset);
else return ImmediateByte(Offset);
}
Word Disasm::GetImmediate(int Offset /* = 0 */)
{
Len = Offset + 1 + W;
if (W) return GetImmediateWord(Offset);
else return (Word)GetImmediateByte(Offset);
}
String &Disasm::ImmediateSByte(int Offset /* = 0 */)
{
int val = (int)*(char far *)(Ip+Offset);
static String tmp;
tmp = (val<0)?"-":"+";
tmp += (val<0)?(Byte)(256-val):(Byte)val;
return tmp;
}
String &Disasm::ImmediateSWord(int Offset /* = 0 */)
{
int val = (int)*(int far *)(Ip+Offset);
static String tmp;
tmp = (val<0)?"-":"+";
tmp += (val<0)?(Word)(65536-val):(Word)val;
return tmp;
}
String &Disasm::Operand1(int Reg,int W,int SRegs /* = FALSE */)
{
static String operand;
CurInst.Operand1 = REG_DIRECT;
CurInst.Data11 = (SRegs)?SegmentReg(Reg):Register(W,Reg);
operand = (SRegs) ? SRegstr[Reg] : Regstr[W][Reg];
return operand;
}
String &Disasm::Operand2(int Mod,int RM,int W /* = 0 */,int Offset /* = 0 */)
{
static String operand;
operand="[";
String Nul;
switch(Mod)
{
case 0 : if (RM == 6)
{
CurInst.Operand2 = MEMORY;
CurInst.Data21 = GetImmediateWord(Offset);
operand += ImmediateWord(Offset);
Len += 2;
}
else
{
CurInst.Operand2 = REG_INDIRECT;
CurInst.Data21 = RM;
operand += Effaddrstr[RM];
break;
}
break;
case 1 : CurInst.Operand2 = INDEXED_BYTE;
CurInst.Data21 = RM;
CurInst.Data22 = (Sword)GetImmediateSByte(Offset);
operand += Nul + Effaddrstr[RM] + ImmediateSByte(Offset);
Len++;
break;
case 2 : CurInst.Operand2 = INDEXED_WORD;
CurInst.Data21 = RM;
CurInst.Data22 = (Sword)GetImmediateSWord(Offset);
operand += Nul + Effaddrstr[RM] + ImmediateSWord(Offset);
Len+=2;
break;
case 3 : CurInst.Operand2 = REG_DIRECT;
CurInst.Data21 = Register(W,RM);
operand = Regstr[W][RM];
break;
}
if (Mod!=3) operand += "]";
return operand;
}
String &Disasm::GetOperands()
{
static String str;
if (D==0)
{
str = Operand2(Mod,RM,W,2) + "," + Operand1(Reg,W);
CurInst.SwapOperands();
}
else str = Operand1(Reg,W) + "," + Operand2(Mod,RM,W,2);
return str;
}
void Disasm::TraceInst(Byte far *Insts,int &Length)
{
regIP = (Insts - CodePtr);
Ip = Insts;
Opcode = Insts[0];
D = (Opcode >> 1) & 1;
W = Opcode & 1;
Mod = (Insts[1] >> 6) & 3;
Reg = (Insts[1] >> 3) & 7;
RM = Insts[1] & 7;
int ArithOper = (Opcode >> 3) & 7;
Len = 1;
SRegs = FALSE;
FirstOperand = FALSE;
SecondOperand = FALSE;
CurInst.Clear();
String str;
switch(Opcode)
{
// Mov AL,[mem]. Mov AX,[mem]. Mov [mem],AL. Mov [mem],AX.
case 0xa0 : case 0xa1 : case 0xa2 : case 0xa3 :
CurInst.Instr = MOV;
if (D)
{
CurInst.Operand2 = REG_DIRECT;
CurInst.Data21 = Register(W,0);
CurInst.Operand1 = MEMORY;
CurInst.Data11 = GetImmediateWord(1);
}
else
{
CurInst.Operand1 = REG_DIRECT;
CurInst.Data11 = Register(W,0);
CurInst.Operand2 = MEMORY;
CurInst.Data21 = GetImmediateWord(1);
}
Len = 3; break;
// Mov Addr,Reg8. & Mov Addr,Reg16.
case 0x88 : case 0x89 :
// Mov Reg8,Addr. & Mov Reg16,Addr.
case 0x8a : case 0x8b :
CurInst.Instr = MOV; Len = 2;
GetOperands();
break;
// Mov Reg8,Immediate8.
case 0xb0 : case 0xb1 : case 0xb2 : case 0xb3 :
case 0xb4 : case 0xb5 : case 0xb6 : case 0xb7 :
// Mov Reg16,Immediate16.
case 0xb8 : case 0xb9 : case 0xba : case 0xbb :
case 0xbc : case 0xbd : case 0xbe : case 0xbf :
Reg = Opcode & 15;
Len = 2;
CurInst.Instr = MOV;
CurInst.Operand1 = REG_DIRECT;
CurInst.Data11 = Reg;
CurInst.Operand2 = IMMEDIATE;
W = (Reg>>3)&1;
CurInst.operSize1 = CurInst.operSize2 = W;
CurInst.Data21 = GetImmediate(1);
break;
// Mov Addr,Imm.
case 0xc6 : case 0xc7 :
Len = 2;
CurInst.Instr = MOV;
CurInst.operSize2 = W;
Operand2(Mod,RM,W,2);
CurInst.Operand1 = IMMEDIATE;
CurInst.operSize1 = W;
CurInst.Data11 = GetImmediate(Len);
CurInst.SwapOperands();
break;
// Mov Addr,SReg.
case 0x8c : Len = 2;
CurInst.Instr = MOV;
if (RM==0)
{
CurInst.Operand1 = REG_DIRECT;
CurInst.Data11 = RM;
}
else
{
Operand2(Mod,RM,1,2);
CurInst.SwapOperands();
}
CurInst.Operand2 = REG_DIRECT;
CurInst.Data21 = SegmentReg(Reg);
break;
// Mov Sreg,Addr.
case 0x8e : Len = 2;
CurInst.Instr = MOV;
CurInst.Operand1 = REG_DIRECT;
CurInst.Data11 = SegmentReg(Reg);
if (RM==0)
{
CurInst.Operand2 = REG_DIRECT;
CurInst.Data21 = RM;
}
else
{
Operand2(Mod,RM,1,2);
}
break;
// Ret & Retf
case 0xc2 : CurInst.Instr = RET;
CurInst.operSize1=0;
CurInst.Data11 = GetImmediateWord(1);
break;
case 0xc3 : CurInst.Instr = RET;
CurInst.operSize1=0;
CurInst.Data11 = 0; break;
case 0xca : CurInst.Instr = RET;
CurInst.operSize1=1;
CurInst.Data11 = GetImmediateWord(1);
break;
case 0xcb : CurInst.Instr = RET;
CurInst.operSize1=0;
CurInst.Data11 = 0; break;
// (Inc,Dec,Call,Call far,Jmp,Jmp far,Push) Addr.
case 0xff : Len = 2;
switch(Reg)
{
case 0 : CurInst.Instr = INC; break;
case 1 : CurInst.Instr = DEC; break;
case 2 : CurInst.Instr = CALL; CurInst.operSize2=0;
CurInst.Data22=FP_SEG(Insts); break;
case 3 : CurInst.Instr = CALL; CurInst.operSize2=1; break;
case 4 : CurInst.Instr = JMP; CurInst.operSize2=0;
CurInst.Data22=FP_SEG(Insts); break;
case 5 : CurInst.Instr = JMP; CurInst.operSize2=1; break;
case 6 : CurInst.Instr = PUSH; break;
case 7 : CurInst.Instr = UNKNOWN;
}
Operand2(Mod,RM,1,2);
CurInst.SwapOperands();
break;
// Push Reg.
case 0x50 : case 0x51 :
case 0x52 : case 0x53 :
case 0x54 : case 0x55 :
case 0x56 : case 0x57 :
Reg = Opcode & 7; Len = 1;
CurInst.Instr = PUSH;
CurInst.Operand1 = REG_DIRECT;
CurInst.Data11 = Register(1,Reg);
break;
// Push SReg.
case 0x06 : case 0x0e :
case 0x16 : case 0x1e :
Reg = (Opcode >> 3) & 3; Len = 1;
CurInst.Instr = PUSH;
CurInst.Operand1 = REG_DIRECT;
CurInst.Data11 = SegmentReg(Reg);
break;
// Pop Sreg.
case 0x07 : case 0x0f :
case 0x17 : case 0x1f :
Reg = (Opcode >> 3) & 3; Len = 1;
CurInst.Instr = POP;
CurInst.Operand1 = REG_DIRECT;
CurInst.Data11 = SegmentReg(Reg);
break;
// Pop [mem], Pop [reg].
case 0x8f : CurInst.Instr = POP; Len = 2;
Operand2(Mod,RM,1,2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -