Пример #1
0
        private static void AlalyzeBlock(MemoryStream memory, ushort address, OpCodeArray opCodes, HashSet <ushort> codeAddress)
        {
            while (true)
            {
                ushort addr = (ushort)(address + memory.Position);
                if (codeAddress.Contains(addr))
                {
                    return;
                }
                var code = memory.ReadByte();
                if (code == -1)
                {
                    return;
                }
                var item = opCodes.List[code];
                if (item == null)
                {
                    return;
                }
                item.Parse(memory);
                codeAddress.Add(addr);
                string command = item.ToString();

                // Обрабатываем команды переходов jmp
                if (jumpOpCodes.Any(c => command.StartsWith(c)))
                {
                    // При выходе за пределы код прекращаем анализ
                    if (item.ParamWord !.Value < address || item.ParamWord !.Value > address + memory.Length)
                    {
                        return;
                    }
                    // Если анализа еще не было, то делаем его.
                    if (!codeAddress.Contains(item.ParamWord.Value))
                    {
                        var position = memory.Position;
                        memory.Seek(item.ParamWord.Value - address, SeekOrigin.Begin);
                        AlalyzeBlock(memory, address, opCodes, codeAddress);
                        memory.Seek(position, SeekOrigin.Begin);
                    }
                }
                // Обрабатываем команды вызовов функций call
                if (callOpCodes.Any(c => command.StartsWith(c)))
                {
                    // При выходе за пределы кода, например вызов системных функций, продолжаем анализ
                    if (item.ParamWord !.Value < address || item.ParamWord !.Value > address + memory.Length)
                    {
                        continue;
                    }
                    // Если анализа еще не было, то делаем его.
                    if (!codeAddress.Contains(item.ParamWord.Value))
                    {
                        var position = memory.Position;
                        memory.Seek(item.ParamWord.Value - address, SeekOrigin.Begin);
                        AlalyzeBlock(memory, address, opCodes, codeAddress);
                        memory.Seek(position, SeekOrigin.Begin);
                    }
                }

                // Обрабатываем команды выхода из функций ret
                if (retOpCodes.Any(c => command.StartsWith(c)))
                {
                    return;
                }
            }
        }
Пример #2
0
        static void Main(string[] args)
        {
            ushort org = 0x0000;

            string text;

            #region  азбор параметров командной строки
            string?includePath = null;
            string?fileName    = null;
            Dictionary <string, string>?comments = null;
            Dictionary <string, string>?labels   = null;
            Dictionary <string, string>?datas    = null;
            for (int i = 1; i < args.Length; i++)
            {
                string arg = args[i];
                if (arg.ToLower().StartsWith("c:"))
                {
                    string path = arg.Substring(2).Trim('\"');
                    comments = ConfigLoader.LoadDictionary(path);
                }
                if (arg.ToLower().StartsWith("l:"))
                {
                    string path = arg.Substring(2).Trim('\"');
                    labels = ConfigLoader.LoadDictionary(path);
                }
                if (arg.ToLower().StartsWith("d:"))
                {
                    string path = arg.Substring(2).Trim('\"');
                    datas = ConfigLoader.LoadDictionary(path);
                }
                if (arg.ToLower().StartsWith("o:"))
                {
                    fileName = arg.Substring(2).Trim('\"');
                }
                if (arg.ToLower().StartsWith("i:"))
                {
                    includePath = arg.Substring(2).Trim('\"');
                }
                if (arg.ToLower().StartsWith("s:"))
                {
                    org = arg.Substring(2).ParseHex();
                }
            }
            try
            {
                if (comments == null)
                {
                    throw new ArgumentNullException();
                }
                if (labels == null)
                {
                    throw new ArgumentNullException();
                }
                if (datas == null)
                {
                    throw new ArgumentNullException();
                }
                if (fileName == null)
                {
                    throw new ArgumentNullException();
                }
            }
            catch (Exception)
            {
                Console.WriteLine("dasm <path> l:<label> c:<comment> d:<data> [i:<include>] [s:<start>] o:<file>");
                Console.WriteLine("<path>\t\tфайл который надо дизассемблировать");
                Console.WriteLine("<label>\t\tфайл содержащий описания меток (label)");
                Console.WriteLine("<comment>\tфайл содержащий описания комментариев (comment)");
                Console.WriteLine("<data>\t\tфайл содержащий описания данных и их типов");
                Console.WriteLine("<start>\t\tначало кода в памяти, для истркуциии ORG [не обязателено]");
                Console.WriteLine("<include>\tфайл заголовка, подключается в самое начало [не обязателено]");
                Console.WriteLine("<file>\t\tфайл с результатом дизассемблирования");
                return;
            }
            #endregion

            OpCodeArray codeArray = new OpCodeArray(labels);
            OpDataArray dataArray = new OpDataArray();

            using (var stream = File.OpenRead(args[0]))
                using (var writer = File.CreateText(fileName))
                {
                    if (!String.IsNullOrEmpty(includePath))
                    {
                        writer.WriteLine(File.ReadAllText(includePath));
                    }

                    writer.WriteLine(String.Format("ORG {0}", org.ToHex()));
                    writer.WriteLine();

                    while (true)
                    {
                        try
                        {
                            ushort current = (ushort)(org + stream.Position);
                            string addr    = current.ToHex();

                            if (datas.ContainsKey(addr))
                            {
                                text = dataArray.Get(datas[addr]).ToString(stream);
                            }
                            else
                            {
                                if (stream.Position == stream.Length)
                                {
                                    break;
                                }
                                byte data = (byte)stream.ReadByte();
                                text = codeArray.Handle(data, stream);
                            }

                            text = String.Format("{0, -32}", text); // Форматируем строку
                            string note = comments.ContainsKey(addr) ? comments[addr] : "";
                            if (labels.ContainsKey(addr))
                            {
                                var label = labels[addr];
                                if (label.StartsWith(";"))
                                {
                                    label = label.Substring(1);
                                    writer.WriteLine();
                                }
                                writer.WriteLine(String.Format("{0}:", label));
                            }
                            if (note.StartsWith(";"))
                            {
                                foreach (var commentLine in note.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                                {
                                    writer.WriteLine(String.Format(";{0}", commentLine));
                                }
                                writer.WriteLine(String.Format("    {0};{1}", text, addr));
                            }
                            else
                            {
                                writer.WriteLine(String.Format("    {0};{1} {2}", text, addr, note));
                            }
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("ERROR");
                            break;
                        }
                    }
                }
        }