예제 #1
0
파일: Program.cs 프로젝트: NewMai/iced
        static (uint totValid, ulong totBytesValid, uint totInvalid, ulong totBytesInvalid) Gen(Options options, OpCodeInfo[] infos)
        {
            var genFlags = InstrGenFlags.None;

            if (options.UnusedTables)
            {
                genFlags |= InstrGenFlags.UnusedTables;
            }
            if (!options.OpCodeInfoOptions.IncludeVEX)
            {
                genFlags |= InstrGenFlags.NoVEX;
            }
            if (!options.OpCodeInfoOptions.IncludeXOP)
            {
                genFlags |= InstrGenFlags.NoXOP;
            }
            if (!options.OpCodeInfoOptions.IncludeEVEX)
            {
                genFlags |= InstrGenFlags.NoEVEX;
            }
            if (!options.OpCodeInfoOptions.Include3DNow)
            {
                genFlags |= InstrGenFlags.No3DNow;
            }
            if (options.OpCodeInfoOptions.Filter.WasRemoved(CpuidFeature.AVX))
            {
                genFlags |= InstrGenFlags.NoAVX;
            }
            if (options.OpCodeInfoOptions.Filter.WasRemoved(CpuidFeature.AVX2))
            {
                genFlags |= InstrGenFlags.NoAVX2;
            }
            var encodingTables = InstrGen.Create(options.OpCodeInfoOptions.Bitness, infos, genFlags);

            var instructions = encodingTables.GetOpCodeGroups().SelectMany(a => a.opCodes).SelectMany(a => a.Instructions).Where(instr => {
                if (!options.Filter.ShouldInclude(instr.Code, instr.IsModrmMemory))
                {
                    return(false);
                }
                if (instr.Code == Code.INVALID)
                {
                    return(options.IncludeInvalidInstructions);
                }
                return(options.IncludeValidInstructions);
            }).ToArray();

            FileStream?  validStream   = null;
            FileStream?  invalidStream = null;
            BinaryWriter?validWriter   = null;
            BinaryWriter?invalidWriter = null;
            var          data2         = new byte[2];

            try {
                if (options.ValidFilename is object)
                {
                    CreateFile(ref validStream, ref validWriter, options.ValidFilename);
                }
                if (options.InvalidFilename is object)
                {
                    CreateFile(ref invalidStream, ref invalidWriter, options.InvalidFilename);
                }

                var fuzzerOptions = FuzzerOptions.NoPAUSE | FuzzerOptions.NoWBNOINVD |
                                    FuzzerOptions.NoTZCNT | FuzzerOptions.NoLZCNT;
                if (options.OpCodeInfoOptions.Filter.FilterEnabled || options.Filter.FilterEnabled)
                {
                    fuzzerOptions |= FuzzerOptions.NoVerifyInstrs;
                }
                if (!options.OpCodeInfoOptions.Filter.WasRemoved(CpuidFeature.MPX))
                {
                    fuzzerOptions |= FuzzerOptions.HasMPX;
                }
                foreach (var instr in instructions)
                {
                    switch (instr.Code)
                    {
                    case Code.Pause:
                        fuzzerOptions &= ~FuzzerOptions.NoPAUSE;
                        break;

                    case Code.Wbnoinvd:
                        fuzzerOptions &= ~FuzzerOptions.NoWBNOINVD;
                        break;

                    case Code.Tzcnt_r16_rm16:
                    case Code.Tzcnt_r32_rm32:
                    case Code.Tzcnt_r64_rm64:
                        fuzzerOptions &= ~FuzzerOptions.NoTZCNT;
                        break;

                    case Code.Lzcnt_r16_rm16:
                    case Code.Lzcnt_r32_rm32:
                    case Code.Lzcnt_r64_rm64:
                        fuzzerOptions &= ~FuzzerOptions.NoLZCNT;
                        break;
                    }
                }

                var   fuzzer          = new Fuzzer(options.OpCodeInfoOptions.Bitness, fuzzerOptions, options.OpCodeInfoOptions.CpuDecoder);
                ulong totBytesValid   = 0;
                ulong totBytesInvalid = 0;
                uint  totValid        = 0;
                uint  totInvalid      = 0;
                foreach (var info in fuzzer.GetInstructions(instructions))
                {
                    BinaryWriter?writer;
                    bool         writeLength;
                    bool         writeCodeValue;
                    if (info.Invalid)
                    {
                        totBytesInvalid += (uint)info.EncodedDataLength;
                        totInvalid++;
                        writer         = invalidWriter;
                        writeLength    = true;
                        writeCodeValue = false;
                    }
                    else
                    {
                        totBytesValid += (uint)info.EncodedDataLength;
                        totValid++;
                        writer         = validWriter;
                        writeLength    = options.IncludeValidByteLength;
                        writeCodeValue = options.IncludeValidCodeValue;
                    }
                    if (writer is object)
                    {
                        if (writeCodeValue)
                        {
                            uint code = (uint)info.Instruction.Code;
                            if (code > ushort.MaxValue)
                            {
                                throw new InvalidOperationException();
                            }
                            data2[0] = (byte)code;
                            data2[1] = (byte)(code >> 8);
                            writer.Write(data2, 0, 2);
                        }
                        if (writeLength)
                        {
                            data2[0] = (byte)info.EncodedDataLength;
                            writer.Write(data2, 0, 1);
                        }
                        writer.Write(info.EncodedData, 0, info.EncodedDataLength);
                    }
                }
                return(totValid, totBytesValid, totInvalid, totBytesInvalid);
            }
            finally {
                validWriter?.Dispose();
                invalidWriter?.Dispose();
                validStream?.Dispose();
                invalidStream?.Dispose();
            }
        }
예제 #2
0
파일: Program.cs 프로젝트: NewMai/iced
        static Options ParseOptions(string[] args)
        {
            var options = new Options();
            var toCpuid = ((CpuidFeature[])Enum.GetValues(typeof(CpuidFeature))).ToDictionary(a => a.ToString(), a => a, StringComparer.OrdinalIgnoreCase);
            var toCode  = ((Code[])Enum.GetValues(typeof(Code))).ToDictionary(a => a.ToString(), a => a, StringComparer.OrdinalIgnoreCase);

            for (int i = 0; i < args.Length; i++)
            {
                var arg  = args[i];
                var next = i + 1 < args.Length ? args[i + 1] : null;
                switch (arg)
                {
                case "-h":
                case "--help":
                    throw new CommandLineParserException(string.Empty);

                case "--quiet":
                    options.Quiet = true;
                    break;

                case "-16":
                    SetBitness(options, 16);
                    break;

                case "-32":
                    SetBitness(options, 32);
                    break;

                case "-64":
                    SetBitness(options, 64);
                    break;

                case "--show-instructions":
                    options.PrintInstructions = true;
                    break;

                case "--intel":
                    options.OpCodeInfoOptions.CpuDecoder = CpuDecoder.Intel;
                    break;

                case "--amd":
                    options.OpCodeInfoOptions.CpuDecoder = CpuDecoder.AMD;
                    break;

                case "--no-vex":
                    options.OpCodeInfoOptions.IncludeVEX = false;
                    break;

                case "--no-xop":
                    options.OpCodeInfoOptions.IncludeXOP = false;
                    break;

                case "--no-evex":
                    options.OpCodeInfoOptions.IncludeEVEX = false;
                    break;

                case "--no-3dnow":
                    options.OpCodeInfoOptions.Include3DNow = false;
                    options.OpCodeInfoOptions.Filter.ExcludeCode.Add(Code.Femms);
                    options.OpCodeInfoOptions.Filter.ExcludeCpuid.Add(CpuidFeature.CYRIX_D3NOW);
                    break;

                case "--no-geode-3dnow":
                    options.OpCodeInfoOptions.Filter.ExcludeCpuid.Add(CpuidFeature.CYRIX_D3NOW);
                    break;

                case "--no-padlock":
                    options.OpCodeInfoOptions.Filter.ExcludeCpuid.Add(CpuidFeature.PADLOCK_ACE);
                    options.OpCodeInfoOptions.Filter.ExcludeCpuid.Add(CpuidFeature.PADLOCK_PHE);
                    options.OpCodeInfoOptions.Filter.ExcludeCpuid.Add(CpuidFeature.PADLOCK_PMM);
                    options.OpCodeInfoOptions.Filter.ExcludeCpuid.Add(CpuidFeature.PADLOCK_RNG);
                    break;

                case "--no-unused-tables":
                    options.UnusedTables = false;
                    break;

                case "--include-cpuid":
                    AddCpuid(options.OpCodeInfoOptions.Filter.IncludeCpuid, toCpuid, next);
                    i++;
                    break;

                case "--exclude-cpuid":
                    AddCpuid(options.OpCodeInfoOptions.Filter.ExcludeCpuid, toCpuid, next);
                    i++;
                    break;

                case "--include-code":
                    AddCode(options.OpCodeInfoOptions.Filter.IncludeCode, toCode, next);
                    i++;
                    break;

                case "--exclude-code":
                    AddCode(options.OpCodeInfoOptions.Filter.ExcludeCode, toCode, next);
                    i++;
                    break;

                case "--gen-include-cpuid":
                    AddCpuid(options.Filter.IncludeCpuid, toCpuid, next);
                    i++;
                    break;

                case "--gen-exclude-cpuid":
                    AddCpuid(options.Filter.ExcludeCpuid, toCpuid, next);
                    i++;
                    break;

                case "--gen-include-code":
                    AddCode(options.Filter.IncludeCode, toCode, next);
                    i++;
                    break;

                case "--gen-exclude-code":
                    AddCode(options.Filter.ExcludeCode, toCode, next);
                    i++;
                    break;

                case "--no-invalid-instr":
                    options.IncludeInvalidInstructions = false;
                    break;

                case "--no-valid-instr":
                    options.IncludeValidInstructions = false;
                    break;

                case "-oil":
                    if (next is null)
                    {
                        throw new CommandLineParserException("Missing filename");
                    }
                    if (options.ValidFilename is object)
                    {
                        throw new CommandLineParserException("Can't use -oil twice");
                    }
                    options.InvalidFilename = next;
                    i++;
                    break;

                case "-ov":
                    AddValidFilename(options, next, false);
                    i++;
                    break;

                case "-ovl":
                    AddValidFilename(options, next, true);
                    i++;
                    break;

                case "-ovlc":
                    AddValidFilename(options, next, true);
                    options.IncludeValidCodeValue = true;
                    i++;
                    break;

                default:
                    throw new CommandLineParserException($"Unknown option {arg}");
                }
            }

            if (options.OpCodeInfoOptions.Bitness == 0)
            {
                throw new CommandLineParserException("Missing bitness: -16 -32 or -64");
            }
            if (!options.PrintInstructions)
            {
                if (options.ValidFilename is null && options.InvalidFilename is null)
                {
                    throw new CommandLineParserException("At least one of -oil, -ovl, -ovlc and -ov must be used");
                }
            }
            return(options);
        }
예제 #3
0
파일: Program.cs 프로젝트: NewMai/iced
 static OpCodeInfo[] GetOpCodeInfos(Options options) =>
 OpCodeInfoProvider.GetOpCodeInfos(options.OpCodeInfoOptions);