private ThreatInformation FeatureExtractFile(string filePath, bool forPrediction = false) { var peFile = new PeNet.PeFile(filePath); var information = new ThreatInformation { NumberImports = peFile.ImageResourceDirectory.NumberOfIdEntries, DataSizeInBytes = peFile.ImageSectionHeaders.FirstOrDefault()?.SizeOfRawData ?? 0.0f }; foreach (var name in Enum.GetNames(typeof(ThreatTypes))) { if (!filePath.Contains(name)) { continue; } information.Classification = name; } if (!string.IsNullOrEmpty(information.Classification) || forPrediction) { return(information); } Console.WriteLine($"{filePath} was not named properly"); return(null); }
private bool CheckExeCodeSize(string exeo, string exep) { var peoHeaderE = new PeNet.PeFile(exeo); var peoHeaderO = new PeNet.PeFile(exep); return(peoHeaderE.ImageSectionHeaders[0].SizeOfRawData == peoHeaderO.ImageSectionHeaders[0].SizeOfRawData); }
public static List <string> GetDllCharacteristics(string Path) { List <string> output = new List <string>(); if (NeedsSignature(Path)) { try { // This line throws the exceptions below. var peHeader1 = new PeNet.PeFile(Path); ushort characteristics = peHeader1.ImageNtHeaders.OptionalHeader.DllCharacteristics; foreach (DLLCHARACTERISTICS characteristic in Enum.GetValues(typeof(DLLCHARACTERISTICS))) { if (((ushort)characteristic & characteristics) == (ushort)characteristic) { output.Add(characteristic.ToString()); } } } catch (IndexOutOfRangeException) { Log.Verbose("Failed to get PE Headers for {0} (IndexOutOfRangeException)", Path); } catch (ArgumentNullException) { Log.Verbose("Failed to get PE Headers for {0} (ArgumentNullException)", Path); } catch (Exception e) { Log.Debug(e, "Failed to get DLL Characteristics for path: {0}", Path); } } return(output); }
protected internal static List <DLLCHARACTERISTICS> GetDllCharacteristics(string Path) { if (NeedsSignature(Path)) { try { List <DLLCHARACTERISTICS> l = new List <DLLCHARACTERISTICS>(); var peHeader1 = new PeNet.PeFile(Path); ushort characteristics = peHeader1.ImageNtHeaders.OptionalHeader.DllCharacteristics; foreach (DLLCHARACTERISTICS characteristic in Enum.GetValues(typeof(DLLCHARACTERISTICS))) { if (((ushort)characteristic & characteristics) == (ushort)characteristic) { l.Add(characteristic); } } return(l); } // Catches a case where the line establising the PeFile fails with Index outside bounds of the array. catch (IndexOutOfRangeException) { Log.Verbose("Failed to get PE headers for {0}", Path); } catch (Exception e) { Log.Debug("{0}:{1}", e.GetType().ToString(), e.Message); Log.Debug(e.StackTrace); } } return(new List <DLLCHARACTERISTICS>()); }
public void ExportedFunctions_WithForwardedFunctions_ParsedFordwardedFunctions() { var peFile = new PeNet.PeFile(@"Binaries/win_test.dll"); var forwardExports = peFile.ExportedFunctions.Where(e => e.HasForwad).ToList(); Assert.Equal(180, forwardExports.Count); Assert.Equal("NTDLL.RtlEnterCriticalSection", forwardExports.First(e => e.Name == "EnterCriticalSection").ForwardName); }
public static bool GetImageArchitecture(string filepath) { var file = new PeNet.PeFile(filepath); if (file.HasValidComDescriptor) { throw new BadImageFormatException(".NET assembly is not supported."); } return(file.Is32Bit); }
static void Main(string[] args) { var file = new PeNet.PeFile(@"C:\Local Virus Copies\7c1dba942ca01313b5f4fbcf085d92ce65d1c0c69587fa64207c040179bf23fc"); Console.WriteLine($"IsValidPeFile: {file.IsValidPeFile.ToString()}"); Console.WriteLine($"HasValidExceptionDir.: {file.HasValidExceptionDir.ToString()}"); Console.WriteLine($"HasValidExportDir.: {file.HasValidExportDir.ToString()}"); Console.WriteLine($"HasValidImportDir.: {file.HasValidImportDir.ToString()}"); Console.WriteLine($"HasValidResourceDir.: {file.HasValidResourceDir.ToString()}"); Console.WriteLine($"HasValidSecurityDir.: {file.HasValidSecurityDir.ToString()}"); Console.ReadKey(); }
/// <summary> /// Tries to parse the PE file. If no exceptions are thrown, true /// </summary> /// <param name="file"></param> /// <returns>True if the file could be parsed as a PE file, else false.</returns> public static bool IsValidPEFile(string file) { PeNet.PeFile pe = null; try { pe = new PeNet.PeFile(file); } catch { return(false); } return(pe.IsValidPeFile); }
private CodeByte Disamexe(string fileexe) { progressBar1.Maximum = 100; CodeByte codeByte = new CodeByte(); int exampleCodeBitness; var peHeader = new PeNet.PeFile(fileexe); if (peHeader.Is64Bit) { exampleCodeBitness = 64; } else { exampleCodeBitness = 32; } FileStream input = new FileStream(fileexe, FileMode.Open, FileAccess.Read); BinaryReader reader = new BinaryReader(input); reader.ReadBytes((int)peHeader.ImageSectionHeaders[0].PointerToRawData); byte[] buffer = reader.ReadBytes((int)peHeader.ImageSectionHeaders[0].SizeOfRawData); input.Close(); ulong exampleCodeRIP = peHeader.ImageNtHeaders.OptionalHeader.ImageBase + peHeader.ImageSectionHeaders[0].VirtualAddress; var codeBytes = buffer; var codeReader = new ByteArrayCodeReader(codeBytes); var decoder = Iced.Intel.Decoder.Create(exampleCodeBitness, codeReader); decoder.IP = exampleCodeRIP; ulong endRip = decoder.IP + (uint)codeBytes.Length; var instructions = new InstructionList(); while (decoder.IP < endRip) { decoder.Decode(out instructions.AllocUninitializedElement()); if (decoder.IP % PROGRESS_MODULO == 0) { progressBar1.Value = (int)(decoder.IP * 100 / endRip); } } codeByte.instructions = instructions; codeByte.hexcode = buffer; codeByte.CodeRIP = exampleCodeRIP; return(codeByte); }
public static Signature?GetSignatureStatus(string Path) { if (!NeedsSignature(Path)) { return(null); } try { var peHeader = new PeNet.PeFile(Path); var authenticodeInfo = new AuthenticodeInfo(peHeader); var sig = new Signature(authenticodeInfo); return(sig); } catch (Exception) { } return(null); }
public static List <string> GetDllCharacteristics(string Path) { List <string> output = new List <string>(); if (NeedsSignature(Path)) { try { // This line throws the exceptions below. using var peHeader1 = new PeNet.PeFile(Path); var dllCharacteristics = peHeader1.ImageNtHeaders?.OptionalHeader.DllCharacteristics; if (dllCharacteristics is DllCharacteristicsType chars) { ushort characteristics = (ushort)chars; foreach (DLLCHARACTERISTICS?characteristic in Enum.GetValues(typeof(DLLCHARACTERISTICS))) { if (characteristic is DLLCHARACTERISTICS c) { if (((ushort)c & characteristics) == (ushort)c) { output.Add(c.ToString()); } } } } } catch (Exception e) when( e is IndexOutOfRangeException || e is ArgumentNullException || e is System.IO.IOException || e is ArgumentException || e is UnauthorizedAccessException || e is NullReferenceException) { Log.Verbose($"Failed to get PE Headers for {Path} {e.GetType().ToString()}"); } catch (Exception e) { Log.Debug(e, $"Failed to get PE Headers for {Path}"); } } return(output); }
public static Signature?GetSignatureStatus(string Path) { if (!NeedsSignature(Path)) { return(null); } try { using var peHeader = new PeNet.PeFile(Path); if (peHeader.Authenticode is AuthenticodeInfo ai) { var sig = new Signature(ai); return(sig); } } catch (Exception e) { Log.Debug(e, "Thrown in GetSignatureStatus"); } return(null); }
public FileClassificationResponseItem(byte[] fileBytes) { SHA1Sum = fileBytes.ToSHA1(); Confidence = 0.0; IsMalicious = false; FileSize = fileBytes.Length; try { var peFile = new PeNet.PeFile(fileBytes); Is64Bit = peFile.Is64Bit ? TRUE : FALSE; try { NumImports = peFile.ImageImportDescriptors.Length; } catch { NumImports = 0.0f; } NumImportFunctions = peFile.ImportedFunctions.Length; if (peFile.ExportedFunctions != null) { NumExportFunctions = peFile.ExportedFunctions.Length; } IsSigned = peFile.IsSigned ? TRUE : FALSE; Strings = fileBytes.ToStringsExtraction(); } catch (Exception) { ErrorMessage = $"Invalid file ({SHA1Sum}) - only PE files are supported"; } }
public static int ParseConfig(ref DSConfig config, ref DSFileInfo fi) { D.Print("Entering ParseConfig()"); string file = new string(config.file).Replace("\0", ""); // Checks if file exists if (File.Exists(file) == false) { return(Constants.DONUT_ERROR_INVALID_PARAMETER); } // Validate URL if (config.inst_type == Constants.DONUT_INSTANCE_URL) { // Make sure it's a validate URL (check this don't know exactly how it's checking) D.Print("Validating URL"); if (Uri.IsWellFormedUriString(String(config.url), UriKind.Absolute) == false) { return(Constants.DONUT_ERROR_INVALID_URL); } // If URL doesn't have trailing slash, add one //if (config.url(config.url.Length - 1) != "/") //{ // config.url += "/"; //} } // Validate Arch D.Print("Checking for Arch Mismatch"); if (config.arch != Constants.DONUT_ARCH_ANY && config.arch != Constants.DONUT_ARCH_X86 && config.arch != Constants.DONUT_ARCH_X84 && config.arch != Constants.DONUT_ARCH_X64) { return(Constants.DONUT_ERROR_INVALID_ARCH); } // Validate AMSI/WDLP Bypass Option D.Print("Validating Bypass Option"); if (config.bypass != Constants.DONUT_BYPASS_SKIP && config.bypass != Constants.DONUT_BYPASS_ABORT && config.bypass != Constants.DONUT_BYPASS_CONTINUE) { return(Constants.DONUT_ERROR_BYPASS_INVALID); } // Get File Info var ret = ParseInputFile(file, ref fi); if (ret != Constants.DONUT_ERROR_SUCCESS) { return(ret); } // Set Module Type config.mod_type = fi.type; if (config.mod_type == Constants.DONUT_MODULE_DLL || config.mod_type == Constants.DONUT_MODULE_EXE) { // Check for Arch mismatch if ((config.arch == Constants.DONUT_ARCH_X86 && fi.arch == Constants.DONUT_ARCH_X64) || (config.arch == Constants.DONUT_ARCH_X64 && fi.arch == Constants.DONUT_ARCH_X86)) { return(Constants.DONUT_ERROR_ARCH_MISMATCH); } // Check existence of DLL function specified if (config.mod_type == Constants.DONUT_MODULE_DLL && config.method != null) { try { var exported = new PeNet.PeFile(file).ExportedFunctions; bool found = false; foreach (var func in exported) { if (func.Name == String(config.method)) { found = true; } } if (found == false) { return(Constants.DONUT_ERROR_DLL_FUNCTION); } } catch { return(Constants.DONUT_ERROR_DLL_FUNCTION); } } // If unmanaged DLL with params, need function if (config.mod_type == Constants.DONUT_MODULE_DLL && config.param != null) { if (config.method == null) { return(Constants.DONUT_ERROR_DLL_PARAM); } } } // If .NET DLL make sure Method and Class provided if (config.mod_type == Constants.DONUT_MODULE_NET_DLL) { if (config.cls == null || config.method == null) { return(Constants.DONUT_ERROR_NET_PARAMS); } } return(Constants.DONUT_ERROR_SUCCESS); }
public static int ParseInputFile(string file, ref DSFileInfo fi) { D.Print("Entering ParseInputFile()"); PeNet.PeFile PE; var extension = Path.GetExtension(file); D.Print($"File extension is: {extension}"); // If supplied file is a directory if (extension == null) { return(Constants.DONUT_ERROR_FILE_INVALID); } // Parse extension if (extension == ".vbs") { fi.type = Constants.DONUT_MODULE_VBS; fi.arch = Constants.DONUT_ARCH_ANY; } else if (extension == ".js") { fi.type = Constants.DONUT_MODULE_JS; fi.arch = Constants.DONUT_ARCH_ANY; } else if (extension == ".xsl") { fi.type = Constants.DONUT_MODULE_XSL; fi.arch = Constants.DONUT_ARCH_ANY; } else if (extension == ".exe") { fi.type = Constants.DONUT_MODULE_EXE; fi.arch = Constants.DONUT_ARCH_ANY; } else if (extension == ".dll") { fi.type = Constants.DONUT_MODULE_DLL; fi.arch = Constants.DONUT_ARCH_ANY; } else { return(Constants.DONUT_ERROR_FILE_INVALID); } // Do PE parsing for .dll and .exe if (fi.type == Constants.DONUT_MODULE_DLL || fi.type == Constants.DONUT_MODULE_EXE) { D.Print("Parsing PE file"); try { PE = new PeNet.PeFile(file); if (PE.ImageDosHeader == null) { return(Constants.DONUT_ERROR_FILE_INVALID); } if (PE.ImageNtHeaders == null) { return(Constants.DONUT_ERROR_FILE_INVALID); } } catch { return(Constants.DONUT_ERROR_FILE_INVALID); } // Check and Reset Arch if (PE.Is32Bit == true) { fi.arch = Constants.DONUT_ARCH_X86; } else { fi.arch = Constants.DONUT_ARCH_X64; } // Check .NET and Reset Type if (PE.HasValidComDescriptor == true) { D.Print("COM Descriptor found, .NET selected"); if (PE.IsDLL == true) { fi.type = Constants.DONUT_MODULE_NET_DLL; } else { fi.type = Constants.DONUT_MODULE_NET_EXE; } Copy(fi.ver, PE.MetaDataHdr.Version); D.Print($"Runtime found in Metadata Header: {String(fi.ver)}"); } else if (PE.ImageRelocationDirectory.Length == 0) { //Think this should be ok? return(Constants.DONUT_ERROR_NORELOC); } } return(Constants.DONUT_ERROR_SUCCESS); }
static void Main(string[] args) { //Cheesy way to generate a temp filename for our original DLL var tempName = Path.GetFileNameWithoutExtension(Path.GetTempFileName()); var orgDllPath = @""; var payloadPath = @"shellcode.bin"; var pragmaBuilder = ""; for (int i = 0; i < args.Length; i++) { if (args[i].ToLower().Equals("--dll") || args[i].ToLower().Equals("-dll")) { if (i + 1 < args.Length) { orgDllPath = Path.GetFullPath(args[i + 1]); } } if (args[i].ToLower().Equals("--payload") || args[i].ToLower().Equals("-payload")) { if (i + 1 < args.Length) { //Needed to filter filename input from powershell payloadPath = Path.GetFileName(args[i + 1]); } } } if (string.IsNullOrWhiteSpace(orgDllPath) || !File.Exists(orgDllPath)) { Console.WriteLine($"[!] Cannot locate DLL path, does it exists?"); Environment.Exit(0); } if (string.IsNullOrWhiteSpace(payloadPath)) { Console.WriteLine($"[!] shellcode filname/path is empty, bad input!"); Environment.Exit(0); } //Create an output directory to export stuff too string outPath = Directory.CreateDirectory("output_" + Path.GetFileNameWithoutExtension(orgDllPath)).FullName; Console.WriteLine($"[+] Reading exports from {orgDllPath}..."); //Read PeHeaders -> Exported Functions from provided DLL PeNet.PeFile dllPeHeaders = new PeNet.PeFile(orgDllPath); //Build up our linker redirects foreach (var exportedFunc in dllPeHeaders.ExportedFunctions) { pragmaBuilder += $"#pragma comment(linker, \"/export:{exportedFunc.Name}={tempName}.{exportedFunc.Name},@{exportedFunc.Ordinal}\")\n"; } Console.WriteLine($"[+] Redirected {dllPeHeaders.ExportedFunctions.Count()} function calls from { Path.GetFileName(orgDllPath)} to {tempName}.dll"); //Replace data in our template dllTemplate = dllTemplate.Replace("PRAGMA_COMMENTS", pragmaBuilder); dllTemplate = dllTemplate.Replace("PAYLOAD_PATH", payloadPath); Console.WriteLine($"[+] Exporting DLL C source to {outPath + @"\" + Path.GetFileNameWithoutExtension(orgDllPath)}_pragma.c"); File.WriteAllText($@"{outPath + @"\" + Path.GetFileNameWithoutExtension(orgDllPath)}_pragma.c", dllTemplate); File.WriteAllBytes(outPath + @"\" + tempName + ".dll", File.ReadAllBytes(orgDllPath)); }
public void IsDriver_GivenAPeFile_ReturnsDriverOrNot(string file, bool isDriver) { var peFile = new PeNet.PeFile(file); Assert.Equal(isDriver, peFile.IsDriver); }
public static System.Diagnostics.Process?StartLocalTrace(int bitWidth, ProcessLaunchSettings settings, PeNet.PeFile? targetPE = null, long testID = -1) { if (!File.Exists(GlobalConfig.GetSettingPath(CONSTANTS.PathKey.PinPath))) { GlobalConfig.InstallNewPin(); if (!File.Exists(GlobalConfig.GetSettingPath(CONSTANTS.PathKey.PinPath))) { Logging.RecordError($"Pin.exe path is not correctly configured (Settings->Files->Pin Executable)"); return(null); } } string pintool = bitWidth is 32 ? GlobalConfig.GetSettingPath(CONSTANTS.PathKey.PinToolPath32) : GlobalConfig.GetSettingPath(CONSTANTS.PathKey.PinToolPath64); if (File.Exists(pintool) is false) { Logging.RecordError("Valid pintool not found - installing"); GlobalConfig.InstallNewTools(); pintool = bitWidth is 32 ? GlobalConfig.GetSettingPath(CONSTANTS.PathKey.PinToolPath32) : GlobalConfig.GetSettingPath(CONSTANTS.PathKey.PinToolPath64); } if (!File.Exists(pintool)) { if (pintool is null) { Logging.RecordError($"Pintool path was not set"); } else { Logging.RecordError($"Pintool {pintool} path was not found"); } return(null); } if (!File.Exists(settings.BinaryPath)) { Logging.RecordError($"Target binary not available: {settings.BinaryPath}"); return(null); } try { if (targetPE is null) { targetPE = new PeNet.PeFile(settings.BinaryPath); if (targetPE is null) { Logging.RecordError($"Unable to parse PE file: {settings.BinaryPath}"); return(null); } } } catch (Exception e) { Logging.RecordException($"Unable to parse PE file: {settings.BinaryPath} - {e.Message}", e); return(null); } if (targetPE.IsDll) { return(StartLocalDLLTrace(pintool, settings, testID)); } else if (targetPE.IsExe) //'isexe' is true even for DLLs, so isdll has to be first { return(StartLocalEXETrace(pintool, settings, testID: testID)); } Logging.RecordError("Unable to trace non-EXE/DLL file"); return(null); }
public PhpDiagDialog(IServiceProvider provider, ServerManager server) : base(provider) { InitializeComponent(); var knownPhpVersions = new Dictionary <string, PhpVersion> { { "5.6", new PhpVersion("5.6", new DateTime(2018, 12, 31), new Version(11, 0)) }, { "7.0", new PhpVersion("7.0", new DateTime(2018, 12, 3), new Version(14, 0)) }, { "7.1", new PhpVersion("7.1", new DateTime(2019, 12, 1), new Version(14, 0)) }, { "7.2", new PhpVersion("7.2", new DateTime(2020, 11, 30), new Version(14, 11)) } }; var container = new CompositeDisposable(); FormClosed += (sender, args) => container.Dispose(); container.Add( Observable.FromEventPattern <EventArgs>(btnGenerate, "Click") .ObserveOn(System.Threading.SynchronizationContext.Current) .Subscribe(evt => { txtResult.Clear(); try { Warn("IMPORTANT: This report might contain confidential information. Mask such before sharing to others."); Warn("-----"); Debug($"System Time: {DateTime.Now}"); Debug($"Processor Architecture: {Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")}"); Debug($"OS: {Environment.OSVersion}"); Debug($"Server Type: {server.Mode.AsString(EnumFormat.Description)}"); Debug(string.Empty); var modules = new ModulesFeature((Module)provider); modules.Load(); Debug($"Scan {modules.Items.Count} installed module(s)."); if (modules.Items.All(item => item.Name != "FastCgiModule")) { Error($"FastCGI module is not installed as part of IIS. Please refer to https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php#13-download-and-install-php-manually for more details."); return; } else { Debug("FastCGI module is installed."); } Debug(string.Empty); var handlers = new HandlersFeature((Module)provider); handlers.Load(); var foundPhpHandler = new List <HandlersItem>(); Debug($"Scan {handlers.Items.Count} registered handler(s)."); foreach (var item in handlers.Items) { if (item.Modules == "FastCgiModule") { Debug($"* Found FastCGI handler as {{ Name: {item.Name}, Path: {item.Path}, State: {item.GetState(handlers.AccessPolicy)}, Handler: {item.TypeString}, Entry Type: {item.Flag} }}."); foundPhpHandler.Add(item); } } if (foundPhpHandler.Count == 0) { Error($"No FastCGI handler is registered for this web site."); Error($" * To run PHP on IIS, please refer to https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php#13-download-and-install-php-manually for more details."); Error($" * To run Python on IIS, please refer to https://pypi.org/project/wfastcgi/ or use HttpPlatformHandler https://docs.microsoft.com/en-us/iis/extensions/httpplatformhandler/httpplatformhandler-configuration-reference."); return; } Debug(string.Empty); var fastCgiFeature = new FastCgiFeature((Module)provider); fastCgiFeature.Load(); Debug($"Scan {fastCgiFeature.Items.Count} registered FastCGI application(s)."); var foundPhp = new List <FastCgiItem>(); foreach (var item in fastCgiFeature.Items) { var combination = string.IsNullOrWhiteSpace(item.Arguments) ? item.Path : item.Path + '|' + item.Arguments; foreach (var handler in foundPhpHandler) { if (string.Equals(combination, handler.ScriptProcessor, StringComparison.OrdinalIgnoreCase)) { Debug($"* Found FastCGI application registered as {{ Full path: {item.Path}, Arguments: {item.Arguments} }}."); foundPhp.Add(item); break; } } } if (foundPhp.Count == 0) { Error($"No suitable FastCGI appilcation is registered on this server."); Error($" * To run PHP on IIS, please refer to https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php#13-download-and-install-php-manually for more details."); Error($" * To run Python on IIS, please refer to https://pypi.org/project/wfastcgi/ or use HttpPlatformHandler https://docs.microsoft.com/en-us/iis/extensions/httpplatformhandler/httpplatformhandler-configuration-reference."); return; } Debug(Environment.NewLine); Debug($"Verify web stack installation versions."); foreach (var item in foundPhp) { var path = item.Path; if (path.TrimEnd('"').EndsWith("php-cgi.exe", StringComparison.OrdinalIgnoreCase)) { // PHP var info = FileVersionInfo.GetVersionInfo(path); var version = $"{info.FileMajorPart}.{info.FileMinorPart}"; if (knownPhpVersions.ContainsKey(version)) { var matched = knownPhpVersions[version]; if (matched.ExpiringDate <= DateTime.Now) { Error($"* PHP {info.FileVersion} ({path}) is unknown or obsolete. Please refer to http://php.net/supported-versions.php for more details."); } else if (matched.ExpiringDate > DateTime.Now && (matched.ExpiringDate - DateTime.Now).TotalDays < 180) { Warn($"* PHP {version} ({path}) will soon be obsolete. Please refer to http://php.net/supported-versions.php for more details."); } else { Debug($"* PHP {version} ({path}) is supported."); } var x86 = new PeNet.PeFile(path).Is32Bit; var cppFile = Path.Combine( Environment.GetFolderPath(x86 ? Environment.SpecialFolder.SystemX86 : Environment.SpecialFolder.System), $"msvcp{matched.CppVersion.Major}0.dll"); if (File.Exists(cppFile)) { var cpp = FileVersionInfo.GetVersionInfo(cppFile); if (cpp.FileMinorPart >= matched.CppVersion.Minor) { Debug($" Visual C++ runtime is detected (expected: {matched.CppVersion}, detected: {cpp.FileVersion})."); } else { Error($" Visual C++ runtime {matched.CppVersion} is not detected. Please install it following the tips on https://windows.php.net/download/."); } } else { Error($" Visual C++ {matched.CppVersion} runtime is not detected. Please install it following the tips on https://windows.php.net/download/."); } } else { Error($"* PHP {info.FileVersion} ({path}) is unknown or obsolete. Please refer to http://php.net/supported-versions.php for more details."); } } else if (path.TrimEnd('"').EndsWith("python.exe", StringComparison.OrdinalIgnoreCase)) { // Python } } Debug(string.Empty); var systemPath = Environment.GetEnvironmentVariable("Path"); Debug($"Windows Path environment variable: {systemPath}."); Debug(string.Empty); string[] paths = systemPath.Split(new char[1] { Path.PathSeparator }); foreach (var item in foundPhp) { var path = item.Path; if (path.TrimEnd('"').EndsWith("php-cgi.exe", StringComparison.OrdinalIgnoreCase)) { var rootFolder = Path.GetDirectoryName(path); Debug($"[{rootFolder}]"); if (!Directory.Exists(rootFolder)) { Error("Invalid root folder is found. Skip."); continue; } var config = Path.Combine(rootFolder, "php.ini"); if (File.Exists(config)) { Info($"Found PHP config file {config}."); var parser = new ConcatenateDuplicatedKeysIniDataParser(); parser.Configuration.ConcatenateSeparator = " "; var data = parser.Parse(File.ReadAllText(config)); var extensionFolder = data["PHP"]["extension_dir"]; if (extensionFolder == null) { extensionFolder = "ext"; } var fullPath = Path.Combine(rootFolder, extensionFolder); Info($"PHP loadable extension folder: {fullPath}"); var extesionNames = data["PHP"]["extension"]; if (extesionNames == null) { Info("No extension to verify."); } else { var extensions = extesionNames.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); Info($"Found {extensions.Length} extension(s) to verify."); var noError = true; foreach (var name in extensions) { var fileName = Path.Combine(fullPath, $"php_{name}.dll"); if (!File.Exists(fileName)) { Error($"* Extension {name} is listed, but on disk the file cannot be found {fileName}"); noError = false; } } if (noError) { Info("All extension(s) listed can be found on disk."); } } } else { Warn($"Cannot find PHP config file {config}. Default settings are used."); } var matched = false; foreach (var system in paths) { if (string.Equals(rootFolder, system, StringComparison.OrdinalIgnoreCase)) { matched = true; break; } } if (matched) { Debug($"PHP installation has been added to Windows Path environment variable."); } else { Error($"PHP installation is not yet added to Windows Path environment variable. Please refer to https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php#13-download-and-install-php-manually for more details."); Warn($"Restart Jexus Manager and rerun PHP Diagnostics after changing Windows Path environment variable."); } Debug(string.Empty); // TODO: verify other configuration in php.info. } else if (path.TrimEnd('"').EndsWith("python.exe", StringComparison.OrdinalIgnoreCase)) { } } } catch (Exception ex) { Debug(ex.ToString()); Rollbar.RollbarLocator.RollbarInstance.Error(ex); } })); container.Add( Observable.FromEventPattern <EventArgs>(btnSave, "Click") .ObserveOn(System.Threading.SynchronizationContext.Current) .Subscribe(evt => { var fileName = DialogHelper.ShowSaveFileDialog(null, "Text Files|*.txt|All Files|*.*"); if (string.IsNullOrEmpty(fileName)) { return; } File.WriteAllText(fileName, txtResult.Text); })); container.Add( Observable.FromEventPattern <EventArgs>(btnVerify, "Click") .ObserveOn(System.Threading.SynchronizationContext.Current) .Subscribe(evt => { txtResult.Clear(); })); }
public static MonoLibraryOffsets GetOffsets(string gameExecutableFilePath, bool force = true) { if (gameExecutableFilePath == null) { throw new ArgumentNullException("gameExecutableFilePath parameter cannot be null"); } string unityVersion; if (gameExecutableFilePath.EndsWith(".exe")) { var peHeader = new PeNet.PeFile(gameExecutableFilePath); unityVersion = peHeader.Resources.VsVersionInfo.StringFileInfo.StringTable[0].FileVersion; // Taken from here https://stackoverflow.com/questions/1001404/check-if-unmanaged-dll-is-32-bit-or-64-bit; // See http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx // Offset to PE header is always at 0x3C. // The PE header starts with "PE\0\0" = 0x50 0x45 0x00 0x00, // followed by a 2-byte machine type field (see the document above for the enum). FileStream fs = new FileStream(gameExecutableFilePath, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); fs.Seek(0x3c, SeekOrigin.Begin); int peOffset = br.ReadInt32(); fs.Seek(peOffset, SeekOrigin.Begin); uint peHead = br.ReadUInt32(); // "PE\0\0", little-endian if (peHead != 0x00004550) { throw new Exception("Can't find PE header"); } int machineType = br.ReadUInt16(); br.Close(); fs.Close(); Console.WriteLine($"Game executable file closed, unity version = {unityVersion}."); switch (machineType) { case 0x8664: // IMAGE_FILE_MACHINE_AMD64 return(GetOffsets(unityVersion, true, BinaryFormat.PE, force)); case 0x14c: // IMAGE_FILE_MACHINE_I386 return(GetOffsets(unityVersion, false, BinaryFormat.PE, force)); } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { FileInfo gameExecutableFile = new FileInfo(gameExecutableFilePath); string infoPlist = File.ReadAllText(gameExecutableFile.Directory.Parent.FullName + "/Info.plist"); string unityVersionField = "Unity Player version "; int indexOfUnityVersionField = infoPlist.IndexOf(unityVersionField); unityVersion = infoPlist.Substring(indexOfUnityVersionField + unityVersionField.Length).Split(' ')[0]; // Start the child process. Process p = new Process(); // Redirect the output stream of the child process. p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = "file"; p.StartInfo.Arguments = gameExecutableFile.FullName; p.Start(); // Do not wait for the child process to exit before // reading to the end of its redirected stream. // p.WaitForExit(); // Read the output stream first and then wait. string output = p.StandardOutput.ReadToEnd(); p.WaitForExit(); return(GetOffsets(unityVersion, output.EndsWith("x86_64\n"), BinaryFormat.MachO, force)); } throw new NotSupportedException("Platform not supported"); }