private static string findOnly(string file, ref string[] svals)
        {
            byte[] bytes;
            bytes = File.ReadAllBytes(file);

            int[] locs = Patcher.BinaryPatternSearch(ref bytes, svals, false);


            if (locs.Length == 1)
            {
                return(string.Format("Pattern found at: {0}+{1:X8}", tarfilename, locs[0]));
            }
            else if (locs.Length < 1)
            {
                return("Pattern not found.");
            }
            else
            {
                return(locs.Length.ToString() + " occurrences found.");
            }
        }
Ejemplo n.º 2
0
        private static bool doMemPatch(string[] processName, string[] svals, int offset, string[] rvals)
        {
            // Get process
            Process proc;

            if (processName.Length == 3)
            {
                proc = Process.GetProcessById(int.Parse(processName[2]));
            }
            else
            {
                proc = Process.GetProcessesByName(processName[1])[0];
            }
            IntPtr baseAddress = proc.MainModule.BaseAddress;
            IntPtr moduleSize  = (IntPtr)proc.MainModule.ModuleMemorySize;

            IntPtr hProc = NativeMethods.OpenProcess(NativeMethods.ProcessAccessFlags.All, false, proc.Id);

            // Read bytes
            int bytesRead = 0;

            byte[] bytes = new byte[moduleSize.ToInt32()];
            if (!NativeMethods.ReadProcessMemory(hProc, baseAddress, bytes, moduleSize, ref bytesRead) || bytes == null)
            {
                goto badEnding;
            }

            // Search binary data for pattern
            int[] locs = Patcher.BinaryPatternSearch(ref bytes, svals);
            // Make sure we only have 1 match
            if (!onlyOne(locs.Length, processName[1], String.Join(" ", svals)))
            {
                goto badEnding;
            }
            // Replace
            int replaced = Patcher.BinaryPatternReplace(ref bytes, locs[0], rvals, offset);

            if (replaced < 1)
            {
                goto badEnding;
            }

            // Write bytes
            int  bytesWritten = 0;
            uint oldp         = 0;
            uint oldp2        = 0;

            byte[] newbytes = new byte[rvals.Length];
            IntPtr off      = baseAddress + locs[0] + offset;

            // Get write privileges
            if (!NativeMethods.VirtualProtectEx(proc.Handle, off, (IntPtr)rvals.Length, (uint)NativeMethods.Protection.PAGE_EXECUTE_WRITECOPY, ref oldp))
            {
                goto badEnding;
            }
            // Do actual write
            Array.Copy(bytes, locs[0] + offset, newbytes, 0, rvals.Length);
            NativeMethods.WriteProcessMemory(hProc, off, newbytes, (IntPtr)rvals.Length, ref bytesWritten);
            // Set original access rights back (we have no buisness getting errors here)
            NativeMethods.VirtualProtectEx(proc.Handle, off, (IntPtr)rvals.Length, oldp, ref oldp2);
            // Were we successful?
            if (bytesWritten != rvals.Length)
            {
                goto badEnding;
            }

            // Happy ending. :)
            NativeMethods.CloseHandle(hProc);
            return(true);

badEnding:
            NativeMethods.CloseHandle(hProc);
            return(false);
        }
Ejemplo n.º 3
0
        private static bool doPatch(string file, string search, string offset, string replace)
        {
            // Variable setup
            int off;

            if (!Int32.TryParse(offset, out off))
            {
                return(false);
            }
            search  = search.Trim();
            replace = replace.Trim();
            string[] svals = search.Replace(_qq, _q).Replace(_ss, _q).Split(' ');
            string[] rvals = replace.Replace(_qq, _q).Replace(_ss, _q).Split(' ');

            if (replace.Length == 0)
            {
                return(findOnly(file, ref svals));
            }

            // MemPatch! :) (Highly experimental!)
            if (file.Length > 5 && file.Substring(0, 5).ToLower() == _p)
            {
                return(doMemPatch(file.Split(':'), svals, off, rvals));
            }

            if (!File.Exists(file))
            {
                if (isconsole == 0)
                {
                    MessageBox.Show("File not found.");
                }
                else if (isconsole == 2)
                {
                    Console.WriteLine(file + " not found.");
                }
                return(false);
            }

            // Get file contents
            byte[] bytes = File.ReadAllBytes(file);
            // Search binary data for pattern
            int[] locs = Patcher.BinaryPatternSearch(ref bytes, svals);
            // Make sure we only have 1 match
            if (!onlyOne(locs.Length, file, search))
            {
                return(false);
            }
            // Replace
            int replaced = Patcher.BinaryPatternReplace(ref bytes, locs[0], rvals, off);

            if (replaced < 1)
            {
                return(false);
            }

            // Write new file
            if (!File.Exists(file + _b))
            {
                File.Move(file, file + _b);
            }
            File.WriteAllBytes(file, bytes);
            return(true);
        }
Ejemplo n.º 4
0
        private static string processArgs()
        {
            int    patched = 0;
            string ret     = " ";

            switch (args[1])
            {
            case "e":
            case "-e":
            case "/e":
                for (int i = 0; i < settings.Count; i++)
                {
                    if (doPatch(settings[i][1], settings[i][2], settings[i][3], settings[i][4]))
                    {
                        patched++;
                    }
                    else if (isconsole == 2)
                    {
                        Console.WriteLine(settings[i][0] + " patch failed. (Nothing written.)");
                    }
                }
                break;

            case "x":
            case "-x":
            case "/x":
                if (args.Length != 6)
                {
                    goto default;
                }
                if (doPatch(args[2], args[3], args[4], args[5]))
                {
                    return("All done. " + args[2] + " successfully patched.\n");
                }
                break;

            case "r":
            case "-r":
            case "/r":
                for (int i = 0; i < settings.Count; i++)
                {
                    restore(settings[i][1]);
                }
                break;

            case "m":
            case "-m":
            case "/m":
                if (args.Length != 5)
                {
                    goto default;
                }
                if (!File.Exists(args[3]) || !File.Exists(args[4]))
                {
                    break;
                }
                if ((new FileInfo(args[3])).Length != (new FileInfo(args[4])).Length)
                {
                    if (isconsole == 2)
                    {
                        Console.WriteLine("Not equal size!");
                    }
                    break;
                }
                Spinner.Start();
                byte[] bytes1 = File.ReadAllBytes(args[3]);
                byte[] bytes2 = File.ReadAllBytes(args[4]);
                if (args[2].Length > gz.Length && args[2].Substring(args[2].Length - gz.Length) == gz)
                {
                    CompressINI(args[2], Patcher.Format4Ini(Patcher.FindDiffs(ref bytes1, ref bytes2), args[3], "Patch"));
                }
                else
                {
                    File.WriteAllText(args[2], Patcher.Format4Ini(Patcher.FindDiffs(ref bytes1, ref bytes2), args[3], "Patch"));
                }
                Spinner.Stop();
                ret = args[2] + " written.\n";
                break;

            default:
                return("Command line options:\n\n" +
                       iam + " [e [ini_file]]\n" +
                       "\tRun all patches specified in the inifile.\n\n" +
                       iam + " [x file search_pattern offset replace_pattern]\n" +
                       "\tRun patch given by arguments.\n\n" +
                       iam + " [r [ini_file]]\n" +
                       "\tRestore all files mentioned in inifile from their backups.\n\n" +
                       iam + " [m out_ini_file[" + gz + "] original_file changed_file]\n" +
                       "\tTry to create a pattern based patch for original_file. (Don't get your hopes up.)\n");
            }
            if (patched > 0)
            {
                ret = "All done. " + patched.ToString() + " patches executed.\n";
            }
            return(ret);
        }