Beispiel #1
0
        public static void ApplyPatch(FpuSegment seg)
        {
            Process p=new Process();
            p.StartInfo.FileName="nasm.exe";
            p.StartInfo.Arguments="out.txt";
            p.StartInfo.UseShellExecute=false;
            p.StartInfo.CreateNoWindow=true;
            p.Start();
            p.WaitForExit();
            p.Close();
            FileInfo fi=new FileInfo("out");
            if(fi.Length==0) throw new OptimizationException("Patcher: Code generator produced uncompilable code");
            ArrayList code=new ArrayList();
            for(int i=0;i<seg.Pre.Length;i++) {
                code.AddRange(HexToString(seg.Pre[i].code));
            }
            code.AddRange(Program.ReadFileBytes("out"));
            for(int i=0;i<seg.Post.Length;i++) {
                code.AddRange(HexToString(seg.Post[i].code));
            }
            if(code.Count>seg.End-seg.Start) throw new OptimizationException("Patcher: Patch to big to fit into code");

            /*if(Program.TestPatches) {
                TestPatch(seg); //TESTPATCH CALL
            }*/
            if(Program.Benchmark) {
                Benchmark(seg); //BENCHMARK CALL!!!!!!!!!!!!!!!!!!!!!!!! <---------------- OVER HERE
            }
            byte[] Code=new byte[seg.End-seg.Start];
            code.CopyTo(Code);
            for(int i=code.Count;i<(seg.End-seg.Start);i++) {
                Code[i]=144;    //Fill the rest of the code up with nop's
            }
            long a=(seg.End-seg.Start)-code.Count;
            if(a>255) {
                throw new OptimizationException("Patcher: Patch end address out of range of a short jump");
            } else if(a>2) {
                Code[code.Count]=235;
                Code[code.Count+1]=(byte)(a-2);
            }
            if(Program.Restrict) {
                if(PatchCount<Program.FirstPatch||PatchCount>Program.LastPatch) {
                    PatchCount++;
                    throw new OptimizationException("Patcher: Patch restricted");
                }
                PatchCount++;
            }
            #if emitpatch
            FileStream fs2=File.Create("emittedpatch.patch",4096);
            BinaryWriter bw=new BinaryWriter(fs2);
            bw.Write(seg.Start);
            bw.Write(Code.Length);
            bw.Write(Code,0,Code.Length);
            bw.Close();
            #endif
            FileStream fs=File.Open("code",FileMode.Open);
            fs.Position=seg.Start;
            fs.Write(Code,0,Code.Length);
            fs.Close();
        }
Beispiel #2
0
        public static bool OptimizeSegment(ref CodeSegment segment)
        {
#if !fulltest
            if (segment.Lines[0].address != "0015FC6C")
            {
                return(false);
            }
            Console.WriteLine(LineNo);
#endif
            if (segment.ContainsFpu == false)
            {
                return(false);
            }
            //if(segment.Lines.Length<10) return false;

            //Fpu to sse stuff
            FpuSegment FpuStream = segment.GetFpuStream();
            CurrentSeg = segment;
            CurrentFpu = FpuStream;
            thingy     = true;
            fpu.Reset();
            string s;
            for (byte i = 0; i < FpuStream.Lines.Length; i++)
            {
                fpu.PerformOp(FpuStream.Lines[i], i);
            }
            fpu.Process();
            vectorizer.Reset();
            for (int i = 0; i < fpu.Result.Length; i++)
            {
                vectorizer.AddLine(fpu.Result[i], fpu.ResultLines[i]);
            }
            VectorMatch[] PatchedCode = vectorizer.Process();
            if (PatchedCode == null || PatchedCode.Length == 0)
            {
                throw new OptimizationException("Main: fpu code not vectorizable");
            }
            CodeGenerator.GenerateCode(new ArrayList(PatchedCode));
            Patcher.ApplyPatch(FpuStream);
            if (CreateLog)
            {
                s = string.Join("\r\n", fpu.Result);
                LogFile.Write(segment.Lines[0].address + ":");
                LogFile.WriteLine(CodeGenerator.ToHex(HexParse(FpuStream.Lines[0].address) + 4198400).Remove(0, 3).PadLeft(8, '0'));
                LogFile.WriteLine(s);
                LogFile.WriteLine("\r\nPatched:");
                LogFile.WriteLine(segment.FpuString);
                LogFile.WriteLine("\r\nwith:");
                LogFile.Write(FpuStream.PreString() + ReadFile("out.txt").Replace("bits 32\r\n", "") + FpuStream.PostString());
                if (Benchmark)
                {
                    LogFile.WriteLine("\r\nBenchmark:");
                    LogFile.WriteLine("FPU: " + Patcher.FpuTime.ToString());
                    LogFile.WriteLine("SSE: " + Patcher.SseTime.ToString());
                    LogFile.WriteLine("Ratio: " + ((double)Patcher.SseTime.Ticks / (double)Patcher.FpuTime.Ticks).ToString());
                }
                LogFile.WriteLine("------------------------------------------------");
            }
            return(true);
        }
Beispiel #3
0
        /*
         * public static void TestPatch(FpuSegment seg) {
         *  ArrayList TempCode;
         *  //Generate the code
         *  TempCode=new ArrayList(Program.ReadFileBytes("out"));
         *  byte[] sseCode=(byte[])TempCode.ToArray(typeof(byte));
         *  TempCode.Clear();
         *  StreamWriter sr=new StreamWriter("tout.txt");
         *  sr.WriteLine("bits 32");
         *  foreach(string s in seg.TestData) {
         *      sr.WriteLine(s);
         *  }
         *  sr.Close();
         *  Process p=new Process();
         *  p.StartInfo.FileName="nasm.exe";
         *  p.StartInfo.Arguments="-o tout tout.txt";
         *  p.StartInfo.UseShellExecute=false;
         *  p.StartInfo.CreateNoWindow=true;
         *  p.Start();
         *  p.WaitForExit();
         *  p.Close();
         *  FileInfo fi=new FileInfo("tout");
         *  if(fi.Length==0) throw new OptimizationException("Patcher: patch tester produced uncompilable code");
         *  TempCode.AddRange(Program.ReadFileBytes("tout"));
         *  byte[] fpuCode=(byte[])TempCode.ToArray(typeof(byte));
         *  //inject and run the code
         *  if(sseCode.Length>InjectionLength||fpuCode.Length>InjectionLength)
         *      throw new OptimizationException("Checker: Injection site is too short");
         *  try {
         *      File.Delete("asmTester2.exe");
         *  } catch { }
         *  try {
         *      File.Copy("asmTester.exe","asmTester2.exe");
         *      FileStream fs=File.Open("asmTester2.exe",FileMode.Open);
         *      fs.Position=TestPoint1;
         *      fs.Write(fpuCode,0,fpuCode.Length);
         *      fs.Position=TestPoint2;
         *      fs.Write(sseCode,0,sseCode.Length);
         *      fs.Close();
         *      p=new Process();
         *      p.StartInfo.UseShellExecute=false;
         *      p.StartInfo.CreateNoWindow=true;
         *      p.StartInfo.FileName="asmTester2.exe";
         *      p.Start();
         *      p.WaitForExit();
         *      if(!p.HasExited) {
         *          p.Kill();
         *          p.Close();
         *          throw new OptimizationException("Checker: Process has not exited");
         *      }
         *      if(p.ExitCode!=1) {
         *          p.Close();
         *          throw new OptimizationException("Checker: Patch appears to be corrupt");
         *      }
         *      p.Close();
         *  } catch (Exception e) {
         *      if(e is OptimizationException) throw;
         *      throw new OptimizationException("Checker: Something threw an exception");
         *  }
         *
         * }
         */

        public static void Benchmark(FpuSegment seg)
        {
            ArrayList TempCode;

            //Get the sse code
            TempCode = new ArrayList(Program.ReadFileBytes("out"));
            TempCode.AddRange(JumpCode);
            byte[] bytes = (byte[])TempCode.ToArray(typeof(byte));
            TempCode.Clear();
            //Get the fpu code
            int a = 0;

            for (int i = 0; i < seg.Lines.Length; i++)
            {
                if (a == CodeGenerator.FpuLines.Length)
                {
                    break;
                }
                if (CodeGenerator.FpuLines[a] == i)
                {
                    TempCode.AddRange(HexToString(seg.Lines[i].code));
                    a++;
                }
            }
            TempCode.AddRange(JumpCode);
            byte[] bytes2 = (byte[])TempCode.ToArray(typeof(byte));
            Benchmark(bytes, bytes2);
            if (!Program.IgnoreBenchmark)
            {
                if (SseTime >= FpuTime + Bias)
                {
                    throw new OptimizationException("Benchmarker: Patch was slower than original code");
                }
            }
        }
Beispiel #4
0
        public static bool OptimizeSegment(ref CodeSegment segment) {
#if !fulltest
            if(segment.Lines[0].address!="0015FC6C") return false;
            Console.WriteLine(LineNo);
#endif
            if(segment.ContainsFpu==false) return false;
            //if(segment.Lines.Length<10) return false;
            
            //Fpu to sse stuff
            FpuSegment FpuStream=segment.GetFpuStream();
            CurrentSeg=segment;
            CurrentFpu=FpuStream;
            thingy=true;
            fpu.Reset();
            string s;
            for(byte i=0;i<FpuStream.Lines.Length;i++) {
                fpu.PerformOp(FpuStream.Lines[i],i);
            }
            fpu.Process();
            vectorizer.Reset();
            for(int i=0;i<fpu.Result.Length;i++) {
                vectorizer.AddLine(fpu.Result[i],fpu.ResultLines[i]);
            }
            VectorMatch[] PatchedCode=vectorizer.Process();
            if(PatchedCode==null||PatchedCode.Length==0) throw new OptimizationException("Main: fpu code not vectorizable");
            CodeGenerator.GenerateCode(new ArrayList(PatchedCode));
            Patcher.ApplyPatch(FpuStream);
            if(CreateLog) {
                s=string.Join("\r\n",fpu.Result);
                LogFile.Write(segment.Lines[0].address+":");
                LogFile.WriteLine(CodeGenerator.ToHex(HexParse(FpuStream.Lines[0].address)+4198400).Remove(0,3).PadLeft(8,'0'));
                LogFile.WriteLine(s);
                LogFile.WriteLine("\r\nPatched:");
                LogFile.WriteLine(segment.FpuString);
                LogFile.WriteLine("\r\nwith:");
                LogFile.Write(FpuStream.PreString()+ReadFile("out.txt").Replace("bits 32\r\n","")+FpuStream.PostString());
                if(Benchmark) {
                    LogFile.WriteLine("\r\nBenchmark:");
                    LogFile.WriteLine("FPU: "+Patcher.FpuTime.ToString());
                    LogFile.WriteLine("SSE: "+Patcher.SseTime.ToString());
                    LogFile.WriteLine("Ratio: "+((double)Patcher.SseTime.Ticks/(double)Patcher.FpuTime.Ticks).ToString());
                }
                LogFile.WriteLine("------------------------------------------------");
            }
            return true;
        }
Beispiel #5
0
        /*
        public static void TestPatch(FpuSegment seg) {
            ArrayList TempCode;
            //Generate the code
            TempCode=new ArrayList(Program.ReadFileBytes("out"));
            byte[] sseCode=(byte[])TempCode.ToArray(typeof(byte));
            TempCode.Clear();
            StreamWriter sr=new StreamWriter("tout.txt");
            sr.WriteLine("bits 32");
            foreach(string s in seg.TestData) {
                sr.WriteLine(s);
            }
            sr.Close();
            Process p=new Process();
            p.StartInfo.FileName="nasm.exe";
            p.StartInfo.Arguments="-o tout tout.txt";
            p.StartInfo.UseShellExecute=false;
            p.StartInfo.CreateNoWindow=true;
            p.Start();
            p.WaitForExit();
            p.Close();
            FileInfo fi=new FileInfo("tout");
            if(fi.Length==0) throw new OptimizationException("Patcher: patch tester produced uncompilable code");
            TempCode.AddRange(Program.ReadFileBytes("tout"));
            byte[] fpuCode=(byte[])TempCode.ToArray(typeof(byte));
            //inject and run the code
            if(sseCode.Length>InjectionLength||fpuCode.Length>InjectionLength)
                throw new OptimizationException("Checker: Injection site is too short");
            try {
                File.Delete("asmTester2.exe");
            } catch { }
            try {
                File.Copy("asmTester.exe","asmTester2.exe");
                FileStream fs=File.Open("asmTester2.exe",FileMode.Open);
                fs.Position=TestPoint1;
                fs.Write(fpuCode,0,fpuCode.Length);
                fs.Position=TestPoint2;
                fs.Write(sseCode,0,sseCode.Length);
                fs.Close();
                p=new Process();
                p.StartInfo.UseShellExecute=false;
                p.StartInfo.CreateNoWindow=true;
                p.StartInfo.FileName="asmTester2.exe";
                p.Start();
                p.WaitForExit();
                if(!p.HasExited) {
                    p.Kill();
                    p.Close();
                    throw new OptimizationException("Checker: Process has not exited");
                }
                if(p.ExitCode!=1) {
                    p.Close();
                    throw new OptimizationException("Checker: Patch appears to be corrupt");
                }
                p.Close();
            } catch (Exception e) {
                if(e is OptimizationException) throw;
                throw new OptimizationException("Checker: Something threw an exception");
            }

        }
        */
        public static void Benchmark(FpuSegment seg)
        {
            ArrayList TempCode;
            //Get the sse code
            TempCode=new ArrayList(Program.ReadFileBytes("out"));
            TempCode.AddRange(JumpCode);
            byte[] bytes=(byte[])TempCode.ToArray(typeof(byte));
            TempCode.Clear();
            //Get the fpu code
            int a=0;
            for(int i=0;i<seg.Lines.Length;i++) {
                if(a==CodeGenerator.FpuLines.Length) break;
                if(CodeGenerator.FpuLines[a]==i) {
                    TempCode.AddRange(HexToString(seg.Lines[i].code));
                    a++;
                }
            }
            TempCode.AddRange(JumpCode);
            byte[] bytes2=(byte[])TempCode.ToArray(typeof(byte));
            Benchmark(bytes,bytes2);
            if(!Program.IgnoreBenchmark) {
                if(SseTime>=FpuTime+Bias) throw new OptimizationException("Benchmarker: Patch was slower than original code");
            }
        }
Beispiel #6
0
        public static void ApplyPatch(FpuSegment seg)
        {
            Process p = new Process();

            p.StartInfo.FileName        = "nasm.exe";
            p.StartInfo.Arguments       = "out.txt";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow  = true;
            p.Start();
            p.WaitForExit();
            p.Close();
            FileInfo fi = new FileInfo("out");

            if (fi.Length == 0)
            {
                throw new OptimizationException("Patcher: Code generator produced uncompilable code");
            }
            ArrayList code = new ArrayList();

            for (int i = 0; i < seg.Pre.Length; i++)
            {
                code.AddRange(HexToString(seg.Pre[i].code));
            }
            code.AddRange(Program.ReadFileBytes("out"));
            for (int i = 0; i < seg.Post.Length; i++)
            {
                code.AddRange(HexToString(seg.Post[i].code));
            }
            if (code.Count > seg.End - seg.Start)
            {
                throw new OptimizationException("Patcher: Patch to big to fit into code");
            }

            /*if(Program.TestPatches) {
             *  TestPatch(seg); //TESTPATCH CALL
             * }*/
            if (Program.Benchmark)
            {
                Benchmark(seg); //BENCHMARK CALL!!!!!!!!!!!!!!!!!!!!!!!! <---------------- OVER HERE
            }
            byte[] Code = new byte[seg.End - seg.Start];
            code.CopyTo(Code);
            for (int i = code.Count; i < (seg.End - seg.Start); i++)
            {
                Code[i] = 144;    //Fill the rest of the code up with nop's
            }
            long a = (seg.End - seg.Start) - code.Count;

            if (a > 255)
            {
                throw new OptimizationException("Patcher: Patch end address out of range of a short jump");
            }
            else if (a > 2)
            {
                Code[code.Count]     = 235;
                Code[code.Count + 1] = (byte)(a - 2);
            }
            if (Program.Restrict)
            {
                if (PatchCount < Program.FirstPatch || PatchCount > Program.LastPatch)
                {
                    PatchCount++;
                    throw new OptimizationException("Patcher: Patch restricted");
                }
                PatchCount++;
            }
#if emitpatch
            FileStream   fs2 = File.Create("emittedpatch.patch", 4096);
            BinaryWriter bw  = new BinaryWriter(fs2);
            bw.Write(seg.Start);
            bw.Write(Code.Length);
            bw.Write(Code, 0, Code.Length);
            bw.Close();
#endif
            FileStream fs = File.Open("code", FileMode.Open);
            fs.Position = seg.Start;
            fs.Write(Code, 0, Code.Length);
            fs.Close();
        }