Esempio n. 1
0
        // test_thumb
        public static void TestThumb()
        {
            Console.WriteLine("Emulate THUMB code");

            using (var emulator = new ArmEmulator(ArmMode.Thumb))
            {
                ulong addr = 0x10000;

                // sub    sp, #0xc
                byte[] armcode =
                {
                    0x83, 0xb0
                };

                // Map 2mb of memory.
                emulator.Memory.Map(addr, 2 * 1024 * 1024, MemoryPermissions.All);
                emulator.Memory.Write(addr, armcode, (uint)armcode.Length);

                emulator.Registers.SP = 0x1234;

                emulator.Hooks.Block.Add(HookBlock, null);
                emulator.Hooks.Code.Add(HookCode, addr, addr, null);

                emulator.Start(addr | 1, addr + (ulong)armcode.Length);

                Console.WriteLine(">>> Emulation done. Below is the CPU context");
                Console.WriteLine($">>> SP = 0x{emulator.Registers.SP.ToString("x2")}");
            }
        }
Esempio n. 2
0
        // test_arm
        public static void TestArm()
        {
            Console.WriteLine("Emulate ARM code");

            using (var emulator = new ArmEmulator(ArmMode.Arm))
            {
                ulong addr = 0x10000;

                // mov r0, #0x37; sub r1, r2, r3
                byte[] armcode =
                {
                    0x37, 0x00, 0xa0, 0xe3, 0x03, 0x10, 0x42, 0xe0
                };

                // Map 2mb of memory.
                emulator.Memory.Map(addr, 2 * 1024 * 1024, MemoryPermissions.All);
                emulator.Memory.Write(addr, armcode, (ulong)armcode.Length);

                emulator.Registers.R0 = 0x1234;
                emulator.Registers.R2 = 0x6789;
                emulator.Registers.R3 = 0x3333;

                emulator.Hooks.Block.Add(HookBlock, null);
                emulator.Hooks.Code.Add(HookCode, addr, addr, null);

                emulator.Start(addr, addr + (ulong)armcode.Length);

                Console.WriteLine(">>> Emulation done. Below is the CPU context");
                Console.WriteLine($">>> R0 = 0x{emulator.Registers.R0.ToString("x2")}");
                Console.WriteLine($">>> R1 = 0x{emulator.Registers.R1.ToString("x2")}");
            }
        }
Esempio n. 3
0
        public static void Main(string[] args)
        {
            Console.WriteLine("Unicorn version - " + Version.Current);

            using (var emulator = new MipsEmulator(MipsMode.b32 | MipsMode.BigEndian))
            {
                ulong addr = 0x10000;
                byte[] mipscode =
                {
                      0x34, 0x21, 0x34, 0x56
                };
                
                emulator.Memory.Map(addr, 2 * 1024 * 1024, MemoryPermissions.All);
                emulator.Memory.Write(addr, mipscode, mipscode.Length);

                emulator.Registers._1 = 0x6789;

                emulator.Hooks.Code.Add(CodeHook, null);
                emulator.Start(addr, addr + (ulong)mipscode.Length);

                Console.WriteLine("{0}", emulator.Registers._1);
            }

            using (var emulator = new ArmEmulator(ArmMode.Arm))
            {
                ulong addr = 0x10000;

                // mov r0, #0x37; sub r1, r2, r3
                byte[] armcode =
                {
                    0x37, 0x00, 0xa0, 0xe3, 0x03, 0x10, 0x42, 0xe0
                };

                // Map 2mb of memory.
                emulator.Memory.Map(addr, 2 * 1024 * 1024, MemoryPermissions.All);
                emulator.Memory.Write(addr, armcode, armcode.Length);

                emulator.Registers.R0 = 0x1234;
                emulator.Registers.R2 = 0x6789;
                emulator.Registers.R3 = 0x3333;

                emulator.Hooks.Block.Add((emu, address, size, userToken) =>
                {
                    Console.WriteLine($">>> Tracing basic block at 0x{address.ToString("x2")}, block size = 0x{size.ToString("x2")}");
                }, null);

                emulator.Hooks.Code.Add((emu, address, size, userToken) =>
                {
                    Console.WriteLine($">>> Tracing instruction at 0x{address.ToString("x2")}, instruction size = 0x{size.ToString("x2")}");
                }, null);

                emulator.Start(addr, addr + (ulong)armcode.Length);

                Console.WriteLine(">>> Emulation done. Below is the CPU context");
                Console.WriteLine($">>> R0 = 0x{emulator.Registers.R0.ToString("x2")}");
                Console.WriteLine($">>> R1 = 0x{emulator.Registers.R1.ToString("x2")}");
            }

            /*
            using (var emulator = new X86Emulator(X86Mode.b32))
            {
                ulong addr = 0x1000000;
                byte[] x86code =
                {
                    0x41, // INC ECX
                    0x4a  // DEC EDX
                };

                var ecx = 0x1234;
                var edx = 0x7890;

                // Map 2mb of memory.
                emulator.Memory.Map(addr, 2 * 1024 * 1024, MemoryPermissions.All);

                var handle = emulator.Hooks.Code.Add(CodeHook, null);

                // Capture context.
                Console.WriteLine("-> Capturing context...");
                using (var context = emulator.Context)
                {
                    emulator.Registers.ECX = ecx;
                    emulator.Registers.EDX = edx;

                    emulator.Memory.Write(addr, x86code, x86code.Length);

                    emulator.Start(addr, addr + (ulong)x86code.Length);

                    Console.WriteLine($"ECX = {emulator.Registers.ECX}");
                    Console.WriteLine($"EDX = {emulator.Registers.EDX}");


                    Console.WriteLine("-> Restoring context...");

                    // Restore captured context.
                    emulator.Context = context;
                }

                Console.WriteLine($"ECX = {emulator.Registers.ECX}");
                Console.WriteLine($"EDX = {emulator.Registers.EDX}");
            }
            */

            Console.ReadLine();
        }
Esempio n. 4
0
        private void emulate_Click(object sender, EventArgs e)
        {
            ArmMode arm_mode = ArmMode.Arm;

            if (thumb.Checked)
            {
                arm_mode = ArmMode.Thumb;
            }
            uint addr = (uint)ReadStartAddress.Value;

            if ((addr & 1) == 1)
            {
                arm_mode = ArmMode.Thumb;
                addr--;
            }
            if (addr >= GBAMemory.ROM_ADDR)
            {
                addr -= GBAMemory.ROM_ADDR;
                U.ForceUpdate(ReadStartAddress, addr);
            }
            if (addr >= (uint)Program.ROM.Data.Length)
            {
                return;
            }
            addr += GBAMemory.ROM_ADDR;
            EncodedData enc;

            // 即时汇编
            if (arm_mode == ArmMode.Thumb)
            {
                using (Engine keystone = new Engine(Architecture.ARM, Mode.THUMB)
                {
                    ThrowOnError = true
                })
                {
                    enc = keystone.Assemble(assembly.Text, addr);
                }
            }
            else
            {
                using (Engine keystone = new Engine(Architecture.ARM, Mode.ARM)
                {
                    ThrowOnError = true
                })
                {
                    enc = keystone.Assemble(assembly.Text, addr);
                }
            }
            // 模拟运行
            using (var emulator = new ArmEmulator(arm_mode))
            {
                // load register value
                emulator.Registers.R0  = (long)r0.Value;
                emulator.Registers.R1  = (long)r1.Value;
                emulator.Registers.R2  = (long)r2.Value;
                emulator.Registers.R3  = (long)r3.Value;
                emulator.Registers.R4  = (long)r4.Value;
                emulator.Registers.R5  = (long)r5.Value;
                emulator.Registers.R6  = (long)r6.Value;
                emulator.Registers.R7  = (long)r7.Value;
                emulator.Registers.R8  = (long)r8.Value;
                emulator.Registers.R9  = (long)r9.Value;
                emulator.Registers.R10 = (long)r10.Value;
                emulator.Registers.R11 = (long)r11.Value;
                emulator.Registers.R12 = (long)r12.Value;
                emulator.Registers.SP  = (long)r13.Value;
                emulator.Registers.LR  = (long)r14.Value;
                //emulator.Registers.PC = (long)r15.Value;

                // load ROM
                if (whole_rom.Checked)
                {
                    emulator.Memory.Map(GBAMemory.ROM_ADDR, Program.ROM.Data.Length, MemoryPermissions.Execute | MemoryPermissions.Read);
                    emulator.Memory.Write(GBAMemory.ROM_ADDR, Program.ROM.Data, Program.ROM.Data.Length);
                }
                else
                {
                    emulator.Memory.Map(addr, enc.Buffer.Length, MemoryPermissions.All);
                }

                // load assembly
                emulator.Memory.Write(addr, enc.Buffer, enc.Buffer.Length);

                // 加载GBA地址布局
                if (memory.Checked)
                {
                    // laod WRAM
                    emulator.Memory.Map(GBAMemory.EWRAM_ADDR, GBAMemory.EWRAM_MAX_LENGTH, MemoryPermissions.All);
                    emulator.Memory.Map(GBAMemory.IWRAM_ADDR, GBAMemory.IWRAM_MAX_LENGTH, MemoryPermissions.All);
                    if (!String.IsNullOrEmpty(sgm.Text))
                    {
                        if (File.Exists(sgm.Text))
                        {
                            //TODO load data in .sgm to EWRAM and IWRAM
                        }
                    }

                    // load SRAM
                    emulator.Memory.Map(GBAMemory.SRAM_ADDR, GBAMemory.SRAM_MAX_LENGTH, MemoryPermissions.Write | MemoryPermissions.Read);
                    if (!String.IsNullOrEmpty(sav.Text))
                    {
                        if (File.Exists(sav.Text))
                        {
                            FileInfo fi   = new FileInfo(sav.Text);
                            byte[]   buff = new byte[Math.Min(GBAMemory.SRAM_MAX_LENGTH, fi.Length)];

                            FileStream fs = fi.OpenRead();
                            fs.Read(buff, 0, Math.Min(buff.Length, Convert.ToInt32(fs.Length)));
                            fs.Close();

                            emulator.Memory.Write(GBAMemory.SRAM_ADDR, buff, buff.Length);
                        }
                    }

                    // load BIOS
                    emulator.Memory.Map(GBAMemory.BIOS_ADDR, GBAMemory.BIOS_MAX_LENGTH, MemoryPermissions.Execute);
                    if (!String.IsNullOrEmpty(bios.Text))
                    {
                        if (File.Exists(bios.Text))
                        {
                            FileInfo fi   = new FileInfo(bios.Text);
                            byte[]   buff = new byte[Math.Min(GBAMemory.BIOS_MAX_LENGTH, fi.Length)];

                            FileStream fs = fi.OpenRead();
                            fs.Read(buff, 0, Math.Min(buff.Length, Convert.ToInt32(fs.Length)));
                            fs.Close();

                            emulator.Memory.Write(GBAMemory.BIOS_ADDR, buff, buff.Length);
                        }
                        else
                        {
                            bios.Clear();
                        }
                    }

                    // load IOREG
                    // PageSize = 1KB, 不翻倍map内存的时候会报错
                    emulator.Memory.Map(GBAMemory.IOREG_ADDR, GBAMemory.IOREG_MAX_LENGTH * 2, MemoryPermissions.Read | MemoryPermissions.Write);
                    if (!String.IsNullOrEmpty(ioreg.Text))
                    {
                        if (File.Exists(ioreg.Text))
                        {
                            FileInfo fi   = new FileInfo(ioreg.Text);
                            byte[]   buff = new byte[Math.Min(GBAMemory.IOREG_MAX_LENGTH, fi.Length)];

                            FileStream fs = fi.OpenRead();
                            fs.Read(buff, 0, Math.Min(buff.Length, Convert.ToInt32(fs.Length)));
                            fs.Close();

                            emulator.Memory.Write(GBAMemory.IOREG_ADDR, buff, buff.Length);
                        }
                    }

                    // load PALRAM
                    // PageSize = 1KB, 不翻倍map内存的时候会报错
                    emulator.Memory.Map(GBAMemory.PALRAM_ADDR, GBAMemory.PALRAM_MAX_LENGTH * 2, MemoryPermissions.Read | MemoryPermissions.Write);
                    if (!String.IsNullOrEmpty(palram.Text))
                    {
                        if (File.Exists(palram.Text))
                        {
                            FileInfo fi   = new FileInfo(palram.Text);
                            byte[]   buff = new byte[Math.Min(GBAMemory.PALRAM_MAX_LENGTH, fi.Length)];

                            FileStream fs = fi.OpenRead();
                            fs.Read(buff, 0, Math.Min(buff.Length, Convert.ToInt32(fs.Length)));
                            fs.Close();

                            emulator.Memory.Write(GBAMemory.PALRAM_ADDR, buff, buff.Length);
                        }
                    }

                    // load VRAM
                    emulator.Memory.Map(GBAMemory.VRAM_ADDR, GBAMemory.VRAM_MAX_LENGTH, MemoryPermissions.Read | MemoryPermissions.Write);
                    if (!String.IsNullOrEmpty(vram.Text))
                    {
                        if (File.Exists(vram.Text))
                        {
                            FileInfo fi   = new FileInfo(vram.Text);
                            byte[]   buff = new byte[Math.Min(GBAMemory.VRAM_MAX_LENGTH, fi.Length)];

                            FileStream fs = fi.OpenRead();
                            fs.Read(buff, 0, Math.Min(buff.Length, Convert.ToInt32(fs.Length)));
                            fs.Close();

                            emulator.Memory.Write(GBAMemory.VRAM_ADDR, buff, buff.Length);
                        }
                    }

                    // load OAM
                    // PageSize = 1KB, 不翻倍map内存的时候会报错
                    emulator.Memory.Map(GBAMemory.OAM_ADDR, GBAMemory.OAM_MAX_LENGTH * 2, MemoryPermissions.Read | MemoryPermissions.Write);
                    if (!String.IsNullOrEmpty(oam.Text))
                    {
                        if (File.Exists(oam.Text))
                        {
                            FileInfo fi   = new FileInfo(oam.Text);
                            byte[]   buff = new byte[Math.Min(GBAMemory.OAM_MAX_LENGTH, fi.Length)];

                            FileStream fs = fi.OpenRead();
                            fs.Read(buff, 0, Math.Min(buff.Length, Convert.ToInt32(fs.Length)));
                            fs.Close();

                            emulator.Memory.Write(GBAMemory.OAM_ADDR, buff, buff.Length);
                        }
                    }

                    // load address value list
                    if (!String.IsNullOrEmpty(address_value.Text))
                    {
                        foreach (string line in address_value.Lines)
                        {
                            if (String.IsNullOrWhiteSpace(line))
                            {
                                string[] record = line.Split(':');
                                if (record.Length == 2)
                                {
                                    ulong    address   = ulong.Parse(record[0], System.Globalization.NumberStyles.HexNumber);
                                    string[] byte_list = (record[1]).Split();
                                    emulator.Memory.Write(address, Array.ConvertAll <string, byte>(byte_list, s => byte.Parse(s, System.Globalization.NumberStyles.HexNumber)), byte_list.Length);
                                }
                            }
                        }
                    }
                }

                // emulate
                emulator.Start(addr, addr + (ulong)enc.Buffer.Length, new TimeSpan(0, 0, Convert.ToInt32(timeout.Value)), Convert.ToInt32(code_num_limit.Value));

                // show registers
                r0.Value = emulator.Registers.R0;
                r0.Update();
                r1.Value = emulator.Registers.R1;
                r1.Update();
                r2.Value = emulator.Registers.R2;
                r2.Update();
                r3.Value = emulator.Registers.R3;
                r3.Update();
                r4.Value = emulator.Registers.R4;
                r4.Update();
                r5.Value = emulator.Registers.R5;
                r5.Update();
                r6.Value = emulator.Registers.R6;
                r6.Update();
                r7.Value = emulator.Registers.R7;
                r7.Update();
                r8.Value = emulator.Registers.R8;
                r8.Update();
                r9.Value = emulator.Registers.R9;
                r9.Update();
                r10.Value = emulator.Registers.R10;
                r10.Update();
                r11.Value = emulator.Registers.R11;
                r11.Update();
                r12.Value = emulator.Registers.R12;
                r12.Update();
                r13.Value = emulator.Registers.SP;
                r13.Update();
                r14.Value = emulator.Registers.LR;
                r14.Update();
                r15.Value = emulator.Registers.PC;
                r15.Update();

                if (memory.Checked)
                {
                    // dump binaries

                    if (!String.IsNullOrEmpty(sav.Text))
                    {
                        byte[] buff = new byte[GBAMemory.SRAM_MAX_LENGTH];
                        emulator.Memory.Read(GBAMemory.SRAM_ADDR, buff, buff.Length);
                        FileStream   fs = new FileStream(sav.Text, FileMode.Create);
                        BinaryWriter bw = new BinaryWriter(fs);
                        bw.Write(buff, 0, buff.Length);
                        bw.Close();
                        fs.Close();
                    }

                    if (!String.IsNullOrEmpty(sgm.Text))
                    {
                        //TODO dump data in EWRAM and IWRAM to .sgm
                    }

                    if (!String.IsNullOrEmpty(ioreg.Text))
                    {
                        byte[] buff = new byte[GBAMemory.IOREG_MAX_LENGTH];
                        emulator.Memory.Read(GBAMemory.IOREG_ADDR, buff, buff.Length);
                        FileStream   fs = new FileStream(ioreg.Text, FileMode.Create);
                        BinaryWriter bw = new BinaryWriter(fs);
                        bw.Write(buff, 0, buff.Length);
                        bw.Close();
                        fs.Close();
                    }

                    if (!String.IsNullOrEmpty(palram.Text))
                    {
                        byte[] buff = new byte[GBAMemory.PALRAM_MAX_LENGTH];
                        emulator.Memory.Read(GBAMemory.PALRAM_ADDR, buff, buff.Length);
                        FileStream   fs = new FileStream(palram.Text, FileMode.Create);
                        BinaryWriter bw = new BinaryWriter(fs);
                        bw.Write(buff, 0, buff.Length);
                        bw.Close();
                        fs.Close();
                    }

                    if (!String.IsNullOrEmpty(vram.Text))
                    {
                        byte[] buff = new byte[GBAMemory.VRAM_MAX_LENGTH];
                        emulator.Memory.Read(GBAMemory.VRAM_ADDR, buff, buff.Length);
                        FileStream   fs = new FileStream(vram.Text, FileMode.Create);
                        BinaryWriter bw = new BinaryWriter(fs);
                        bw.Write(buff, 0, buff.Length);
                        bw.Close();
                        fs.Close();
                    }

                    if (!String.IsNullOrEmpty(oam.Text))
                    {
                        byte[] buff = new byte[GBAMemory.OAM_MAX_LENGTH];
                        emulator.Memory.Read(GBAMemory.OAM_ADDR, buff, buff.Length);
                        FileStream   fs = new FileStream(oam.Text, FileMode.Create);
                        BinaryWriter bw = new BinaryWriter(fs);
                        bw.Write(buff, 0, buff.Length);
                        bw.Close();
                        fs.Close();
                    }
                }
            }
        }