public async override Task <string> Compare(string ofi, string nfi) { StringBuilder sb = new StringBuilder(); string ofi_temp = Path.GetTempFileName(); try { string nfi_temp = Path.GetTempFileName(); try { await Preprocess(ofi, ofi_temp); await Preprocess(nfi, nfi_temp); var cmd = new NullSource() .Pipe(new Command(Tools.Diff, ofi_temp, nfi_temp)) .Pipe(new StringSink(sb)); await cmd.Run(); } finally { File.Delete(nfi_temp); } } finally { File.Delete(ofi_temp); } return(sb.ToString()); }
protected async override Task Preprocess(string infile, string outfile) { Directory.SetCurrentDirectory(Path.GetDirectoryName(infile)); var cmd = new NullSource() .Pipe(new Command(Tools.Sigcheck, "-d", infile)) .Pipe(new Command(Tools.Sed, "-n", Tools.Quote(@"/HWID/p;/OS:/p"))) .Pipe(new FileSink(outfile)); await cmd.Run(); }
protected async override Task Preprocess(string infile, string outfile) { if (!File.Exists(Tools.Resedit)) { return; } // Resedit doesn't recognize all PE file extensions so always rename to .exe // and also copy to a separate directory to avoid output file name conflicts string tmpPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory(tmpPath); try { string tmpFile = Path.GetTempFileName(); string tmpFileExe = Path.Combine(tmpPath, Path.GetFileNameWithoutExtension(infile) + ".exe"); string tmpFileRc = Path.ChangeExtension(tmpFileExe, "rc"); File.Copy(infile, tmpFileExe); FileAttributes attributes = File.GetAttributes(tmpFileExe); if (attributes.HasFlag(FileAttributes.ReadOnly)) { File.SetAttributes(tmpFileExe, attributes & ~FileAttributes.ReadOnly); } var cmd1 = new NullSource() .Pipe(new Command(Tools.Resedit, "-convert", tmpFileExe, tmpFileRc)); await cmd1.Run(); // normalize versions var cmd2 = new FileSource(tmpFileRc) .Pipe(new Command(Tools.Sed, Tools.Quote(@"s/\([0-9]*[,\.][0-9]*[,\.][0-9]*[,\.]\)[0-9]*/\10/"))) .Pipe(new FileSink(outfile)); await cmd2.Run(); // process and delete other resource artifacts var dir = new DirectoryInfo(Path.GetDirectoryName(tmpFileRc)); foreach (var file in dir.EnumerateFiles("manifest*.xml")) { string manifest = File.ReadAllText(file.FullName); File.AppendAllText(outfile, manifest); } } finally { Directory.Delete(tmpPath, true); } }
protected async override Task Preprocess(string infile, string outfile) { var cmd1 = new NullSource() .Pipe(new Command(Tools.Dumpbin, "/HEADERS", infile)) .Pipe(new Command(Tools.Sed, "-n", Tools.Quote(@"/machine/p;/characteristics/p;/subsystem/p;/size of image/p;" + @"s/^.*entry point (.*) \(.*\)$/entry point \1/p"))) .Pipe(new FileSink(outfile)); await cmd1.Run(); SortedDictionary <string, List <string> > importDict = new SortedDictionary <string, List <string> >(); string tmpFile = Path.GetTempFileName(); try { var cmd2 = new NullSource() .Pipe(new Command(Tools.Dumpbin, "/IMPORTS", infile)) .Pipe(new Command(Tools.Sed, "-r", Tools.Quote(@"s/^ *[0-9A-F]+/ /g"))) .Pipe(new Command(Tools.Sed, Tools.Quote(@"/Import Address Table/d;/Import Name Table/d;/time date stamp/d;/Index of first forwarder reference/d"))) .Pipe(new FileSink(tmpFile)); await cmd2.Run(); // sort imports by module and symbol for a nice diff string line; string module = null; using (StreamReader sr = new StreamReader(tmpFile)) { while ((line = sr.ReadLine()) != null) { if (line.StartsWith(" Summary")) { // summary is not interesting, bail break; } if (line.StartsWith(" ")) { importDict[module].Add(line.Trim()); } else if (line.StartsWith(" ")) { module = line.Trim().ToUpper(); if (!importDict.ContainsKey(module)) { importDict[module] = new List <string>(); } } } } } finally { File.Delete(tmpFile); } using (StreamWriter sw = new StreamWriter(outfile, true)) { foreach (var pair in importDict) { var imports = pair.Value; imports.Sort(); foreach (var import in imports) { sw.WriteLine(" " + pair.Key + ": " + import); } } } }