コード例 #1
0
        internal static void InternalParse(ImageReader reader, long offset, ref int i, RexPrefix prefix, int opCodePrefix, byte opCode, string name)
        {
            var modRM = new ModRM(reader.ReadByte());

            i += 1;

            var sib = (SIB)null;

            if (modRM.Mod != 0b_11 && modRM.Rm == 0b_100)
            {
                sib = new SIB(reader.ReadByte());
                i  += 1;
            }

            var displacementPresentation = string.Empty;

            if (modRM.Mod == 0b_00 && modRM.Rm == 0b_101)
            {
                var displacement = reader.ReadInt32();
                i += 4;
                var codes = BitConverter.GetBytes(displacement);
                displacementPresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);
            }
コード例 #2
0
        internal static IList <IntelInstruction> Decode(ImageReader reader, IntelInstructionDecoderMode mode, int codeSize)
        {
            var result = new List <IntelInstruction>();

            for (int i = 0; i < codeSize; i++)
            {
                var offset             = i + 0x8000D0E0;
                var offsetPresentation = string.Format("{0:x8} ", offset);
                var opCode             = reader.ReadByte();
                var prefix             = (RexPrefix)null;

                switch (opCode)
                {
                case 0x40:
                case 0x41:
                case 0x42:
                case 0x43:
                case 0x44:
                case 0x45:
                case 0x46:
                case 0x47:
                case 0x48:
                case 0x49:
                case 0x4a:
                case 0x4b:
                case 0x4c:
                case 0x4d:
                case 0x4e:
                case 0x4f:
                {
                    if (mode == IntelInstructionDecoderMode.x64)
                    {
                        prefix = new RexPrefix(opCode);
                    }

                    break;
                }
                }

                var prefixPresentation = prefix != null
                    ? string.Format("{0:x2} ", prefix.Code)
                    : string.Empty;

                if (prefix != null)
                {
                    opCode = reader.ReadByte();
                    i     += 1;
                }

                switch (opCode)
                {
                case 0x33:
                {
                    InternalParse(reader, offset, ref i, prefix, opCode, "xor");
                    break;
                }

                case 0x3b:
                {
                    var modRM = new ModRM(reader.ReadByte());
                    i += 1;

                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        Console.WriteLine("{0}{1:x2} {2:x2} {3}", offsetPresentation, opCode, modRM.Value, "cmp");
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        Console.WriteLine("{0}{1:x2} {2:x2} {3}", offsetPresentation, opCode, modRM.Value, "cmp");
                    }
                    else
                    {
                        throw new InvalidOperationException(mode.ToString());
                    }

                    break;
                }

                case 0x39:
                {
                    InternalParse(reader, offset, ref i, prefix, opCode, "cmp");
                    break;
                }

                case 0x50:
                {
                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "eax");
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "rax");
                    }
                    else
                    {
                        throw new InvalidOperationException(mode.ToString());
                    }

                    break;
                }

                case 0x51:
                {
                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "ecx");
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "rcx");
                    }
                    else
                    {
                        throw new InvalidOperationException(mode.ToString());
                    }

                    break;
                }

                case 0x52:
                {
                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "edx");
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "rdx");
                    }
                    else
                    {
                        throw new InvalidOperationException(mode.ToString());
                    }

                    break;
                }

                case 0x53:
                {
                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "ebx");
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "rbx");
                    }
                    else
                    {
                        throw new InvalidOperationException(mode.ToString());
                    }

                    break;
                }

                case 0x54:
                {
                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "esp");
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "rsp");
                    }
                    else
                    {
                        throw new InvalidOperationException(mode.ToString());
                    }

                    break;
                }

                case 0x55:
                {
                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "ebp");
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "rbp");
                    }
                    else
                    {
                        throw new InvalidOperationException(mode.ToString());
                    }

                    break;
                }

                case 0x56:
                {
                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        Console.WriteLine("{0}{1:x2} {2} {3}", offsetPresentation, opCode, "push", "esi");
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        if (prefix != null)
                        {
                            Console.WriteLine("{0}{1}{2:x2} {3} {4}", offsetPresentation, prefixPresentation, opCode, "push", "r14");
                        }
                        else
                        {
                            Console.WriteLine("{0}{1:x2} {2} {3}", offsetPresentation, opCode, "push", "rsi");
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException(mode.ToString());
                    }

                    break;
                }

                case 0x57:
                {
                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "edi");
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "push", "rdi");
                    }
                    else
                    {
                        throw new InvalidOperationException(mode.ToString());
                    }

                    break;
                }

                case 0x5f:
                {
                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "pop", "edi");
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        Console.WriteLine("{0:X8} {1:x2} {2} {3}", offset, opCode, "pop", "rdi");
                    }
                    else
                    {
                        throw new InvalidOperationException(mode.ToString());
                    }

                    break;
                }

                case 0x70:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jo", offset + 2 + immediate);
                    break;
                }

                case 0x71:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jno", offset + 2 + immediate);
                    break;
                }

                case 0x72:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jb", offset + 2 + immediate);
                    break;
                }

                case 0x73:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jnb", offset + 2 + immediate);
                    break;
                }

                case 0x74:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jz", offset + 2 + immediate);
                    break;
                }

                case 0x75:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jnz", offset + 2 + immediate);
                    break;
                }

                case 0x76:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jbe", offset + 2 + immediate);
                    break;
                }

                case 0x77:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "ja", offset + 2 + immediate);
                    break;
                }

                case 0x78:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "js", offset + 2 + immediate);
                    break;
                }

                case 0x79:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jns", offset + 2 + immediate);
                    break;
                }

                case 0x7a:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jp", offset + 2 + immediate);
                    break;
                }

                case 0x7b:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jnp", offset + 2 + immediate);
                    break;
                }

                case 0x7c:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jl", offset + 2 + immediate);
                    break;
                }

                case 0x7d:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jnl", offset + 2 + immediate);
                    break;
                }

                case 0x7e:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jle", offset + 2 + immediate);
                    break;
                }

                case 0x7f:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jnle", offset + 2 + immediate);
                    break;
                }

                case 0x81:
                {
                    var modRM = new ModRM(reader.ReadByte());
                    i += 1;

                    var mnemonic = string.Empty;

                    switch (modRM.Reg)
                    {
                    case 0: mnemonic = "add"; break;

                    case 1: mnemonic = "or";  break;

                    case 2: mnemonic = "adc"; break;

                    case 3: mnemonic = "sbb"; break;

                    case 4: mnemonic = "and"; break;

                    case 5: mnemonic = "sub"; break;

                    case 6: mnemonic = "xor"; break;

                    case 7: mnemonic = "cmp"; break;
                    }

                    uint   immediate;
                    string codePresentation;

                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        immediate = reader.ReadUInt16();
                        i        += 2;
                        var codes = BitConverter.GetBytes(immediate);
                        codePresentation = string.Format("{0:x2} {1:x2}", codes[0], codes[1]);
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        immediate = reader.ReadUInt32();
                        i        += 4;
                        var codes = BitConverter.GetBytes(immediate);
                        codePresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4:x2} {5}", offsetPresentation, prefixPresentation, opCode, modRM.Value, codePresentation, mnemonic);
                    break;
                }

                case 0x83:
                {
                    InternalParse(reader, offset, ref i, prefix, opCode, x =>
                        {
                            switch (x.Reg)
                            {
                            case 0: return("add");

                            case 1: return("or");

                            case 2: return("adc");

                            case 3: return("sbb");

                            case 4: return("and");

                            case 5: return("sub");

                            case 6: return("xor");

                            case 7: return("cmp");
                            }

                            throw new NotSupportedException();
                        });
                    break;
                }

                case 0x85:
                {
                    var modRM = new ModRM(reader.ReadByte());
                    i += 1;

                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        Console.WriteLine("{0}{1:x2} {2:x2} {3}", offsetPresentation, opCode, modRM.Value, "test");
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        Console.WriteLine("{0}{1}{2:x2} {3:x2} {4}", offsetPresentation, prefixPresentation, opCode, modRM.Value, "test");
                    }
                    else
                    {
                        throw new InvalidOperationException(mode.ToString());
                    }

                    break;
                }

                case 0x89:
                {
                    InternalParse(reader, offset, ref i, prefix, opCode, "mov");
                    break;
                }

                case 0x8b:
                {
                    InternalParse(reader, offset, ref i, prefix, opCode, "mov");
                    break;
                }

                case 0x8d:
                {
                    InternalParse(reader, offset, ref i, prefix, opCode, "lea");
                    break;
                }

                case 0xbe:
                {
                    var immediate = reader.ReadUInt32();
                    i += 4;

                    var codes            = BitConverter.GetBytes(immediate);
                    var codePresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);

                    Console.WriteLine("{0}{1:x2} {2} {3} esi, 0x{4:x}", offsetPresentation, opCode, codePresentation, "mov", immediate);
                    break;
                }

                case 0xcc:
                {
                    Console.WriteLine("{0}{1:x2} {2}", offsetPresentation, opCode, "int 3");
                    break;
                }

                case 0xe8:
                {
                    uint   immediate;
                    string codePresentation;

                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        immediate = reader.ReadUInt16();
                        i        += 2;

                        var codes = BitConverter.GetBytes(immediate);
                        codePresentation = string.Format("{0:x2} {1:x2}", codes[0], codes[1]);
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        immediate = reader.ReadUInt32();
                        i        += 4;

                        var codes = BitConverter.GetBytes(immediate);
                        codePresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }

                    Console.WriteLine("{0}{1:x2} {2} {3} {4:x4}", offsetPresentation, opCode, codePresentation, "call", offset + 5 + immediate);
                    break;
                }

                case 0xe9:
                {
                    uint   immediate;
                    string codePresentation;

                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        immediate = reader.ReadUInt16();
                        i        += 2;
                        var codes = BitConverter.GetBytes(immediate);
                        codePresentation = string.Format("{0:x2} {1:x2}", codes[0], codes[1]);
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        immediate = reader.ReadUInt32();
                        i        += 4;
                        var codes = BitConverter.GetBytes(immediate);
                        codePresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }

                    Console.WriteLine("{0}{1:x2} {2} {3} {4:x4}", offsetPresentation, opCode, codePresentation, "jmp", offset + 5 + immediate);
                    break;
                }

                case 0xeb:
                {
                    var immediate = reader.ReadByte();
                    i += 1;

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4} 0x{5:x2}", offsetPresentation, prefixPresentation, opCode, immediate, "jmp", offset + 2 + immediate);
                    break;
                }

                case 0x0f:
                {
                    opCode = reader.ReadByte();
                    i     += 1;

                    var opCodePresentation = string.Format("{0:x2} {1:x2} ", 0x0f, opCode);

                    switch (opCode)
                    {
                    case 0x44:
                    {
                        InternalParse(reader, offset, ref i, prefix, 0x0f, opCode, "cmovz");
                        break;
                    }

                    case 0x84:
                    {
                        var immediate = reader.ReadInt32();
                        i += 4;

                        if (mode == IntelInstructionDecoderMode.x86)
                        {
                            var codes            = BitConverter.GetBytes(immediate);
                            var codePresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);

                            Console.WriteLine("{0}{1}{2} {3} {4:x}", offsetPresentation, opCodePresentation, codePresentation, "jz", offset + immediate + 6);
                        }
                        else if (mode == IntelInstructionDecoderMode.x64)
                        {
                            var codes            = BitConverter.GetBytes(immediate);
                            var codePresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);

                            Console.WriteLine("{0}{1}{2} {3} {4:x}", offsetPresentation, opCodePresentation, codePresentation, "jz", offset + immediate + 6);
                        }
                        else
                        {
                            throw new InvalidOperationException(mode.ToString());
                        }

                        break;
                    }

                    case 0x85:
                    {
                        var immediate = reader.ReadInt32();
                        i += 4;

                        if (mode == IntelInstructionDecoderMode.x86)
                        {
                            var codes            = BitConverter.GetBytes(immediate);
                            var codePresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);

                            Console.WriteLine("{0}{1}{2} {3} {4:x}", offsetPresentation, opCodePresentation, codePresentation, "jnz", offset + immediate + 6);
                        }
                        else if (mode == IntelInstructionDecoderMode.x64)
                        {
                            var codes            = BitConverter.GetBytes(immediate);
                            var codePresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);

                            Console.WriteLine("{0}{1}{2} {3} {4:x}", offsetPresentation, opCodePresentation, codePresentation, "jnz", offset + immediate + 6);
                        }
                        else
                        {
                            throw new InvalidOperationException(mode.ToString());
                        }

                        break;
                    }

                    case 0x87:
                    {
                        var immediate = reader.ReadInt32();
                        i += 4;

                        if (mode == IntelInstructionDecoderMode.x86)
                        {
                            var codes            = BitConverter.GetBytes(immediate);
                            var codePresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);

                            Console.WriteLine("{0}{1}{2} {3} {4:x}", offsetPresentation, opCodePresentation, codePresentation, "ja", offset + immediate + 6);
                        }
                        else if (mode == IntelInstructionDecoderMode.x64)
                        {
                            var codes            = BitConverter.GetBytes(immediate);
                            var codePresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);

                            Console.WriteLine("{0}{1}{2} {3} {4:x}", offsetPresentation, opCodePresentation, codePresentation, "ja", offset + immediate + 6);
                        }
                        else
                        {
                            throw new InvalidOperationException(mode.ToString());
                        }

                        break;
                    }

                    default:
                    {
                        throw new InvalidOperationException(string.Format("0x0f 0x{0:x2}", opCode));
                    }
                    }

                    break;
                }

                case 0xff:
                {
                    var modRM = new ModRM(reader.ReadByte());
                    i += 1;

                    var mnemonic = string.Empty;

                    switch (modRM.Reg)
                    {
                    case 0: mnemonic = "inc";   break;

                    case 1: mnemonic = "dec";   break;

                    case 2: mnemonic = "call";  break;

                    case 3: mnemonic = "callf"; break;

                    case 4: mnemonic = "jmp";   break;

                    case 5: mnemonic = "jmpf";  break;

                    case 6: mnemonic = "push";  break;
                    }

                    uint   immediate;
                    string codePresentation;

                    if (mode == IntelInstructionDecoderMode.x86)
                    {
                        immediate = reader.ReadUInt16();
                        i        += 2;
                        var codes = BitConverter.GetBytes(immediate);
                        codePresentation = string.Format("{0:x2} {1:x2}", codes[0], codes[1]);
                    }
                    else if (mode == IntelInstructionDecoderMode.x64)
                    {
                        immediate = reader.ReadUInt32();
                        i        += 4;
                        var codes = BitConverter.GetBytes(immediate);
                        codePresentation = string.Format("{0:x2} {1:x2} {2:x2} {3:x2}", codes[0], codes[1], codes[2], codes[3]);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }

                    Console.WriteLine("{0}{1}{2:x2} {3:x2} {4:x2} {5}", offsetPresentation, prefixPresentation, opCode, modRM.Value, codePresentation, mnemonic);
                    break;
                }

                default:
                {
                    throw new InvalidOperationException(string.Format("0x{0:x2}", opCode));
                }
                }
            }

            return(result);
        }