// test_i386_loop public static void TestLoop() { var addr = 0x1000000UL; var code = new byte[] { 0x41, // INC ecx 0x4A, // DEC edx 0xEB, // JMP self-loop 0xFE }; Console.WriteLine("==================================="); Console.WriteLine("Emulate i386 code that emulates forever."); using (var emulator = new X86Emulator(X86Mode.b32)) { // Map 2MB of memory. emulator.Memory.Map(addr, 2 * 1024 * 1024, MemoryPermissions.All); // Write machine code to be emulated. emulator.Memory.Write(addr, code, (uint)code.Length); // Initialize registers. emulator.Registers.ECX = 0x1234; emulator.Registers.EDX = 0x7890; // Emulate code for 2 seconds, so we can exit the code since it loops forever. emulator.Start(addr, addr + (ulong)code.Length, TimeSpan.FromSeconds(2), 0); Console.WriteLine(">>> Emulation done. Below is the CPU context"); Console.WriteLine($">>> ECX = 0x{emulator.Registers.ECX.ToString("x2")}"); Console.WriteLine($">>> EDX = 0x{emulator.Registers.EDX.ToString("x2")}"); } }
public override Program Load(Address addrLoad) { // First load the file as a PE Executable. This gives us a (writeable) image and // the packed entry point. var pe = CreatePeImageLoader(); var program = pe.Load(pe.PreferredBaseAddress); var rr = pe.Relocate(program, pe.PreferredBaseAddress); this.ImageMap = program.SegmentMap; this.Architecture = (IntelArchitecture)program.Architecture; var win32 = new Win32Emulator(program.SegmentMap, program.Platform, program.ImportReferences); var state = (X86State)program.Architecture.CreateProcessorState(); var emu = new X86Emulator((IntelArchitecture)program.Architecture, program.SegmentMap, win32); this.debugger = new Debugger(emu); this.scriptInterpreter = new OllyLang(Services); this.scriptInterpreter.Host = new Host(this, program.SegmentMap); this.scriptInterpreter.Debugger = this.debugger; emu.InstructionPointer = rr.EntryPoints[0].Address; emu.BeforeStart += emu_BeforeStart; emu.ExceptionRaised += emu_ExceptionRaised; var stackSeg = InitializeStack(emu); LoadScript(Argument, scriptInterpreter.script); emu.Start(); TearDownStack(stackSeg); foreach (var ic in win32.InterceptedCalls) { program.InterceptedCalls.Add(Address.Ptr32(ic.Key), ic.Value); } return(program); }
// test_i386_context_save public static void TestContextSave() { var addr = 0x1000000UL; var code = new byte[] { 0x40, // INC eax }; Console.WriteLine("==================================="); Console.WriteLine("Save/restore CPU context in opaque blob."); using (var emulator = new X86Emulator(X86Mode.b32)) { // Map 8KB of memory for emulation. emulator.Memory.Map(addr, 8 * 1024, MemoryPermissions.All); // Write machine code to emulate. emulator.Memory.Write(addr, code, (uint)code.Length); // Initialize registers. emulator.Registers.EAX = 1; // Emulate written machine code. emulator.Start(addr, addr + (ulong)code.Length); Console.WriteLine(">>> Emulation done. Below is the CPU context"); Console.WriteLine($">>> EAX = 0x{emulator.Registers.EAX.ToString("x2")}"); Console.WriteLine(">>> Saving CPU context"); using (var context = emulator.Context) { Console.WriteLine(">>> Running emulation for the second time"); // Emulate machine code again. emulator.Start(addr, addr + (ulong)code.Length); Console.WriteLine(">>> Emulation done. Below is the CPU context"); Console.WriteLine($">>> EAX = 0x{emulator.Registers.EAX.ToString("x2")}"); emulator.Context = context; } Console.WriteLine(">>> CPU context restored. Below is the CPU context"); Console.WriteLine($">>> EAX = 0x{emulator.Registers.EAX.ToString("x2")}"); } }
// test_i386_invalid_mem_write public static void TestInvalidMemoryWrite() { var addr = 0x1000000UL; var code = new byte[] { 0x89, 0x0D, 0xAA, 0xAA, 0xAA, 0xAA, // MOV [0xaaaaaaaa] ecx 0x41, // INC ecx 0x4A // DEC edx }; Console.WriteLine("==================================="); Console.WriteLine("Emulate i386 code that write to invalid memory."); using (var emulator = new X86Emulator(X86Mode.b32)) { // Map 2MB of memory. emulator.Memory.Map(addr, 2 * 1024 * 1024, MemoryPermissions.All); // Write machine code to be emulated. emulator.Memory.Write(addr, code, (uint)code.Length); // Initialize registers. emulator.Registers.ECX = 0x1234; emulator.Registers.EDX = 0x7890; emulator.Hooks.Code.Add(CodeHook, null); emulator.Hooks.Memory.Add(MemoryEventHookType.UnmappedRead | MemoryEventHookType.UnmappedWrite, InvalidMemoryHook, null); // Start emulating the machine written machine code. emulator.Start(addr, addr + (ulong)code.Length); Console.WriteLine(">>> Emulation done. Below is the CPU context"); Console.WriteLine($">>> ECX = 0x{emulator.Registers.ECX.ToString("x2")}"); Console.WriteLine($">>> EDX = 0x{emulator.Registers.EDX.ToString("x2")}"); // Read from memory. var buffer = new byte[4]; var tmp = 0; emulator.Memory.Read(0xAAAAAAAA, buffer, (uint)buffer.Length); tmp = BitConverter.ToInt32(buffer, 0); Console.WriteLine($">>> Read 4 bytes from [0x{0xAAAAAAAA.ToString("x2")}] = 0x{tmp.ToString("x2")}"); try { emulator.Memory.Read(0xFFFFFFAA, buffer, (uint)buffer.Length); tmp = BitConverter.ToInt32(buffer, 0); Console.WriteLine($">>> Read 4 bytes from [0x{0xFFFFFFAA.ToString("x2")}] = 0x{tmp.ToString("x2")}"); } catch { Console.WriteLine($">>> Failed to read 4 bytes from [0x{0xFFFFFFAA.ToString("x2")}]"); } } }
public static long Test(byte[] file, ulong offset, uint value) { uint in_value = value; ulong stack_pointer = addr + (ulong)stack_offset; byte[] code = file.Skip((int)offset).ToArray(); byte[] real_code = new byte[0x2000]; Array.Copy(code, real_code, real_code.Length); // Console.WriteLine("Emulate i386 code"); using (X86Emulator emulator = new X86Emulator(X86Mode.b32)) { emulator.Memory.Map(addr, 1024 * 1024 * 1024, MemoryPermissions.All); emulator.Memory.Write(addr, real_code, real_code.Length); byte[] esp_b = BitConverter.GetBytes(in_value); //Array.Reverse(esp_b); emulator.Memory.Write(stack_pointer + 4, BitConverter.GetBytes(in_value), sizeof(uint)); emulator.Registers.ESP = (long)stack_pointer; //emulator.Registers.ECX = (long)esp; emulator.Registers.EAX = 0x0; emulator.Registers.EBX = 0x0; emulator.Hooks.Code.Add(HookCode, null); emulator.Hooks.Interrupt.Add(HookInterrupt, null); // Console.WriteLine(); // Console.WriteLine(">>> Start tracing this Linux code"); try { emulator.Start(addr, addr + (ulong)real_code.Length); } catch { } GC.Collect(); return(emulator.Registers.EAX); } }
// test_i386_invalid_mem_read public static void TestInvalidMemoryRead() { var addr = 0x1000000UL; var code = new byte[] { 0x8B, 0x0D, 0xAA, 0xAA, 0xAA, 0xAA, // MOV ecx [0xaaaaaaaa] 0x41, // INC ecx 0x4A // DEC edx }; Console.WriteLine("==================================="); Console.WriteLine("Emulate i386 code that read from invalid memory."); using (var emulator = new X86Emulator(X86Mode.b32)) { // Map 2MB of memory. emulator.Memory.Map(addr, 2 * 1024 * 1024, MemoryPermissions.All); // Write machine code to be emulated. emulator.Memory.Write(addr, code, (uint)code.Length); // Initialize registers. emulator.Registers.ECX = 0x1234; emulator.Registers.EDX = 0x7890; // Trace all basic blocks. emulator.Hooks.Block.Add(BlockHook, null); // Trace all instructions. emulator.Hooks.Code.Add(CodeHook, null); try { // Start emulating the machine written machine code. emulator.Start(addr, addr + (ulong)code.Length); } catch (UnicornException ex) { Debug.Assert(ex.ErrorCode == UnicornError.ReadUnmapped, "Unexpected error code in caught UnicornException."); Console.WriteLine($"Failed to start emulator instance. -> {ex.Message}."); } Console.WriteLine(">>> Emulation done. Below is the CPU context"); Console.WriteLine($">>> ECX = 0x{emulator.Registers.ECX.ToString("x2")}"); Console.WriteLine($">>> EDX = 0x{emulator.Registers.EDX.ToString("x2")}"); } }
// test_i386_inout public static void TestInOut() { var addr = 0x1000000UL; var code = new byte[] { 0x41, // INC ecx 0xE4, 0x3F, // IN AL 0x3F 0x4A, // DEC edx 0xE6, 0x46, // OUT 0x46 AL 0x43 // INC ebx }; Console.WriteLine("==================================="); Console.WriteLine("Emulate i386 code with IN/OUT instructions."); using (var emulator = new X86Emulator(X86Mode.b32)) { // Map 2MB of memory. emulator.Memory.Map(addr, 2 * 1024 * 1024, MemoryPermissions.All); // Write machine code to be emulated. emulator.Memory.Write(addr, code, (uint)code.Length); // Initialize registers. emulator.Registers.ECX = 0x1234; emulator.Registers.EDX = 0x7890; // Trace all basic blocks. emulator.Hooks.Block.Add(BlockHook, null); // Trace all instructions. emulator.Hooks.Code.Add(CodeHook, null); // Hook X86 IN instructions. emulator.Hooks.Instruction.Add(HookIn, X86Instructions.IN, null); // Hook X86 OUT instructions. emulator.Hooks.Instruction.Add(HookOut, X86Instructions.OUT, null); // Start emulating the machine written machine code. emulator.Start(addr, addr + (ulong)code.Length); Console.WriteLine(">>> Emulation done. Below is the CPU context"); Console.WriteLine($">>> ECX = 0x{emulator.Registers.ECX.ToString("x2")}"); Console.WriteLine($">>> EDX = 0x{emulator.Registers.EDX.ToString("x2")}"); } }
private void emulatorToolStripMenuItem_Click(object sender, EventArgs e) { var sc = new ServiceContainer(); var fs = new FileStream(@"D:\dev\jkl\dec\halsten\decompiler_paq\upx\demo.exe", FileMode.Open); var size = fs.Length; var abImage = new byte[size]; fs.Read(abImage, 0, (int)size); var exe = new ExeImageLoader(sc, "foolexe", abImage); var peLdr = new PeImageLoader(sc, "foo.exe", abImage, exe.e_lfanew); var addr = peLdr.PreferredBaseAddress; var program = peLdr.Load(addr); var rr = peLdr.Relocate(program, addr); var win32 = new Win32Emulator(program.SegmentMap, program.Platform, program.ImportReferences); var emu = new X86Emulator((IntelArchitecture)program.Architecture, program.SegmentMap, win32); emu.InstructionPointer = rr.EntryPoints[0].Address; emu.ExceptionRaised += delegate { throw new Exception(); }; emu.WriteRegister(Registers.esp, (uint)peLdr.PreferredBaseAddress.ToLinear() + 0x0FFC); emu.Start(); }
// test_i386 public static void Test() { ulong addr = 0x1000000; ulong esp = addr + 0x200000; byte[] code = { 0xeb, 0x1c, 0x5a, 0x89, 0xd6, 0x8b, 0x02, 0x66, 0x3d, 0xca, 0x7d, 0x75, 0x06, 0x66, 0x05, 0x03, 0x03, 0x89, 0x02, 0xfe, 0xc2, 0x3d, 0x41, 0x41, 0x41, 0x41, 0x75, 0xe9, 0xff, 0xe6, 0xe8, 0xdf, 0xff, 0xff, 0xff, 0x31, 0xd2, 0x6a, 0x0b, 0x58, 0x99, 0x52, 0x68, 0x2f, 0x2f, 0x73, 0x68, 0x68, 0x2f, 0x62, 0x69, 0x6e, 0x89, 0xe3, 0x52, 0x53, 0x89, 0xe1, 0xca, 0x7d, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }; Console.WriteLine("Emulate i386 code"); using (var emulator = new X86Emulator(X86Mode.b32)) { emulator.Memory.Map(addr, 2 * 1024 * 1024, MemoryPermissions.All); emulator.Memory.Write(addr, code, code.Length); emulator.Registers.ESP = (long)esp; emulator.Hooks.Code.Add(HookCode, null); emulator.Hooks.Interrupt.Add(HookInterrupt, null); Console.WriteLine(); Console.WriteLine(">>> Start tracing this Linux code"); emulator.Start(addr, addr + (ulong)code.Length); Console.WriteLine(); Console.WriteLine(">>> Emulation done."); } }
public void X86Emu_Mov32() { Given_Win32Code(m => { m.Mov(m.eax, m.ebx); }); Given_RegValue(Registers.ebx, 4); emu.Start(); Assert.AreEqual(4, emu.Registers[Registers.eax.Number]); }