private static void LoadMods() { // Check for Known DRM and Workarounds. var basicPeParser = new BasicPeParser(Environment.CurrentProcessLocation.Value); var drmTypes = DRMHelper.CheckDrmAndNotify(basicPeParser, _loader.Logger, out bool requiresDelayStart); // Note: If loaded externally, we assume another mod loader or DLL override took care of bypassing DRM. bool loadedFromExternalSource = (_parameters.Flags & EntryPointFlags.LoadedExternally) != 0; if (loadedFromExternalSource) { Logger?.LogWriteLineAsync($"Note: Reloaded is being loaded from an external source or mod loader.", Logger.ColorInformation); } if (!requiresDelayStart || loadedFromExternalSource) { _loader.LoadForCurrentProcess(); } else { Logger?.LogWriteLineAsync($"DRM Requiring Delayed Initialization ({drmTypes}) Found.\n" + $"Reloaded will try to initialize late to bypass this DRM.\n" + $"Please note this feature is experimental.\n" + $"If you encounter issues, report and/or try ASI Loader `Edit Application -> Deploy ASI Loader`", Logger.ColorWarning); _delayInjector = new DelayInjector(() => { Logger?.LogWriteLineAsync($"Loading via Delayed Injection (DRM Workaround)", Logger.ColorInformation); _loader.LoadForCurrentProcess(); }, _loader.Logger); } }
/// <summary> /// Checks if the ASI loader can be deployed. /// </summary> public bool CanDeploy() { if (!File.Exists(Application.Config.AppLocation)) { return(false); } using var peParser = new BasicPeParser(Application.Config.AppLocation); return(GetFirstDllFile(peParser) != null); }
/// <summary> /// Get name of first DLL file using which ASI loader can be installed. /// </summary> /// <param name="peParser">Parsed PE file.</param> private string?GetFirstSupportedDllFile(BasicPeParser peParser) { string?GetSupportedDll(BasicPeParser file, string[] supportedDlls) { var names = file.GetImportDescriptorNames(); return(names.FirstOrDefault(x => supportedDlls.Contains(x, StringComparer.OrdinalIgnoreCase))); } return(GetSupportedDll(peParser, peParser.Is32BitHeader ? AsiLoaderSupportedDll32 : AsiLoaderSupportedDll64)); }
public void CanParsePEFile_32() { using var parser = new BasicPeParser("HelloWorld32.exe"); Assert.True(parser.Is32BitHeader); Assert.Equal(5, parser.ImageSectionHeaders.Length); Assert.Equal(8, parser.ImportDescriptors.Length); Assert.Equal(16, parser.DataDirectories.Length); Assert.Equal(0x14C, parser.FileHeader.Machine); Assert.Equal(5, parser.FileHeader.NumberOfSections); Assert.Equal("KERNEL32.DLL", parser.GetImportDescriptorNames().Last(), StringComparer.OrdinalIgnoreCase); }
/// <summary> /// Deploys the ASI loader to the game folder. /// </summary> public void DeployAsiLoader(out string loaderPath, out string bootstrapperPath) { loaderPath = null; DeployBootstrapper(out bool loaderAlreadyInstalled, out bootstrapperPath); if (loaderAlreadyInstalled) { return; } using var peParser = new BasicPeParser(Application.Config.AppLocation); var appDirectory = Path.GetDirectoryName(Application.Config.AppLocation); var dllName = GetFirstDllFile(peParser); loaderPath = Path.Combine(appDirectory, dllName); ExtractAsiLoader(loaderPath, !peParser.Is32BitHeader); }
/// <summary> /// Deploys the ASI loader (if needed) and bootstrapper to the game folder. /// </summary> public void DeployAsiLoader(out string?asiLoaderPath, out string bootstrapperPath) { asiLoaderPath = null; DeployBootstrapper(out bool alreadyHasAsiPlugins, out bootstrapperPath); if (alreadyHasAsiPlugins) { return; } var appLocation = ApplicationConfig.GetAbsoluteAppLocation(Application); using var peParser = new BasicPeParser(appLocation); var appDirectory = Path.GetDirectoryName(appLocation); var dllName = GetFirstSupportedDllFile(peParser); asiLoaderPath = Path.Combine(appDirectory !, dllName !); ExtractAsiLoader(asiLoaderPath, !peParser.Is32BitHeader); }
public static DrmType CheckDrmAndNotify(BasicPeParser parser, Logger logger, out bool requiresDelayStart) { var drmType = DrmType.None; requiresDelayStart = false; if (SteamStubScanner.HasSteamStub(parser)) { logger?.WriteLineAsync("Warning: Steam Stub (Embedded Steam DRM) found.\n" + "This means EXE is encrypted at launch. Support for bypassing this DRM is experimental.\n" + "If you find issues, remove the DRM using `Steamless` or try using ASI Loader `Edit Application -> Deploy ASI Loader`", logger.ColorWarning); requiresDelayStart = true; drmType |= DrmType.SteamStub; } return(drmType); }
/// <summary> /// Checks if the ASI loader can be deployed. /// </summary> public bool CanDeploy() { var appLocation = ApplicationConfig.GetAbsoluteAppLocation(Application); if (!File.Exists(appLocation)) { return(false); } using var peParser = new BasicPeParser(appLocation); try { return(GetFirstSupportedDllFile(peParser) != null); } catch (Exception) { return(false); } }
private static unsafe void PerformPeOperations() { _basicPeParser = new BasicPeParser(Environment.CurrentProcessLocation.Value); // Check for Steam DRM. DRMNotifier.PrintWarnings(_basicPeParser, _loader.Logger); // Hook native import for ExitProcess. (So we can save log on exit) var kernel32 = Kernel32.GetModuleHandle("kernel32.dll"); var address = Kernel32.GetProcAddress(kernel32, "ExitProcess"); if (address != IntPtr.Zero) { _exitProcessHook = new Hook <ExitProcess>(ExitProcessImpl, (long)address).Activate(); } // Hook Console Close if (_loader.Console != null) { _loader.Console.OnConsoleClose += SaveAndFlushLog; } }
/// <summary> /// True if executable is 64bit, else false. /// </summary> /// <param name="filePath">Path of the EXE file.</param> public bool Is64Bit(string filePath) { using var parser = new BasicPeParser(filePath); return(!parser.Is32BitHeader); }
/// <summary> /// Returns true if Steam Stub DRM was found. /// </summary> public static unsafe bool HasSteamStub(BasicPeParser parser) { return(parser.ImageSectionHeaders.Any(x => x.Name.ToString() == SteamBindSection)); }
/// <summary> /// Returns true if Steam Stub DRM was found. /// </summary> public static unsafe bool HasSteamStub(Stream stream, bool isMapped) { using var parser = new BasicPeParser(stream, isMapped); return(HasSteamStub(parser)); }