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(); }
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); }
/* * 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"); } } }
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; }
/* 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"); } }
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(); }