public unsafe void RunMachineCodeTest()
        {
            Assert.AreEqual(1,
                            X86Assembly.RunMachineCode(new byte[] { 0xb8, 0x01, 0x00, 0x00, 0x00, 0xc3 }));
            Assert.AreEqual(145764,
                            X86Assembly.RunMachineCode(new byte[] { 0xB8, 0x40, 0x01, 0x00, 0x00, 0x05, 0x24, 0x38, 0x02, 0x00, 0xc3 }));

            byte[] buffer = new byte[12];
            fixed(byte *newBuffer = &buffer[0])
            {
                try
                {
                    X86Assembly.RunMachineCode(new byte[]
                    {
                        0x53,                      // push   %ebx
                        0x31, 0xc0,                // xor    %eax,%eax
                        0x0f, 0xa2,                // cpuid
                        0x8b, 0x44, 0x24, 0x08,    // mov    0x8(%esp),%eax
                        0x89, 0x18,                // mov    %ebx,0x0(%eax)
                        0x89, 0x50, 0x04,          // mov    %edx,0x4(%eax)
                        0x89, 0x48, 0x08,          // mov    %ecx,0x8(%eax)
                        0x5b,                      // pop    %ebx
                        0xc3                       // ret
                    }, typeof(CPUID0Delegate), new IntPtr(newBuffer));

                    CollectionAssert.AreNotEqual(buffer, new byte[12]);
                }
                catch (Exception ex)
                {
                    Assert.Fail(ex.Message);
                }
            }
        }
 public void CompileToMachineCodeTest()
 {
     CollectionAssert.AreEqual(new byte[]
     {
         0x53,
         0x31, 0xc0,
         0x0f, 0xa2,
         0x8b, 0x44, 0x24, 0x08,
         0x89, 0x18,
         0x89, 0x50, 0x04,
         0x89, 0x48, 0x08,
         0x5b,
         0xc3
     },
                               X86Assembly.CompileToMachineCode(new object[] {
         ASM.push, REG.EBX,
         ASM.xor, REG.EAX, REG.EAX,
         new RawAssemblyCode("cpuid"),
         ASM.mov, REG.EAX, (REG.ESP + 8).Ptr,
         ASM.mov, (REG.EAX + 0).Ptr, REG.EBX,
         ASM.mov, (REG.EAX + 4).Ptr, REG.EDX,
         ASM.mov, (REG.EAX + 8).Ptr, REG.ECX,
         ASM.pop, REG.EBX,
         ASM.ret,
     }));
 }
 public void ConvertInlineAssemblyTest()
 {
     Assert.AreEqual("ret",
                     X86Assembly.FromInline(ASM.ret, new object[] { }));
     Assert.AreEqual("mov eax, 10",
                     X86Assembly.FromInline(ASM.mov, new object[] { REG.EAX, 10 }));
     Assert.AreEqual("mov byte ptr [eax], 10",
                     X86Assembly.FromInline(ASM.mov, new object[] { REG.EAX.Ptr.Byte, 10 }));
     Assert.AreEqual("mov word ptr [eax], 10",
                     X86Assembly.FromInline(ASM.mov, new object[] { REG.EAX.Ptr.Word, 10 }));
     Assert.AreEqual("mov dword ptr [eax], 10",
                     X86Assembly.FromInline(ASM.mov, new object[] { REG.EAX.Ptr, 10 }));
     Assert.AreEqual("mov dword ptr [eax], 10",
                     X86Assembly.FromInline(ASM.mov, new object[] { REG.EAX.Ptr.DWord, 10 }));
     Assert.AreEqual("mov qword ptr [eax], 10",
                     X86Assembly.FromInline(ASM.mov, new object[] { REG.EAX.Ptr.QWord, 10 }));
     Assert.AreEqual("mov dword ptr [eax+4], 10",
                     X86Assembly.FromInline(ASM.mov, new object[] { (REG.EAX + 4).Ptr, 10 }));
     Assert.AreEqual("mov dword ptr [eax+ebx], 10",
                     X86Assembly.FromInline(ASM.mov, new object[] { (REG.EAX + REG.EBX).Ptr, 10 }));
     Assert.AreEqual("mov dword ptr [eax+ebx*8+128], eax",
                     X86Assembly.FromInline(ASM.mov, new object[] { (REG.EAX + REG.EBX * 8 + 128).Ptr.DWord, REG.EAX }));
     Assert.AreEqual("mov dword ptr [ebx*8+128], eax",
                     X86Assembly.FromInline(ASM.mov, new object[] { (REG.EBX * 8 + 128).Ptr.DWord, REG.EAX }));
     Assert.AreEqual("mov dword ptr [ebx*2], eax",
                     X86Assembly.FromInline(ASM.mov, new object[] { (REG.EBX * 2).Ptr.DWord, REG.EAX }));
     Assert.AreEqual("mov eax, dword ptr [ebx+4]",
                     X86Assembly.FromInline(ASM.mov, new object[] { REG.EAX, (REG.EBX + 4).Ptr }));
 }
Exemple #4
0
        public static IVirtualMachine Compile(string asmSource)
        {
            AsmToken[][] asmTokens = AssemblyLexer.LexAsmCode(asmSource);
            X86Assembly  assembly  = X86Assembler.GenerateAssembly(asmTokens);
            string       source    = CSharpGenerator.GenerateSource(assembly);

            return(CSharpCompiler.CompileCSharp(source));
        }
        public void GetCodeTest()
        {
            Assert.AreEqual(
                $"mov eax, 100\nret\n",
                X86Assembly.GetCode(
                    ASM.mov, REG.EAX, 100,
                    ASM.ret));

            Assert.AreEqual(
                "mov eax, 100\nadd eax, 200\nret\n",
                X86Assembly.GetCode(
                    ASM.mov, REG.EAX, 100,
                    ASM.add, REG.EAX, 200,
                    ASM.ret));

            Assert.AreEqual(
                "push 42\npop eax\nret\n",
                X86Assembly.GetCode(
                    ASM.push, 42,
                    ASM.pop, REG.EAX,
                    ASM.ret));

            Assert.AreEqual(
                "mov eax, 0\nmov ecx, 100\nmyloop:\nadd eax, ecx\nloop myloop\nret\n",
                X86Assembly.GetCode(
                    ASM.mov, REG.EAX, 0,
                    ASM.mov, REG.ECX, 100,
                    new Label("myloop"),
                    ASM.add, REG.EAX, REG.ECX,
                    ASM.loop, "myloop",
                    ASM.ret));


            Assert.AreEqual(
                @"push ebx
mov eax, 0
cpuid
mov eax, dword ptr [esp+8]
mov dword ptr [eax+0], ebx
mov dword ptr [eax+4], edx
mov dword ptr [eax+8], ecx
pop ebx
ret
".Replace("\r\n", "\n"),
                X86Assembly.GetCode(new object[]
            {
                ASM.push, REG.EBX,
                ASM.mov, REG.EAX, 0,
                new RawAssemblyCode("cpuid"),
                ASM.mov, REG.EAX, (REG.ESP + 8).Ptr,
                ASM.mov, (REG.EAX + 0).Ptr, REG.EBX,
                ASM.mov, (REG.EAX + 4).Ptr, REG.EDX,
                ASM.mov, (REG.EAX + 8).Ptr, REG.ECX,
                ASM.pop, REG.EBX,
                ASM.ret,
            }));
        }
        public void ConvertInlineAssemblyRawCodeTest()
        {
            string code = "Nobody care this project";

            Assert.AreEqual(code, X86Assembly.FromInline(new object[]
            {
                new RawAssemblyCode(code)
            }));
        }
Exemple #7
0
        public static string GenerateSource(X86Assembly assembly)
        {
            var generator = new CSharpGenerator(assembly);

            return(generator.GenerateProgramSource().Source);
        }
Exemple #8
0
 public CSharpGenerator(X86Assembly assembly)
 {
     _assembly = assembly;
 }
 public CSharpTranslator(X86Assembly assembly, bool yieldAddress) : this(assembly)
 {
     _yieldAddress = yieldAddress;
 }
 public CSharpTranslator(X86Assembly assembly)
 {
     _assembly = assembly;
 }
Exemple #11
0
        public static void Generate(ProgramSource ps, X86Assembly assembly, X86Instruction x86Instruction)
        {
            var translator        = new CSharpTranslator(assembly);
            var addressTranslator = new CSharpTranslator(assembly, true);

            switch (x86Instruction.Name)
            {
            case "add":
                if (x86Instruction.OperandCount != 2)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Memory &&
                    x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Src.Type == OperandTypes.Label)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " += " +
                               x86Instruction.Src.GetCode(translator));
                break;

            case "and":
                if (x86Instruction.OperandCount != 2)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Memory &&
                    x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Src.Type == OperandTypes.Label)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " &= " +
                               x86Instruction.Src.GetCode(translator));
                break;

            case "call":
                if (x86Instruction.OperandCount != 1)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Label)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                string function = x86Instruction.Dst.GetCode(translator);
                if (!X86Assembler.IsFunction(function))
                {
                    throw new UnknownFunctionException(x86Instruction);
                }
                ps.AddCodeLine("vm." + x86Instruction.Dst.GetCode(translator) + "()");
                break;

            case "cmp":
                if (x86Instruction.OperandCount != 2)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Src.Type == OperandTypes.Label)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type == OperandTypes.Label)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                GenerateCmp(ps, x86Instruction.Dst.GetCode(translator), x86Instruction.Src.GetCode(translator));
                break;

            case "jmp":
            case "je":
            case "jne":
            case "jg":
            case "jge":
            case "jl":
            case "jle":
            case "jz":
            case "jnz":
            case "loop":
                JumpInstruction(ps, assembly, x86Instruction);
                break;

            case "lea":
                if (x86Instruction.OperandCount != 2)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Src.Type == OperandTypes.Label)
                {
                    ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " = " +
                                   x86Instruction.Src.GetCode(translator));
                    break;
                }
                if (x86Instruction.Src.Type == OperandTypes.Memory)
                {
                    ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " = " +
                                   x86Instruction.Src.GetCode(addressTranslator));
                    break;
                }
                throw new WrongParameterException(x86Instruction);

            case "mov":
                if (x86Instruction.OperandCount != 2)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Memory &&
                    x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Src.Type == OperandTypes.Label &&
                    !assembly.ConstantExists(((LabelArgument)x86Instruction.Src).Label))
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " = " +
                               x86Instruction.Src.GetCode(translator));
                break;

            case "mul":
                if (x86Instruction.OperandCount != 2)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Memory &&
                    x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Src.Type == OperandTypes.Label)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " *= " +
                               x86Instruction.Src.GetCode(translator));
                break;

            case "or":
                if (x86Instruction.OperandCount != 2)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Memory &&
                    x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Src.Type == OperandTypes.Label)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " |= " +
                               x86Instruction.Src.GetCode(translator));
                break;

            case "push":
                if (x86Instruction.OperandCount != 1)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine("vm.Push(" + x86Instruction.Dst.GetCode(translator) + ")");
                break;

            case "pop":
                if (x86Instruction.OperandCount != 1)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " = vm.Pop()");
                break;

            case "ret":
                if (x86Instruction.OperandCount != 0)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine("return;");
                break;

            case "shl":
                if (x86Instruction.OperandCount != 2)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Memory &&
                    x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Src.Type == OperandTypes.Label)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " <<= " +
                               x86Instruction.Src.GetCode(translator));
                break;

            case "shr":
                if (x86Instruction.OperandCount != 2)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Memory &&
                    x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Src.Type == OperandTypes.Label)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " >>= " +
                               x86Instruction.Src.GetCode(translator));
                break;

            case "sub":
                if (x86Instruction.OperandCount != 2)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Memory &&
                    x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Src.Type == OperandTypes.Label)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " -= " +
                               x86Instruction.Src.GetCode(translator));
                break;

            case "xor":
                if (x86Instruction.OperandCount != 2)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Dst.Type != OperandTypes.Memory &&
                    x86Instruction.Dst.Type != OperandTypes.Register)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                if (x86Instruction.Src.Type == OperandTypes.Label)
                {
                    throw new WrongParameterException(x86Instruction);
                }
                ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " ^= " +
                               x86Instruction.Src.GetCode(translator));
                break;
            }
        }
Exemple #12
0
        public static void JumpInstruction(ProgramSource ps, X86Assembly assembly, X86Instruction x86Instruction)
        {
            if (x86Instruction.OperandCount != 1)
            {
                throw new WrongParameterException(x86Instruction);
            }
            if (x86Instruction.Dst.Type != OperandTypes.Label || x86Instruction.Dst as LabelArgument == null)
            {
                throw new WrongParameterException(x86Instruction);
            }
            var    dst             = x86Instruction.Dst as LabelArgument;
            string instructionName = x86Instruction.Name;
            string realLabel       = dst.Label;

            if (!assembly.LabelExists(realLabel))
            {
                throw new LabelMissingException(x86Instruction.Line, realLabel);
            }
            string label = assembly.InternalNameOf(realLabel);

            switch (instructionName)
            {
            case "jmp":
                ps.AddCodeLine("goto ", label);
                return;

            case "je":
                ps.AddJump("ZF == 1", label);
                return;

            case "jne":
                ps.AddJump("ZF == 0", label);
                return;

            case "jg":
                ps.AddJump("ZF == 0 && SF == OF", label);
                return;

            case "jge":
                ps.AddJump("SF == OF", label);
                return;

            case "jl":
                ps.AddJump("SF != OF", label);
                return;

            case "jle":
                ps.AddJump("ZF == 1 || SF != OF", label);
                return;

            case "jz":
                ps.AddJump("ZF == 1", label);
                return;

            case "jnz":
                ps.AddJump("ZF == 0", label);
                return;

            case "loop":
                ps.AddCodeLine("vm.Ecx.Value--");
                ps.AddJump("vm.Ecx.Value != 0", label);
                return;
            }
            Debug.Assert(false, "Unknown jump instruction");
        }
        public void ExecuteScriptTest()
        {
            Assert.AreEqual(100,
                            X86Assembly.ExecuteScript(
                                ASM.mov, REG.EAX, 100,
                                ASM.ret));

            Assert.AreEqual(300,
                            X86Assembly.ExecuteScript(
                                ASM.mov, REG.EAX, 100,
                                ASM.add, REG.EAX, 200,
                                ASM.ret));

            Assert.AreEqual(42,
                            X86Assembly.ExecuteScript(
                                ASM.push, 42,
                                ASM.pop, REG.EAX,
                                ASM.ret));

            int i = 100;

            Assert.AreEqual(5050,
                            X86Assembly.ExecuteScript(
                                ASM.mov, REG.EAX, 0,
                                ASM.mov, REG.ECX, i,
                                new Label("myloop"),
                                ASM.add, REG.EAX, REG.ECX,
                                ASM.loop, "myloop",
                                ASM.ret));

            unsafe
            {
                int a = 84;
                Assert.AreEqual(84,
                                X86Assembly.ExecuteScript(
                                    ASM.mov, REG.EAX, (int)&a,
                                    ASM.sub, REG.EAX, 4,
                                    ASM.mov, REG.EAX, (REG.EAX + 4).Ptr,
                                    ASM.ret));

                byte[] buffer = new byte[12];
                fixed(byte *newBuffer = &buffer[0])
                {
                    try
                    {
                        X86Assembly.ExecuteScript(new object[]
                        {
                            ASM.push, REG.EBX,
                            ASM.xor, REG.EAX, REG.EAX,
                            new RawAssemblyCode("cpuid"),
                            ASM.mov, REG.EAX, (REG.ESP + 8).Ptr,
                            ASM.mov, (REG.EAX + 0).Ptr, REG.EBX,
                            ASM.mov, (REG.EAX + 4).Ptr, REG.EDX,
                            ASM.mov, (REG.EAX + 8).Ptr, REG.ECX,
                            ASM.pop, REG.EBX,
                            ASM.ret,
                        }, typeof(CPUID0Delegate), new IntPtr(newBuffer));

                        CollectionAssert.AreNotEqual(buffer, new byte[12]);
                    }
                    catch
                    {
                        Assert.Fail();
                    }
                }
            }
        }