Exemple #1
0
        private void cmdCompile_Click(object sender, EventArgs e)
        {
            string VirtualOffsetString = txtVirtualOffset.Text.Trim();

            if (VirtualOffsetString.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
            {
                VirtualOffsetString = VirtualOffsetString.Substring(2);
            }

            UInt32   VirtualOffset = 0;
            CodeType CodeType      = Patcher.CodeType.Thumb2;

            byte[] CompiledCode = null;
            if (UInt32.TryParse(VirtualOffsetString, System.Globalization.NumberStyles.HexNumber, null, out VirtualOffset))
            {
                CodeType     = (CodeType)Enum.Parse(typeof(Patcher.CodeType), cmbCodeType.SelectedItem.ToString());
                CompiledCode = ArmCompiler.Compile(txtVisualStudioPath.Text, VirtualOffset, CodeType, txtAssemblyCode.Text);
            }
            if ((VirtualOffset != 0) && (CompiledCode == null))
            {
                txtCompiledOpcodes.Text = ArmCompiler.Output;
            }
            else if (CompiledCode != null)
            {
                txtCompiledOpcodes.Text = Converter.ConvertHexToString(CompiledCode, " ");
            }
        }
Exemple #2
0
        private void cmdPatch_Click(object sender, EventArgs e)
        {
            string VirtualOffsetString = txtVirtualOffset.Text.Trim();

            if (VirtualOffsetString.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
            {
                VirtualOffsetString = VirtualOffsetString.Substring(2);
            }
            UInt32   VirtualOffset = 0;
            CodeType CodeType      = Patcher.CodeType.Thumb2;

            byte[] CompiledCode = null;
            if (UInt32.TryParse(VirtualOffsetString, System.Globalization.NumberStyles.HexNumber, null, out VirtualOffset))
            {
                CodeType     = (CodeType)Enum.Parse(typeof(Patcher.CodeType), cmbCodeType.SelectedItem.ToString());
                CompiledCode = ArmCompiler.Compile(txtVisualStudioPath.Text, VirtualOffset, CodeType, txtAssemblyCode.Text);
            }
            if ((VirtualOffset != 0) && (CompiledCode == null))
            {
                txtCompiledOpcodes.Text = ArmCompiler.Output;
            }
            else
            {
                if (CompiledCode != null)
                {
                    txtCompiledOpcodes.Text = Converter.ConvertHexToString(CompiledCode, " ");
                }

                string TargetFilePath = Path.Combine(cmbTargetPath.Text, Path.GetFileName(txtInputFile.Text));
                if (TargetFilePath.StartsWith(@"\"))
                {
                    TargetFilePath = TargetFilePath.Substring(1);
                }

                try
                {
                    MainPatcher.AddPatch(txtInputFile.Text, (txtOutputFile.Text.Trim().Length > 0) ? txtOutputFile.Text : null, cmbPatchDefinitionName.Text, cmbTargetVersion.Text, TargetFilePath, txtVisualStudioPath.Text, VirtualOffset, CodeType, txtAssemblyCode.Text, txtPatchDefinitionsFile.Text);
                }
                catch (ArgumentOutOfRangeException)
                {
                    txtCompiledOpcodes.Text = "BAD VIRTUAL OFFSET";
                }
                catch
                {
                    txtCompiledOpcodes.Text = "UNKNOWN ERROR";
                }

                txtVirtualOffset.Focus();
                txtVirtualOffset.SelectAll();
            }
        }
Exemple #3
0
        // TargetFilePath is relative to the root of the PatchDefinition
        // OutputFilePath can be null
        public static void AddPatch(string InputFilePath, string OutputFilePath, string PatchDefinitionName, string TargetVersionDescription, string TargetFilePath, string PathToVisualStudioWithWP8SDK, UInt32 VirtualAddress, CodeType CodeType, string ArmCodeFragment, string PatchDefintionsXmlPath)
        {
            SHA1Managed SHA = new SHA1Managed();

            // Compile ARM code
            byte[] CompiledCode = null;
            if (VirtualAddress != 0)
            {
                CompiledCode = ArmCompiler.Compile(PathToVisualStudioWithWP8SDK, VirtualAddress, CodeType, ArmCodeFragment);
            }

            // Read original binary
            byte[] Binary = File.ReadAllBytes(InputFilePath);

            // Backup original checksum
            UInt32 ChecksumOffset   = GetChecksumOffset(Binary);
            UInt32 OriginalChecksum = ByteOperations.ReadUInt32(Binary, ChecksumOffset);

            // Determine Raw Offset
            PeFile PeFile    = new PeFile(Binary);
            UInt32 RawOffset = 0;

            if (VirtualAddress != 0)
            {
                RawOffset = PeFile.ConvertVirtualAddressToRawOffset(VirtualAddress);
            }

            // Add or replace patch
            string          PatchDefintionsXml = File.ReadAllText(PatchDefintionsXmlPath);
            PatchEngine     PatchEngine        = new PatchEngine(PatchDefintionsXml);
            PatchDefinition PatchDefinition    = PatchEngine.PatchDefinitions.Where(d => (string.Compare(d.Name, PatchDefinitionName, true) == 0)).FirstOrDefault();

            if (PatchDefinition == null)
            {
                PatchDefinition      = new PatchDefinition();
                PatchDefinition.Name = PatchDefinitionName;
                PatchEngine.PatchDefinitions.Add(PatchDefinition);
            }
            TargetVersion TargetVersion = PatchDefinition.TargetVersions.Where(v => (string.Compare(v.Description, TargetVersionDescription, true) == 0)).FirstOrDefault();

            if (TargetVersion == null)
            {
                TargetVersion             = new TargetVersion();
                TargetVersion.Description = TargetVersionDescription;
                PatchDefinition.TargetVersions.Add(TargetVersion);
            }
            TargetFile TargetFile = TargetVersion.TargetFiles.Where(f => ((f.Path != null) && (string.Compare(f.Path.TrimStart(new char[] { '\\' }), TargetFilePath.TrimStart(new char[] { '\\' }), true) == 0))).FirstOrDefault();

            if (TargetFile == null)
            {
                TargetFile = new TargetFile();
                TargetVersion.TargetFiles.Add(TargetFile);
            }
            TargetFile.Path         = TargetFilePath;
            TargetFile.HashOriginal = SHA.ComputeHash(Binary);
            Patch Patch;

            if (VirtualAddress != 0)
            {
                Patch = TargetFile.Patches.Where(p => p.Address == RawOffset).FirstOrDefault();
                if (Patch == null)
                {
                    Patch         = new Patch();
                    Patch.Address = RawOffset;
                    TargetFile.Patches.Add(Patch);
                }
                Patch.OriginalBytes = new byte[CompiledCode.Length];
                Buffer.BlockCopy(Binary, (int)RawOffset, Patch.OriginalBytes, 0, CompiledCode.Length);
                Patch.PatchedBytes = CompiledCode;
            }

            // Apply all patches
            foreach (Patch CurrentPatch in TargetFile.Patches)
            {
                Buffer.BlockCopy(CurrentPatch.PatchedBytes, 0, Binary, (int)CurrentPatch.Address, CurrentPatch.PatchedBytes.Length);
            }

            // Calculate checksum
            // This also modifies the binary
            // Original checksum is already backed up
            UInt32 Checksum = CalculateChecksum(Binary);

            // Add or replace checksum patch
            Patch = TargetFile.Patches.Where(p => p.Address == ChecksumOffset).FirstOrDefault();
            if (Patch == null)
            {
                Patch         = new Patch();
                Patch.Address = ChecksumOffset;
                TargetFile.Patches.Add(Patch);
            }
            Patch.OriginalBytes = new byte[4];
            ByteOperations.WriteUInt32(Patch.OriginalBytes, 0, OriginalChecksum);
            Patch.PatchedBytes = new byte[4];
            ByteOperations.WriteUInt32(Patch.PatchedBytes, 0, Checksum);

            // Calculate hash for patched target file
            TargetFile.HashPatched = SHA.ComputeHash(Binary);

            // Write patched file
            if (OutputFilePath != null)
            {
                File.WriteAllBytes(OutputFilePath, Binary);
            }

            // Write PatchDefintions
            PatchEngine.WriteDefinitions(PatchDefintionsXmlPath);
        }