Example #1
0
        static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Usage();
                Environment.Exit(1);
            }
            if (!args[0].EndsWith(".asm"))
            {
                Usage();
                Environment.Exit(1);
            }

            try
            {
                string inputFile  = args[0];
                string outputFile = System.IO.Path.ChangeExtension(inputFile, ".hack");

                var inStream  = new FileStream(inputFile, FileMode.Open);
                var outStream = new FileStream(outputFile, FileMode.Create);

                Assembler.Assemble(inStream, outStream);
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
Example #2
0
        private static void MethodResolver(MethodContext context)
        {
            if (context.Method.Name == "SimpleSum")
            {
                Assembler assembler = new Assembler(64);

                //Replace with fatorial number:
                //int sum = num1+num2;
                //int fatorial = 1;
                //for(int i = 2; i <= sum; i++){
                //    fatorial *= i;
                //}
                //return fatorial;
                assembler.add(edx, ecx);
                assembler.mov(eax, 1);
                assembler.mov(ecx, 2);
                assembler.cmp(edx, 0x02);
                assembler.jl(assembler.@F);
                assembler.AnonymousLabel();
                assembler.imul(eax, ecx);
                assembler.inc(ecx);
                assembler.cmp(ecx, edx);
                assembler.jle(assembler.@B);
                assembler.AnonymousLabel();
                assembler.ret();

                using MemoryStream ms = new MemoryStream();
                assembler.Assemble(new StreamCodeWriter(ms), 0);

                byte[] asm = ms.ToArray();

                context.ResolveNative(asm);
            }
        }
Example #3
0
        void Test_zero_bytes()
        {
            var a = new Assembler(64);

            var lblf = a.CreateLabel();
            var lbll = a.CreateLabel();
            var lbl1 = a.CreateLabel();
            var lbl2 = a.CreateLabel();

            a.Label(ref lblf);
            a.zero_bytes();

            a.je(lbl1);
            a.je(lbl2);
            a.Label(ref lbl1);
            a.zero_bytes();
            a.Label(ref lbl2);
            a.nop();
            [email protected]_bytes();

            a.Label(ref lbll);
            a.zero_bytes();

            var writer = new CodeWriterImpl();

            a.Assemble(writer, 0);
            var bytes = writer.ToArray();

            Assert.Equal(new byte[] { 0x74, 0x02, 0x74, 0x00, 0x90 }, bytes);
        }
Example #4
0
        private static int Main(string[] args)
        {
            try
            {
                if (args.Length != 1)
                    throw new Ufer(AppDomain.CurrentDomain.FriendlyName + " <xxx.asm>");

                var fpatIn = args[0];
                if (!fpatIn.EndsWith(".asm", StringComparison.InvariantCultureIgnoreCase))
                    throw new Ufer("Not an asm file");

                var src = File.ReadAllText(fpatIn);

                var fpatOut = fpatIn.Substring(0, fpatIn.Length - 4) + ".hack";

                var assembler = new Assembler();

                File.WriteAllLines(fpatOut, assembler.Assemble(src));

                return 0;
            }
            catch (Exception er)
            {
                Console.WriteLine(er.UstMessage());
                return 1;
            }
        }
Example #5
0
        static void Main(string[] args)
        {
            Console.Title = "Test";

            Instruction[] Unused;
            byte[]        ProgMem = Assembler.Assemble(File.ReadAllText("Test.e64"), out Unused);
            Dump(ProgMem);

            //Console.WriteLine("Unused:");
            //Console.WriteLine(string.Join(", ", Unused));

            CPU Elisa = new CPU(ProgMem);

            Elisa.Ports.Add(0, (Data, IsRead) => {
                Console.Write((char)Data);
                return(0);
            });

            try {
                while (!Elisa.Halted)
                {
                    Elisa.Step();
                }
            } catch (Exception E) {
                Console.WriteLine(E.Message);
                throw;
            }
            Console.ReadLine();
        }
Example #6
0
        protected override void InitList()
        {
            if (!Directory.Exists(ProgramDirectory.PATH))
            {
                return;
            }

            // Assemble all program files
            string[] filePaths = Directory.GetFiles(ProgramDirectory.PATH, "*.txt");
            foreach (string filePath in filePaths)
            {
                string  programText = File.ReadAllText(filePath);
                Program program     = Assembler.Assemble(Path.GetFileNameWithoutExtension(filePath), programText);
                if (program != null)
                {
                    // Setup autosave
                    program.OnChange += () => SaveProgram(program);

                    items.Add(program);
                }
                else
                {
                    Debug.LogWarning("Assembly of file " + filePath + " failed");
                }
            }
        }
Example #7
0
        private void button1_Click(object sender, EventArgs e)
        {
            String text        = richTextBox1.Text;
            var    lexerOutput = Lexer.lex(text.Split('\n'));

            if (lexerOutput.Item2.Count > 0)
            {
                string errors = "";
                foreach (var error in lexerOutput.Item2)
                {
                    errors += error + '\n';
                }
                MessageBox.Show(errors, "Error while lexing", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var assmblerOutput = Assembler.Assemble(lexerOutput.Item1);

            if (assmblerOutput.Item2.Count > 0)
            {
                string errors = "";
                foreach (var error in assmblerOutput.Item2)
                {
                    errors += error + '\n';
                }
                MessageBox.Show(errors, "Error while assmbling", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            Form2 emulatorView = new Form2(assmblerOutput.Item1);

            emulatorView.Show();
        }
Example #8
0
        static void TestAssemble()
        {
            try
            {
                Assembler a = new Assembler();

                String lmsFilename = Path.Combine(TEST_OUTPUT, Path.GetFileNameWithoutExtension(SOURCE_FILENAME)) + ".lms";
                String rmfFilename = Path.Combine(TEST_OUTPUT, Path.GetFileNameWithoutExtension(SOURCE_FILENAME)) + ".rmf";

                FileStream fs  = new FileStream(lmsFilename, FileMode.Open, FileAccess.Read);
                FileStream ofs = new FileStream(rmfFilename, FileMode.Create, FileAccess.Write);

                List <String> errors = new List <String>();

                a.Assemble(fs, ofs, errors);

                fs.Close();
                ofs.Close();

                if (errors.Count > 0)
                {
                    foreach (String s in errors)
                    {
                        Console.WriteLine(s);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Assemble error: " + e.Message);
                Console.WriteLine(e.StackTrace);
                Console.ReadKey();
            }
        }
Example #9
0
        public void Test_For_Set_Reg_Label()
        {
            Assembler testAssembler = new Assembler();

            var code = new List <string> {
                "SET X,data", ":data", "DAT \"Hello, World!\",0"
            };

            testAssembler.Assemble(code);


            List <ushort> dump = new List <ushort>()
            {
                0x7c61,
                0x0002,
                0x0048,
                0x0065,
                0x006c,
                0x006c,
                0x006f,
                0x002c,
                0x0020,
                0x0057,
                0x006f,
                0x0072,
                0x006c,
                0x0064,
                0x0021,
                0x0000
            };

            CollectionAssert.AreEqual(dump, testAssembler.Dump);
        }
Example #10
0
        private void PreformRoomAsmPatch()
        {
            var labels    = new AddressLabels();
            var Asm       = EnhancerResources.RoomDataHack;
            var assembler = new Assembler("RoomDataHack", Asm, StandardFileSystem.FileSystem)
            {
                Labels = labels
            };

            var bin    = assembler.Assemble();
            var errors = assembler.GetErrors();

            if (errors.Count > 0)
            {
                throw new EnhancerException("Room data hack ASM patch failed to assemble with " + errors.Count.ToString() + " errors. First error: " + errors[0].Message + " on line " + errors[0].LineNumber.ToString());
            }

            var patches = assembler.GetPatchSegments();

            for (int i = 0; i < patches.Count; i++)
            {
                var patch = patches[i];

                Array.Copy(bin, patch.Start, enhancedRomData, patch.PatchOffset, patch.Length);
            }
        }
        public void ChangePersonalInfoData(IChangePersonalInfoData data)
        {
            ApplicationUser user = repository.UserManager.FindByEmail(data.Email);

            if (data.NewFirstName.IsChanged)
            {
                user.FirstName = data.NewFirstName.NewValue;
            }
            if (data.NewSurname.IsChanged)
            {
                user.Surname = data.NewSurname.NewValue;
            }
            if (data.NewCity.IsChanged)
            {
                user.City = data.NewCity.NewValue;
            }
            if (data.NewPostDepartment.IsChanged)
            {
                user.PostDepartment = data.NewPostDepartment.NewValue;
            }
            if (data.NewPhone.IsChanged)
            {
                user.PhoneNumber = data.NewPhone.NewValue;
            }
            if (data.NewLanguage.IsChanged)
            {
                user.Language = data.NewLanguage.NewValue == null ?
                                default(DAL.Entities.LanguageType?) : Assembler.Assemble(data.NewLanguage.NewValue.Value);
            }


            repository.UserRepository.Update(user);
            repository.Save();
        }
Example #12
0
        private InlineHook(QHackContext ctx, AssemblyCode code, HookParameters parameters)
        {
            Context          = ctx;
            Code             = code.Copy();
            MemoryAllocation = new MemoryAllocation(ctx);
            Parameters       = parameters;

            byte[] headInstBytes = GetHeadBytes(Context.DataAccess.ReadBytes(Parameters.TargetAddress, 32));

            nuint allocAddr        = MemoryAllocation.AllocationBase;
            nuint safeFreeFlagAddr = allocAddr + (uint)HookInfo.Offset_SafeFreeFlag;
            nuint onceFlagAddr     = allocAddr + (uint)HookInfo.Offset_OnceFlag;
            nuint codeAddr         = allocAddr + (uint)HookInfo.HeaderSize;
            nuint retAddr          = Parameters.TargetAddress + (uint)headInstBytes.Length;

            HookInfo info = new(allocAddr, headInstBytes);

            Assembler assembler = new();

            assembler.Emit(DataHelper.GetBytes(info));                                         //emit the header before runnable code
            assembler.Emit((Instruction)$"mov dword ptr [{safeFreeFlagAddr}],1");
            assembler.Emit(Parameters.IsOnce ? GetOnceCheckedCode(Code, onceFlagAddr) : Code); //once or not
            if (Parameters.Original)
            {
                assembler.Emit(headInstBytes);                //emit the raw code replaced by hook jmp
            }
            assembler.Emit((Instruction)$"mov dword ptr [{safeFreeFlagAddr}],0");
            assembler.Emit((Instruction)$"jmp {retAddr}");

            Context.DataAccess.WriteBytes(allocAddr, assembler.GetByteCode(allocAddr));

            JmpHeadBytes = new byte[headInstBytes.Length];
            Array.Fill <byte>(JmpHeadBytes, 0x90);
            Assembler.Assemble($"jmp {codeAddr}", Parameters.TargetAddress).CopyTo(JmpHeadBytes, 0);
        }
Example #13
0
        static void TestAssemble()
        {
            Assembler a = new Assembler();

            String     f  = "C:/temp/compiledbasic.lms";
            FileStream fs = new FileStream(f, FileMode.Open, FileAccess.Read);

            FileStream ofs = new FileStream("c:/temp/compiledbasic.rbf", FileMode.Create, FileAccess.Write);

            List <String> errors = new List <String>();

            a.Assemble(fs, ofs, errors);

            fs.Close();
            ofs.Close();

            if (errors.Count > 0)
            {
                foreach (String s in errors)
                {
                    Console.WriteLine(s);
                }
                Console.ReadKey();
            }
        }
Example #14
0
        void Assemble_throws_if_error()
        {
            var c = new Assembler(64);

            c.aaa();
            Assert.Throws <InvalidOperationException>(() => c.Assemble(new CodeWriterImpl(), 0));
        }
Example #15
0
        private static int Main(string[] args)
        {
            try
            {
                if (args.Length != 1)
                {
                    throw new Ufer(AppDomain.CurrentDomain.FriendlyName + " <xxx.asm>");
                }


                var fpatIn = args[0];
                if (!fpatIn.EndsWith(".asm", StringComparison.InvariantCultureIgnoreCase))
                {
                    throw new Ufer("Not an asm file");
                }

                var src = File.ReadAllText(fpatIn);

                var fpatOut = fpatIn.Substring(0, fpatIn.Length - 4) + ".hack";

                var assembler = new Assembler();

                File.WriteAllLines(fpatOut, assembler.Assemble(src));

                return(0);
            }
            catch (Exception er)
            {
                Console.WriteLine(er.UstMessage());
                return(1);
            }
        }
Example #16
0
        void Awake()
        {
            // Assemble all program files
            string[] filePaths = Directory.GetFiles(ProgramDirectory.value, "*.txt");
            foreach (string filePath in filePaths)
            {
                string  programText = File.ReadAllText(filePath);
                Program program     = Assembler.Assemble(programText);
                if (program != null)
                {
                    program.name = Path.GetFileNameWithoutExtension(filePath);
                    Debug.Log("Assembly of program " + program.name + " succeeded");

                    // Setup autosave
                    program.OnChange += () => SaveProgram(program);

                    programs.Add(program);
                }
                else
                {
                    Debug.LogWarning("Assembly of file " + filePath + " failed");
                }
            }

            // Populate list
            foreach (Program program in programs)
            {
                CreateListEntry(program);
            }
        }
Example #17
0
        private void DisassemblyEditor_LostFocus(object sender, RoutedEventArgs e)
        {
            UndertaleCode code = this.DataContext as UndertaleCode;

            if (code == null)
            {
                return; // Probably loaded another data.win or something.
            }
            UndertaleData data = (Application.Current.MainWindow as MainWindow).Data;

            try
            {
                var instructions = Assembler.Assemble(DisassemblyEditor.Text, data);
                code.Replace(instructions);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Assembler error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            CurrentDisassembled = null;
            CurrentDecompiled   = null;
            CurrentGraphed      = null;
            DisassembleCode(code);

            DisassemblyView.Visibility   = Visibility.Visible;
            DisassemblyEditor.Visibility = Visibility.Collapsed;
        }
Example #18
0
        public void ScanningException_ThrowsException()
        {
            var source = "BORK";

            Assert.That(() => Assembler.Assemble(source), Throws.InstanceOf <AssemblingException>()
                        .With.Message.EqualTo("[1] Error at BORK: Expected LABEL or INSTRUCTION."));
        }
Example #19
0
        public void CommentsInSourceCode()
        {
            string[] sourceCode =
            {
                "; program to swap two memory locations",
                "",
                "LDA $0380 ; load memory address 896 into A",
                "LDX $0381 ; load memory address 897 into X",
                "",
                "STA $0381 ; store A into 897",
                "STX $0380 ; store X into 896",
                "",
                "RTS ; return from subroutine"
            };

            var(binary, _) = Assembler.Assemble(sourceCode, 0x033C);

            byte[] expectedBinary =
            {
                0x3C, 0x03,       // staring memory location (828)
                0xAD, 0x80, 0x03, // LDA $0380 ; (896)
                0xAE, 0x81, 0x03, // LDX $0381 ; (897)
                0x8D, 0x81, 0x03, // STA $0381
                0x8E, 0x80, 0x03, // STX $0380
                0x60              // RTS
            };

            Assert.AreEqual(expectedBinary, binary);
        }
Example #20
0
        public void AssembleTest()
        {
            Assembler target = new Assembler();             // TODO: Initialize to an appropriate value

            target.Assemble();
            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }
Example #21
0
        public void AssembleException()
        {
            var asm = new Assembler();

            string[] mnemonics = new[]
            {
                "use32",
                "jmp [0x123456]" // Missing operand size.
            };

            try
            {
                asm.Assemble(mnemonics);
            }
            catch (FasmException ex)
            {
                // Confirm exception details.
                Assert.Equal(FasmResult.Error, ex.Result);
                Assert.Equal(mnemonics, ex.Mnemonics);
                Assert.Equal(2, ex.Line);
                Assert.Equal(FasmErrors.OperandSizeNotSpecified, ex.ErrorCode);
            }

            asm.Dispose();
        }
        public IPersonalInfo GetPersonalInfo(string email)
        {
            ApplicationUser user         = repository.UserManager.FindByEmail(email);
            LanguageType?   userLanguage = user.Language != null?Assembler.Assemble(user.Language.Value) : default(LanguageType?);

            return(new PersonalInfo(user.FirstName, user.Surname, user.City, user.PostDepartment, user.PhoneNumber, userLanguage));
        }
Example #23
0
        /// <summary>
        /// Takes either an array or list of strings containing assembly instructions, a MachineType of I386 or x64,
        /// an instance of the ERC_Core object and returns the associated opcodes.
        /// </summary>
        /// <param name="instructions">The instructions to be assemble=d</param>
        /// <param name="machineType">a ERC.MachineType of either I386 or x64</param>
        /// <returns>Returns an ERC_Result byte array containing the assembled instructions</returns>
        public static ErcResult <byte[]> AssembleOpcodes(List <string> instructions, MachineType machineType)
        {
            ErcResult <byte[]> result    = new ErcResult <byte[]>(new ErcCore());
            List <string>      mnemonics = new List <string>();

            if (machineType == MachineType.I386)
            {
                mnemonics.Add("use32");
            }
            else if (machineType == MachineType.x64)
            {
                mnemonics.Add("use64");
            }

            for (int i = 0; i < instructions.Count; i++)
            {
                mnemonics.Add(instructions[i]);
            }

            var asm = new Assembler();

            try
            {
                result.ReturnValue = asm.Assemble(mnemonics);
                asm.Dispose();
            }
            catch (Exception e)
            {
                result.Error = e;
                result.LogEvent();
                asm.Dispose();
                return(result);
            }
            return(result);
        }
Example #24
0
        public void CompileInMemory()
        {
            Assembler assembler = new Assembler();
            var savableDocument = this.DockPanel.ActiveDocument as SourceDocument;
            var contents = savableDocument.ContentEditor.Text;
            var output = assembler.Assemble(contents);
            ushort currentAddress = 0;
            List<ushort> data = new List<ushort>();
            foreach (var entry in output)
            {
                loMapping.Add(new LineOffsetMapping
                {
                    LineNumber = entry.LineNumber,
                    Address = entry.Address
                });

                if (mapping.ContainsKey(entry.Address))
                {
                    mapping.Remove(entry.Address);
                }

                mapping.Add(entry.Address, entry.LineNumber);

                if (entry.Output != null)
                {
                    foreach (ushort value in entry.Output)
                    {
                        currentAddress++;
                        data.Add(value);
                    }
                }
            }

            var arr = data.ToArray();
        }
Example #25
0
        public void CodeWithAddressLabels()
        {
            string[] sourceCode =
            {
                "; print 'Y' if memeory address content is non-zero, otherwise 'N'",
                "       LDA $0380  ; load memory address into A",
                "       BEQ *LABEL ; check if it was 0",
                "       LDA #$59   ; load 'Y' into A",
                "       JMP END    ; got to end",
                "LABEL: LDA #$4E   ; load 'N' into A",
                "END:   JSR $FFD2  ; write the character to the screen",
                "       RTS"
            };

            var(binary, _) = Assembler.Assemble(sourceCode, 0x033C);

            byte[] expectedBinary =
            {
                0x3C, 0x03,
                0xAD, 0x80, 0x03, // 033C
                0xF0, 0x05,       // 033F
                0xA9, 0x59,       // 0341
                0x4C, 0x48, 0x03, // 0343
                0xA9, 0x4E,       // 0346 (LABEL)
                0x20, 0xD2, 0xFF, // 0348 (END)
                0x60              // 034B
            };

            Assert.AreEqual(expectedBinary, binary);
        }
Example #26
0
        public void SimpleTest()
        {
            string[] sourceCode =
            {
                "LDA $0380",
                "LDX $0381",
                "STA $0381",
                "STX $0380",
                "RTS"
            };

            var(binary, _) = Assembler.Assemble(sourceCode, 0x033C);

            byte[] expectedBinary =
            {
                0x3C, 0x03,       // staring memory location (828)
                0xAD, 0x80, 0x03, // LDA $0380 ; (896)
                0xAE, 0x81, 0x03, // LDX $0381 ; (897)
                0x8D, 0x81, 0x03, // STA $0381
                0x8E, 0x80, 0x03, // STX $0380
                0x60              // RTS
            };

            Assert.AreEqual(expectedBinary, binary);
        }
Example #27
0
        void Assemble_throws_if_null_writer()
        {
            var c = new Assembler(Bitness);

            c.nop();
            Assert.Throws <ArgumentNullException>(() => c.Assemble(null, 0));
        }
Example #28
0
        public void ParsingException_ThrowsException()
        {
            var source = "INC BORK";

            Assert.That(() => Assembler.Assemble(source), Throws.InstanceOf <AssemblingException>()
                        .With.Message.EqualTo("[1] Error at BORK: Expected register."));
        }
Example #29
0
        /// <summary>
        /// Your own user code starts here.
        /// If this is your first time, do consider reading the notice above.
        /// It contains some very useful information.
        /// </summary>
        public static void Init()
        {
            /*
             *  Reloaded Mod Loader Sample: Reloaded-Assembler
             *  Architectures supported: X86, X64
             *
             *  Demonstrates the simple usage of ReloadedAssembler,
             *  a background service wrapped around FASM.NET.
             *
             *  ReloadedAssembler provides you a means to effortlessly
             *  generate and compile X86 and X64 assembly in a
             *  real-time, just-in-time fashion.
             */

            // Want to see this in with a debugger? Uncomment this line.
            // Debugger.Launch();

            // Print demo details.
            Bindings.PrintInfo("Reloaded-Assembler Demo: 64bit Assembly");
            Bindings.PrintText("X64 Test:");

            // Sample assembler.
            string[] x64asm = new[]
            {
                "use64",                // Specifies this is a X64 piece of ASM.
                "mov rbx, rax",
                "mov rax, 0x123456",
                "jmp qword [0x123456]"  // This is FASM, YOU MUST SPECIFY OPERAND SIZE EXPLICITLY (`qword` in this case)
            };

            Bindings.PrintInfo("Assembling\n" + ConvertStringArrayToString(x64asm));

            // Assemble and print result.
            byte[] resultx64 = Assembler.Assemble(x64asm);
            Bindings.PrintInfo("Result:" + ByteArrayToString(resultx64));

            // Sample assembler.
            Bindings.PrintText("X86 Test:");
            string[] x86asm = new[]
            {
                "use32",                // Specifies this is a X86 piece of ASM.
                "mov ebx, eax",
                "mov eax, 0x123456",
                "jmp dword [0x123456]"  // This is FASM, YOU MUST SPECIFY OPERAND SIZE EXPLICITLY (`dword` in this case)
            };

            Bindings.PrintInfo("Assembling\n" + ConvertStringArrayToString(x86asm));

            // Assemble and print result.
            byte[] resultx86 = Assembler.Assemble(x86asm);
            Bindings.PrintInfo("Result:" + ByteArrayToString(resultx86));

            // Credits
            Bindings.PrintText("Protip: When using Reloaded it is highly recommended to first test your assembler for compilation" +
                               " with standalone FASM assembler.");

            /*"Credits to Zenlulz for FASM.NET, Tomasz Grysztar for FASM and FASMlib.
             * Networked background service version is an implementation of my own"*/
        }
Example #30
0
        void Undeclared_forward_anon_label_throws()
        {
            var c = new Assembler(64);

            c.nop();
            c.je(c.@F);
            Assert.Throws <InvalidOperationException>(() => c.Assemble(new CodeWriterImpl(), 0));
        }
Example #31
0
        void Unused_anonymous_label_throws()
        {
            var c = new Assembler(64);

            c.nop();
            c.AnonymousLabel();
            Assert.Throws <InvalidOperationException>(() => c.Assemble(new CodeWriterImpl(), 0));
        }
Example #32
0
        private static void RunProgram(string assemblyCode)
        {
            Assembler assembler = new Assembler();

            Instruction[] instructions = assembler.Assemble(assemblyCode);

            Memory memory = new Memory();
            memory.LoadInstructions(instructions);

            Registers registers = new Registers();
            registers.ValueWrittenToOutputRegister += System.Console.Write;

            Machine machine = new Machine(memory, registers);
            machine.Run(25);

            System.Console.ReadLine();
        }
        /// <summary>
        /// Gets all the mods and patches them.
        /// </summary>
        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            _errorLevel = ErrorLevel.NoError;

            //Gets the list of mods
            ItemCollection modCollection = null;
            string lolLocation = null;

            //Get the data from the UI thread
            Dispatcher.Invoke(DispatcherPriority.Input, new ThreadStart(() =>
            {
                modCollection = ModsListBox.Items;
                lolLocation = LocationTextbox.Text;
            }));

            SetStatusLabelAsync("Gathering mods...");

            //Gets the list of mods that have been checked.
            List<LessMod> modsToPatch = new List<LessMod>();
            foreach (var x in modCollection)
            {
                CheckBox box = (CheckBox)x;
                bool isBoxChecked = false;
                Dispatcher.Invoke(DispatcherPriority.Input, new ThreadStart(() =>
                {
                    isBoxChecked = box.IsChecked ?? false;
                }));

                if (isBoxChecked)
                {
                    modsToPatch.Add(_lessMods[box]);
                }
            }

            //Create a new dictionary to hold the SWF definitions in. This stops opening and closing the same SWF file if it's going to be modified more than once.
            Dictionary<string, SwfFile> swfs = new Dictionary<string, SwfFile>();

            //Start the stopwatch to see how long it took to patch (aiming for ~5 sec or less on test machine)
            timer = Stopwatch.StartNew();

            //Go through each modification
            foreach (var lessMod in modsToPatch)
            {
                SetStatusLabelAsync("Patching mod: " + lessMod.Name);

                //Go through each patch within the mod
                foreach (var patch in lessMod.Patches)
                {
                    //If the swf hasn't been loaded, load it into the dictionary.
                    if (!swfs.ContainsKey(patch.Swf))
                    {
                        string fullPath = Path.Combine(lolLocation, patch.Swf);

                        //Backup the SWF
                        string CurrentLocation = "";
                        string[] FileLocation = patch.Swf.Split('/', '\\');
                        foreach (string s in FileLocation.Take(FileLocation.Length - 1))
                        {
                            CurrentLocation = Path.Combine(CurrentLocation, s);
                            if (!Directory.Exists(Path.Combine(lolLocation, "LESsBackup", BackupVersion, CurrentLocation)))
                            {
                                Directory.CreateDirectory(Path.Combine(lolLocation, "LESsBackup", BackupVersion, CurrentLocation));
                            }
                        }
                        if (!File.Exists(Path.Combine(lolLocation, "LESsBackup", BackupVersion, patch.Swf)))
                        {
                            File.Copy(Path.Combine(lolLocation, patch.Swf), Path.Combine(lolLocation, "LESsBackup", BackupVersion, patch.Swf));
                        }

                        swfs.Add(patch.Swf, SwfFile.ReadFile(fullPath));
                    }

                    //Get the SWF file that is being modified
                    SwfFile swf = swfs[patch.Swf];

                    //Get the ABC tags (containing the code) from the swf file.
                    List<DoAbcTag> tags = swf.GetDoAbcTags();
                    bool classFound = false;
                    foreach (var tag in tags)
                    {
                        //check if this tag contains our script
                        ScriptInfo si = tag.GetScriptByClassName(patch.Class);

                        //check next tag if it doesn't
                        if (si == null)
                            continue;

                        ClassInfo cls = si.GetClassByClassName(patch.Class);
                        classFound = true;

                        Assembler asm;
                        //Perform the action based on what the patch defines
                        switch (patch.Action)
                        {
                            case "replace_trait": //replace trait (method)
                                //Load the code from the patch and assemble it to be inserted into the code
                                asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code)));
                                TraitInfo newTrait = asm.Assemble() as TraitInfo;

                                int traitIndex = cls.Instance.GetTraitIndexByTypeAndName(newTrait.Type, newTrait.Name.Name);
                                bool classTrait = false;
                                if (traitIndex < 0)
                                {
                                    traitIndex = cls.GetTraitIndexByTypeAndName(newTrait.Type, newTrait.Name.Name);
                                    classTrait = true;
                                }
                                if (traitIndex < 0)
                                {
                                    throw new TraitNotFoundException(String.Format("Can't find trait \"{0}\" in class \"{1}\"", newTrait.Name.Name, patch.Class));
                                }

                                //Modified the found trait
                                if (classTrait)
                                {
                                    cls.Traits[traitIndex] = newTrait;
                                }
                                else
                                {
                                    cls.Instance.Traits[traitIndex] = newTrait;
                                }
                                break;
                            case "replace_cinit"://replace class constructor
                                //Load the code from the patch and assemble it to be inserted into the code
                                asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code)));
                                cls.ClassInit = asm.Assemble() as MethodInfo;
                                break;
                            case "replace_iinit"://replace instance constructor
                                //Load the code from the patch and assemble it to be inserted into the code
                                asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code)));
                                cls.Instance.InstanceInit = asm.Assemble() as MethodInfo;
                                break;
                            case "add_class_trait": //add new class trait (method)
                                //Load the code from the patch and assemble it to be inserted into the code
                                asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code)));
                                newTrait = asm.Assemble() as TraitInfo;
                                traitIndex = cls.GetTraitIndexByTypeAndName(newTrait.Type, newTrait.Name.Name);
                                if (traitIndex < 0)
                                {
                                    cls.Traits.Add(newTrait);
                                }
                                else
                                {
                                    cls.Traits[traitIndex] = newTrait;
                                }
                                break;
                            case "add_instance_trait": //add new instance trait (method)
                                //Load the code from the patch and assemble it to be inserted into the code
                                asm = new Assembler(File.ReadAllText(Path.Combine(lessMod.Directory, patch.Code)));
                                newTrait = asm.Assemble() as TraitInfo;
                                traitIndex = cls.Instance.GetTraitIndexByTypeAndName(newTrait.Type, newTrait.Name.Name);
                                if (traitIndex < 0)
                                {
                                    cls.Instance.Traits.Add(newTrait);
                                }
                                else
                                {
                                    cls.Instance.Traits[traitIndex] = newTrait;
                                }
                                break;
                            case "remove_class_trait":
                                throw new NotImplementedException();
                            case "remove_instance_trait":
                                throw new NotImplementedException();
                            default:
                                throw new NotSupportedException($"Unknown Action \"{patch.Action}\" in mod {lessMod.Name}");
                        }
                    }

                    if (!classFound)
                    {
                        _errorLevel = ErrorLevel.UnableToPatch;
                        throw new ClassNotFoundException($"Class {patch.Class} not found in file {patch.Swf}");
                    }
                }
            }

            //Save the modified SWFS to their original location
            foreach (var patchedSwf in swfs)
            {
                try
                {
                    SetStatusLabelAsync("Applying mods: " + patchedSwf.Key);
                    string swfLoc = Path.Combine(lolLocation, patchedSwf.Key);
                    SwfFile.WriteFile(patchedSwf.Value, swfLoc);
                }
                catch
                {
                    _errorLevel = ErrorLevel.GoodJobYourInstallationIsProbablyCorruptedNow;
                    if (Debugger.IsAttached)
                        throw;
                }
            }
            timer.Stop();
        }