Esempio n. 1
0
        string ResolveSegmentPtr(RegSeg seg)
        {
            if (_prefixSegment == RegSeg.None)
            {
                return("");
            }

            return(Format(_prefixSegment) + ":");
        }
Esempio n. 2
0
        string Format(RegSeg reg)
        {
            switch (reg)
            {
            case RegSeg.CS: return("cs");

            case RegSeg.DS: return("ds");

            case RegSeg.ES: return("es");

            case RegSeg.SS: return("ss");
            }
            throw new NotImplementedException();
        }
Esempio n. 3
0
        public string Read()
        {
            ImplicitParams = null;
            IsCall         = false;
            ushort ipInstruction = ip;

            try
            {
                // Decode prefixes
                _prefixRepEither = false;
                _prefixRepNE     = false;

                _prefixSegment = RegSeg.None;
                _haveReadModRM = false;

                ushort temp;

                byte opCode     = ReadByte(cs, ip++);
                bool haveOpCode = false;
                while (!haveOpCode)
                {
                    switch (opCode)
                    {
                    case 0xF3:
                        _prefixRepEither = true;
                        _prefixRepNE     = false;
                        opCode           = ReadByte(cs, ip++);
                        break;

                    case 0xF2:
                        _prefixRepEither = true;
                        _prefixRepNE     = true;
                        opCode           = ReadByte(cs, ip++);
                        break;

                    case 0xF0:
                        opCode = ReadByte(cs, ip++);
                        break;

                    case 0x2E:
                        _prefixSegment = RegSeg.CS;
                        opCode         = ReadByte(cs, ip++);
                        break;

                    case 0x3E:
                        _prefixSegment = RegSeg.DS;
                        opCode         = ReadByte(cs, ip++);
                        break;

                    case 0x26:
                        _prefixSegment = RegSeg.ES;
                        opCode         = ReadByte(cs, ip++);
                        break;

                    case 0x36:
                        _prefixSegment = RegSeg.SS;
                        opCode         = ReadByte(cs, ip++);
                        break;

                    default:
                        haveOpCode = true;
                        break;
                    }
                }

                switch (opCode)
                {
                case 0x00:
                case 0x01:
                case 0x02:
                case 0x03:
                case 0x04:
                case 0x05:
                    return(FormatAluOp("add", opCode));

                case 0x06:
                case 0x0E:
                case 0x16:
                case 0x1E:
                    ImplicitParams = "sp";
                    return(string.Format("push {0}", Format((RegSeg)((opCode >> 3) & 0x03))));

                case 0x07:
                case 0x17:
                case 0x1F:
                    ImplicitParams = "word ptr ss:[sp]";
                    return(string.Format("pop {0}", Format((RegSeg)((opCode >> 3) & 0x03))));

                case 0x0F:
                    // No pop cs instruction
                    throw new InvalidOpCodeException();

                case 0x08:
                case 0x09:
                case 0x0A:
                case 0x0B:
                case 0x0C:
                case 0x0D:
                    return(FormatAluOp("or", opCode));

                case 0x10:
                case 0x11:
                case 0x12:
                case 0x13:
                case 0x14:
                case 0x15:
                    return(FormatAluOp("adc", opCode));

                case 0x18:
                case 0x19:
                case 0x1A:
                case 0x1B:
                case 0x1C:
                case 0x1D:
                    return(FormatAluOp("sbb", opCode));

                case 0x20:
                case 0x21:
                case 0x22:
                case 0x23:
                case 0x24:
                case 0x25:
                    return(FormatAluOp("and", opCode));

                case 0x26:
                    // ES: prefix
                    throw new InvalidOpCodeException();

                case 0x27:
                    return("daa");

                case 0x28:
                case 0x29:
                case 0x2A:
                case 0x2B:
                case 0x2C:
                case 0x2D:
                    return(FormatAluOp("sub", opCode));

                case 0x2E:
                    // CS:
                    throw new InvalidOpCodeException();

                case 0x2F:
                    return("das");

                case 0x30:
                case 0x31:
                case 0x32:
                case 0x33:
                case 0x34:
                case 0x35:
                    return(FormatAluOp("xor", opCode));

                case 0x36:
                    // SS: prefix
                    throw new InvalidOpCodeException();

                case 0x37:
                    return("aaa");

                case 0x38:
                case 0x39:
                case 0x3A:
                case 0x3B:
                case 0x3C:
                case 0x3D:
                    return(FormatAluOp("cmp", opCode));

                case 0x3E:
                    // DS:
                    throw new InvalidOpCodeException();

                case 0x3F:
                    // AAS
                    return("aas");

                case 0x40:
                case 0x41:
                case 0x42:
                case 0x43:
                case 0x44:
                case 0x45:
                case 0x46:
                case 0x47:
                    return(string.Format("inc {0}", Format((Reg16)(opCode & 0x07))));

                case 0x48:
                case 0x49:
                case 0x4A:
                case 0x4B:
                case 0x4C:
                case 0x4D:
                case 0x4E:
                case 0x4F:
                    return(string.Format("dec {0}", Format((Reg16)(opCode & 0x07))));

                case 0x50:
                case 0x51:
                case 0x52:
                case 0x53:
                case 0x54:
                case 0x55:
                case 0x56:
                case 0x57:
                    ImplicitParams = "sp";
                    return(string.Format("push {0}", Format((Reg16)(opCode & 0x07))));

                case 0x58:
                case 0x59:
                case 0x5A:
                case 0x5B:
                case 0x5C:
                case 0x5D:
                case 0x5E:
                case 0x5F:
                    ImplicitParams = "word ptr ss:[sp]";
                    return(string.Format("pop {0}", Format((Reg16)(opCode & 0x07))));

                case 0x60:
                    ImplicitParams = "sp";
                    return("pusha");

                case 0x61:
                    ImplicitParams = "sp";
                    return("popa");

                case 0x62:
                    // BOUND r16,m16
                    ReadModRM();
                    if (!_modRMIsPointer)
                    {
                        throw new InvalidOpCodeException();
                    }
                    return(string.Format("Bound {0},{1}", Read_Gv(), Read_Ev()));

                case 0x63:
                case 0x64:
                case 0x65:
                case 0x66:
                case 0x67:
                    throw new InvalidOpCodeException();

                case 0x68:
                    // Push Iv
                    ImplicitParams = "sp";
                    return(string.Format("push {0:X4}", Read_Iv()));

                case 0x69:
                    ReadModRM();
                    return(string.Format("imul {0},{1},{2}", Read_Gv(), Read_Ev(), Read_Iv()));

                case 0x6A:
                    // PUSH Ib
                    ImplicitParams = "sp";
                    return(string.Format("push byte {0}", Read_Ib_sx()));

                case 0x6B:
                    // imul Gv,Ev,Ib
                    ReadModRM();
                    return(string.Format("imul {0},{1},{2}", Read_Gv(), Read_Ev(), Read_Ib_sx()));

                case 0x6C:
                    // INSB
                    ImplicitParams = "es:di";
                    return(string.Format("{0} ins", RepPrefix()));

                case 0x6D:
                    // INSW
                    ImplicitParams = "es:di";
                    return(string.Format("{0} insw", RepPrefix()));

                case 0x6E:
                    // OUTSB
                    ImplicitParams = "byte ptr ds:[si]";
                    return(string.Format("{0} outsb", RepPrefix()));

                case 0x6F:
                    // OUTSW
                    ImplicitParams = "word ptr ds:[si]";
                    return(string.Format("{0} outsw", RepPrefix()));

                case 0x70:
                case 0x71:
                case 0x72:
                case 0x73:
                case 0x74:
                case 0x75:
                case 0x76:
                case 0x77:
                case 0x78:
                case 0x79:
                case 0x7A:
                case 0x7B:
                case 0x7C:
                case 0x7D:
                case 0x7E:
                case 0x7F:
                    return(string.Format("j{0} {1}", _ccNames[opCode & 0x0f], Read_Jb()));

                case 0x80:
                case 0x82:
                    // GRP1 Eb Ib
                    ReadModRM();
                    return(string.Format("{0} {1},{2}", Group1Name(_modRM >> 3), Read_Eb(), Read_Ib()));

                case 0x81:
                    // GRP1 Ev Iv
                    ReadModRM();
                    return(string.Format("{0} {1},{2}", Group1Name(_modRM >> 3), Read_Ev(), Read_Iv()));

                case 0x83:
                    // GRP1 Ev Ib
                    ReadModRM();
                    return(string.Format("{0} {1},{2}", Group1Name(_modRM >> 3), Read_Ev(), Read_Ib_sx()));

                case 0x84:
                    // Test Gb, Eb
                    return(string.Format("test {0},{1}", Read_Gb(), Read_Eb()));

                case 0x85:
                    // Test Gv, Ev
                    return(string.Format("and {0},{1}", Read_Gv(), Read_Ev()));

                case 0x86:
                    // XCHG Gb, Eb
                    return(string.Format("xchg {0},{1}", Read_Gb(), Read_Eb()));

                case 0x87:
                    // XCHG Gv, Ev
                    return(string.Format("xchg {0},{1}", Read_Gv(), Read_Ev()));

                case 0x88:
                    // MOV Eb, Gb
                    return(string.Format("mov {0},{1}", Read_Eb(), Read_Gb()));

                case 0x89:
                    // MOV Ev, Gv
                    return(string.Format("mov {0},{1}", Read_Ev(), Read_Gv()));

                case 0x8A:
                    // MOV Gb, Eb
                    return(string.Format("mov {0},{1}", Read_Gb(), Read_Eb()));

                case 0x8B:
                    // MOV Gv Ev
                    return(string.Format("mov {0},{1}", Read_Gv(), Read_Ev()));

                case 0x8C:
                    // MOV Ew Sw
                    return(string.Format("mov {0},{1}", Read_Ev(), Read_Sv()));

                case 0x8D:
                    // LEA Gv M
                    ReadModRM();
                    if (!_modRMIsPointer)
                    {
                        throw new InvalidOpCodeException();
                    }
                    return(string.Format("lea {0},{1}", Read_Gv(), Read_Eb()));

                case 0x8E:
                    // MOV Sw Ew
                    return(string.Format("mov {0},{1}", Read_Sv(), Read_Ev()));

                case 0x8F:
                    // POP Ev
                    ImplicitParams = "word ptr ss:[sp]";
                    return(string.Format("pop {0}", Read_Ev()));

                case 0x90:
                    // NOP
                    return("nop");

                case 0x91:
                case 0x92:
                case 0x93:
                case 0x94:
                case 0x95:
                case 0x96:
                case 0x97:
                    return(string.Format("xchg ax,{0}", Format((Reg16)(opCode & 0x07))));

                case 0x98:
                    return("cbw");

                case 0x99:
                    return("cwd");

                case 0x9A:
                {
                    // Read target address
                    temp = ReadWord(cs, ip);
                    ip  += 2;

                    var newcs = ReadWord(cs, ip);
                    ip += 2;

                    IsCall         = true;
                    ImplicitParams = "sp,bp";
                    return(string.Format("call 0x{0:X4}:0x{1:X4}", newcs, temp));
                }

                case 0x9B:
                    return("wait");

                case 0x9C:
                    ImplicitParams = "sp";
                    return("pushf");

                case 0x9D:
                    ImplicitParams = "sp";
                    return("popf");

                case 0x9E:
                    return("sahf");

                case 0x9F:
                    return("lahf");

                case 0xA0:
                    // MOV al, [Ob]
                    temp = ReadWord(cs, ip);
                    ip  += 2;
                    return(string.Format("mov al,byte ptr {0}[0x{1:X4}]", ResolveSegmentPtr(RegSeg.DS), temp));

                case 0xA1:
                    // MOV ax, [Ov]
                    temp = ReadWord(cs, ip);
                    ip  += 2;
                    return(string.Format("mov ax,word ptr {0}[0x{1:X4}]", ResolveSegmentPtr(RegSeg.DS), temp));

                case 0xA2:
                    // MOV [Ob], al
                    temp = ReadWord(cs, ip);
                    ip  += 2;
                    return(string.Format("mov byte ptr {0}[0x{1:X4}],al", ResolveSegmentPtr(RegSeg.DS), temp));

                case 0xA3:
                    // MOV [Ob], ax
                    temp = ReadWord(cs, ip);
                    ip  += 2;
                    return(string.Format("mov word ptr {0}[0x{1:X4}],ax", ResolveSegmentPtr(RegSeg.DS), temp));

                case 0xA4:
                    // MOVSB
                    if (_prefixSegment != RegSeg.None)
                    {
                        ImplicitParams = "es:di";
                        return(string.Format("{0}movsb byte ptr {1}[si]", RepPrefix(), ResolveSegmentPtr(RegSeg.DS)));
                    }
                    else
                    {
                        ImplicitParams = "ds:si,es:di";
                        return(string.Format("{0}movsb", RepPrefix()));
                    }


                case 0xA5:
                    // MOVSW
                    if (_prefixSegment != RegSeg.None)
                    {
                        ImplicitParams = "es:di";
                        return(string.Format("{0}movsw word ptr {1}[si]", RepPrefix(), ResolveSegmentPtr(RegSeg.DS)));
                    }
                    else
                    {
                        ImplicitParams = "ds:si,es:di";
                        return(string.Format("{0}movsw", RepPrefix()));
                    }

                case 0xA6:
                    // CMPSB
                    if (_prefixSegment != RegSeg.None)
                    {
                        ImplicitParams = "es:di";
                        return(string.Format("{0}cmpsb byte ptr {1}[si]", RepPrefix(), ResolveSegmentPtr(RegSeg.DS)));
                    }
                    else
                    {
                        ImplicitParams = "ds:si,es:di";
                        return(string.Format("{0}cmpsb", RepPrefix()));
                    }

                case 0xA7:
                    // CMPSW
                    if (_prefixSegment != RegSeg.None)
                    {
                        ImplicitParams = "es:di";
                        return(string.Format("{0}cmpsw word ptr {1}[si]", RepPrefix(), ResolveSegmentPtr(RegSeg.DS)));
                    }
                    else
                    {
                        ImplicitParams = "word ptr ds:[si],es:di";
                        return(string.Format("{0}cmpsw", RepPrefix()));
                    }

                case 0xA8:
                    // TEST AL Ib
                    return(string.Format("test al,{0}", Read_Ib()));

                case 0xA9:
                    // TEST eAX Iv
                    return(string.Format("test ax,{0}", Read_Iv()));

                case 0xAA:
                    // STOSB
                    return(string.Format("{0}stosb byte ptr es:[di]", RepPrefix()));

                case 0xAB:
                    // STOSW
                    return(string.Format("{0}stosw word ptr es:[di]", RepPrefix()));

                case 0xAC:
                    // LODSB
                    return(string.Format("{0}lodsb byte ptr {1}:[si]", RepPrefix(), ResolveSegmentPtr(RegSeg.DS)));

                case 0xAD:
                    // LODSW
                    return(string.Format("{0}lodsw word ptr {1}:[si]", RepPrefix(), ResolveSegmentPtr(RegSeg.DS)));

                case 0xAE:
                    // SCASB
                    return(string.Format("{0}scasb byte ptr es:[di]", RepCCPrefix()));

                case 0xAF:
                    // SCASW
                    return(string.Format("{0}scasw word ptr es:[di]", RepCCPrefix()));

                case 0xB0:
                case 0xB1:
                case 0xB2:
                case 0xB3:
                case 0xB4:
                case 0xB5:
                case 0xB6:
                case 0xB7:
                    return(string.Format("mov {0},{1}", Format((Reg8)(opCode & 0x07)), Read_Ib()));

                case 0xB8:
                case 0xB9:
                case 0xBA:
                case 0xBB:
                case 0xBC:
                case 0xBD:
                case 0xBE:
                case 0xBF:
                    return(string.Format("mov {0},{1}", Format((Reg16)(opCode & 0x07)), Read_Iv()));

                case 0xC0:
                    // GRP2 Eb, Ib
                    ReadModRM();
                    return(string.Format("{0} {1},{2}", Group2Name((_modRM >> 3) & 0x07), Read_Eb(), Read_Ib()));

                case 0xC1:
                    // GRP2 Ev, Ib
                    ReadModRM();
                    return(string.Format("{0} {1},{2}", Group2Name((_modRM >> 3) & 0x07), Read_Ev(), Read_Ib()));

                case 0xC2:
                    // RET Iw
                    ImplicitParams = "sp,bp";
                    return(string.Format("ret {0}", Read_Iv()));

                case 0xC3:
                    // RET
                    ImplicitParams = "sp,bp";
                    return("ret");

                case 0xC4:
                    // LES Gv Mp
                    ReadModRM();
                    if (!_modRMIsPointer)
                    {
                        throw new InvalidOpCodeException();
                    }

                    return(string.Format("les {0},d{1}", Read_Gv(), Read_Ev()));

                case 0xC5:
                    // LDS Gv Mp
                    ReadModRM();
                    if (!_modRMIsPointer)
                    {
                        throw new InvalidOpCodeException();
                    }

                    return(string.Format("lds {0},d{1}", Read_Gv(), Read_Ev()));

                case 0xC6:
                    // MOV Eb Ib
                    ReadModRM();
                    return(string.Format("mov {0},{1}", Read_Eb(), Read_Ib()));

                case 0xC7:
                    // MOV Ev Iv
                    ReadModRM();
                    return(string.Format("mov {0},{1}", Read_Ev(), Read_Iv()));

                case 0xC8:
                    // ENTER Iw, Ib
                    string storage      = Read_Iv();
                    string nestingLevel = Read_Ib();
                    return(string.Format("enter {0},{1}", storage, nestingLevel));

                case 0xC9:
                    // LEAVE
                    return("leave");

                case 0xCA:
                    // RETF Iv
                    ImplicitParams = "sp,bp";
                    return(string.Format("retf {0}", Read_Iv()));

                case 0xCB:
                    // RETF
                    ImplicitParams = "sp,bp";
                    return("retf");

                case 0xCC:
                    // INT 3
                    return("int 3");

                case 0xCD:
                    // Int Ib
                    return(string.Format("int {0}", Read_Ib()));

                case 0xCE:
                    // INTO
                    return("into");

                case 0xCF:
                    // IRET
                    return("iret");

                case 0xD0:
                    // GRP2 Eb 1
                    ReadModRM();
                    return(string.Format("{0} {1},1", Group2Name(_modRM >> 3), Read_Eb()));

                case 0xD1:
                    // GRP2 Ev 1
                    ReadModRM();
                    return(string.Format("{0} {1},1", Group2Name(_modRM >> 3), Read_Ev()));

                case 0xD2:
                    // GRP2 Eb CL
                    ReadModRM();
                    return(string.Format("{0} {1},cl", Group2Name(_modRM >> 3), Read_Eb()));

                case 0xD3:
                    // GRP2 Ev CL
                    ReadModRM();
                    return(string.Format("{0} {1},cl", Group2Name(_modRM >> 3), Read_Ev()));

                case 0xD4:
                    // AAM I0
                    return(string.Format("aam {0}", Read_Ib()));

                case 0xD5:
                    // AAD I0
                    return(string.Format("aad {0}", Read_Ib()));

                case 0xD6:
                    // -
                    throw new InvalidOpCodeException();

                case 0xD7:
                    // XLAT
                    return("xlat");

                case 0xD8:
                case 0xD9:
                case 0xDA:
                case 0xDB:
                case 0xDC:
                case 0xDD:
                case 0xDE:
                case 0xDF:
                    // -
                    throw new InvalidOpCodeException();

                case 0xE0:
                    // LOOPNZ Jb
                    return(string.Format("loopnz {0}", Read_Jb()));

                case 0xE1:
                    // LOOPZ Jb
                    return(string.Format("loopz {0}", Read_Jb()));

                case 0xE2:
                    // LOOP Jb
                    return(string.Format("loop {0}", Read_Jb()));

                case 0xE3:
                    // JCXZ Jb
                    return(string.Format("jcxz {0}", Read_Jb()));

                case 0xE4:
                    // IN AL Ib
                    return(string.Format("in al,{0}", Read_Ib()));

                case 0xE5:
                    // IN eAX Ib
                    return(string.Format("in ax,{0}", Read_Ib()));

                case 0xE6:
                    // OUT Ib AL
                    return(string.Format("out {0},al", Read_Ib()));

                case 0xE7:
                    // OUT Ib eAX
                    return(string.Format("out {0},ax", Read_Ib()));

                case 0xE8:
                    // CALL Jv
                    IsCall         = true;
                    ImplicitParams = "sp,bp";
                    return(string.Format("call {0}", Read_Jv()));

                case 0xE9:
                    // JMP Jv
                    return(string.Format("jmp {0}", Read_Jv()));

                case 0xEA:
                {
                    // JMP Ap
                    var strIp = Read_Iv();
                    return(string.Format("jmp {0}:{1}", Read_Iv(), strIp));
                }

                case 0xEB:
                    // JMP Jb
                    return(string.Format("jmp {0}", Read_Jb()));

                case 0xEC:
                    // IN AL DX
                    return("in al,dx");

                case 0xED:
                    // IN eAX DX
                    return("in ax,dx");

                case 0xEE:
                    // OUT DX AL
                    return("out dx,al");

                case 0xEF:
                    // OUT DX eAX
                    return("out dx,ax");

                case 0xF0:
                    // LOCK (Ignore)
                    throw new InvalidOpCodeException();

                case 0xF1:
                    // -
                    throw new InvalidOpCodeException();

                case 0xF2:
                    // REPNZ (Prefix)
                    throw new InvalidOpCodeException();

                case 0xF3:
                    // REPZ (Prefix)
                    throw new InvalidOpCodeException();

                case 0xF4:
                    // HLT
                    return("hlt");

                case 0xF5:
                    // CMC
                    return("cmc");

                case 0xF6:
                    // GRP3a Eb
                    ReadModRM();
                    switch ((_modRM >> 3) & 0x07)
                    {
                    case 0:
                        return(string.Format("{0} {1},{2}", Group3Name((_modRM >> 3) & 0x07), Read_Eb(), Read_Ib()));

                    default:
                        return(string.Format("{0} {1}", Group3Name((_modRM >> 3) & 0x07), Read_Eb()));
                    }

                case 0xF7:
                    // GRP3b Ev
                    ReadModRM();
                    switch ((_modRM >> 3) & 0x07)
                    {
                    case 0:
                        return(string.Format("{0} {1},{2}", Group3Name((_modRM >> 3) & 0x07), Read_Ev(), Read_Iv()));

                    default:
                        return(string.Format("{0} {1}", Group3Name((_modRM >> 3) & 0x07), Read_Ev()));
                    }

                case 0xF8:
                    return("clc");

                case 0xF9:
                    return("stc");

                case 0xFA:
                    return("cli");

                case 0xFB:
                    return("sti");

                case 0xFC:
                    return("cld");

                case 0xFD:
                    return("std");

                case 0xFE:
                    // GRP4 Eb
                    ReadModRM();
                    switch ((_modRM >> 3) & 0x07)
                    {
                    case 0: return(string.Format("inc {0}", Read_Eb()));

                    case 1: return(string.Format("dec {0}", Read_Eb()));

                    default:
                        throw new InvalidOpCodeException();
                    }

                case 0xFF:
                    // GRP5 Ev
                    ReadModRM();
                    switch ((_modRM >> 3) & 0x07)
                    {
                    case 0: return(string.Format("inc {0}", Read_Ev()));

                    case 1: return(string.Format("dec {0}", Read_Ev()));

                    case 2:
                    {
                        IsCall         = true;
                        ImplicitParams = "sp,bp";
                        return(string.Format("call {0}", Read_Ev()));
                    }

                    case 3:
                    {
                        if (!_modRMIsPointer)
                        {
                            throw new InvalidOpCodeException();
                        }
                        IsCall         = true;
                        ImplicitParams = "sp,bp";
                        return(string.Format("call d{0}", Read_Ev()));
                    }

                    case 4: return(string.Format("jmp {0}", Read_Ev()));

                    case 5:
                    {
                        if (!_modRMIsPointer)
                        {
                            throw new InvalidOpCodeException();
                        }
                        return(string.Format("jmp d{0}", Read_Ev()));
                    }

                    case 6:
                        ImplicitParams = "sp";
                        return(string.Format("push {0}", Read_Ev()));

                    case 7: throw new InvalidOpCodeException();
                    }
                    break;
                }

                throw new NotImplementedException();
            }
            catch (NotImplementedException)
            {
                ip = (ushort)(ipInstruction + 1);
                return("??");
            }
            catch (CPUException)
            {
                ip = (ushort)(ipInstruction + 1);
                return("??");
            }
        }