Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions .github/workflows/patcher.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,32 @@ on:
branches: [ "v*", "master" ]
paths: [ "patcher/**/*" ]

env:
DOTNET_VERSION: 8.x

jobs:
build:
name: Build Patcher
runs-on: windows-latest
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Build Patcher
run: msbuild.exe patcher\HitmanPatcher.sln -t:Build -p:Configuration=Release -p:Platform=x64 -m
run: |
export DOTNET_NOLOGO=true
export DOTNET_CLI_TELEMETRY_OPTOUT=true
cd patcher
dotnet publish HitmanPatcher/HitmanPatcher.csproj -c Release -p DebugType=none -o Publish/Windows

- name: Upload Patcher Artifacts
- name: Upload patcher-windows
uses: actions/upload-artifact@v4
with:
name: patcher-windows
path: patcher/bin/x64/Release/PeacockPatcher.exe
path: patcher/Publish/Windows/ILRepack
58 changes: 52 additions & 6 deletions patcher/AOBScanner.cs → patcher/HitmanPatcher.Core/AOBScanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ public static bool TryGetHitmanVersionByScanning(Process process,
tasks =>
tasks.Select(task => task.Result)
.Where(x => x != null));

Task<IEnumerable<Patch[]>> getDynresEnablePatches =
Task.Factory.ContinueWhenAll(new Task<Patch[]>[]
{
findDynresEnable(exeData),
},
tasks =>
tasks.Select(task => task.Result)
.Where(x => x != null));


Task<IEnumerable<Patch[]>>[] alltasks =
Expand All @@ -76,11 +85,13 @@ public static bool TryGetHitmanVersionByScanning(Process process,
getProtocolPatches, getDynresForceofflinePatches
};
// ReSharper disable once CoVariantArrayConversion
Task.WaitAll(alltasks);
Task.WaitAll([..alltasks, getDynresEnablePatches]);

bench.Stop();
Console.WriteLine(bench.Elapsed.ToString());

#if DEBUG
Compositions.Logger.log(bench.Elapsed.ToString());
#endif

// error out if any task does not have exactly 1 result
if (alltasks.Any(task => task.Result.Count() != 1))
{
Expand All @@ -94,7 +105,8 @@ public static bool TryGetHitmanVersionByScanning(Process process,
Note("AuthHeader2", getAuthheadPatches.Result.First()[1]);
Note("ConfigDomain", getConfigdomainPatches.Result.First()[0]);
Note("Protocol", getProtocolPatches.Result.First()[0]);
Note("DynamicResources", getDynresForceofflinePatches.Result.First()[0]);
Note("DynamicResources->ForceOffline", getDynresForceofflinePatches.Result.First()[0]);
Comment thread
LennardF1989 marked this conversation as resolved.
Note("DynamicResources->Enable", getDynresEnablePatches.Result.FirstOrDefault()?[0]);
#endif

result = new HitmanVersion()
Expand All @@ -104,7 +116,9 @@ public static bool TryGetHitmanVersionByScanning(Process process,
configdomain = getConfigdomainPatches.Result.First(),
protocol = getProtocolPatches.Result.First(),
dynres_noforceoffline =
getDynresForceofflinePatches.Result.First()
getDynresForceofflinePatches.Result.First(),
dynres_enable =
getDynresEnablePatches.Result.FirstOrDefault() ?? []
};

return true;
Expand All @@ -115,7 +129,14 @@ public static bool TryGetHitmanVersionByScanning(Process process,
#if DEBUG
private static void Note(string name, Patch patch)
{
MainForm.GetInstance().log($"{name}: {patch.offset:X} {BitConverter.ToString(patch.original).Replace("-", string.Empty)} {BitConverter.ToString(patch.patch).Replace("-", string.Empty)}");
if (patch == null)
{
Compositions.Logger.log($"{name}: n/a");

return;
}

Compositions.Logger.log($"{name}: {patch.offset:X} {BitConverter.ToString(patch.original).Replace("-", string.Empty)} {BitConverter.ToString(patch.patch).Replace("-", string.Empty)}");
}
#endif

Expand Down Expand Up @@ -526,6 +547,31 @@ private static Task<Patch[]> findDynresForceoffline(byte[] data)

#endregion

#region dynres_enable

private static Task<Patch[]> findDynresEnable(byte[] data)
{
return Task.Factory.ContinueWhenAll(new[]
{
Task.Factory.StartNew(() => findPattern(data, 0x4, "ba502e23f1488d0d")) // 3.210
.ContinueWith(task =>
task.Result.Select(addr => addr + 0x22 + BitConverter.ToInt32(data, addr + 0x1A)).ToArray()),
}, tasks =>
{
IEnumerable<int> offsets =
tasks.SelectMany(task => task.Result);
if (offsets.Count() != 1)
return null;
return new[]
{
new Patch(offsets.First(), "01", "00",
MemProtection.PAGE_EXECUTE_READWRITE)
};
});
}

#endregion

private static int[] findPattern(byte[] data, byte alignment,
string pattern)
{
Expand Down
9 changes: 9 additions & 0 deletions patcher/HitmanPatcher.Core/Compositions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace HitmanPatcher
{
public static class Compositions
{
public static bool HasAdmin { get; set; }

public static ILoggingProvider Logger { get; set; }
}
}
23 changes: 23 additions & 0 deletions patcher/HitmanPatcher.Core/HitmanPatcher.Core.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net46</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>

<PlatformTarget>x64</PlatformTarget>
<Prefer32bit>true</Prefer32bit>

<RootNamespace>HitmanPatcher</RootNamespace>
<AssemblyName>PeacockPatcher.Core</AssemblyName>

<LangVersion>latest</LangVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>TRACE;PLATFORM_STEAM;PLATFORM_EPIC;PLATFORM_GOG;PLATFORM_SCARLETT</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>TRACE;PLATFORM_STEAM;PLATFORM_EPIC</DefineConstants>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public Patch(int offset, string original, string patch, MemProtection defaultPro

public class HitmanVersion
{
public Patch[] certpin, authheader, configdomain, protocol, dynres_noforceoffline;
public Patch[] certpin, authheader, configdomain, protocol, dynres_noforceoffline, dynres_enable;

private static Dictionary<uint, string> timestampMap = new Dictionary<uint, string>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public static void PatchAllProcesses(ILoggingProvider logger, Options patchOptio
}
catch (Win32Exception ex)
{
if (ex.NativeErrorCode == 5 && !Program.HasAdmin)
if (ex.NativeErrorCode == 5 && !Compositions.HasAdmin)
{
logger.log(String.Format("Access denied, try running the patcher as admin."));
process.Dispose();
Expand Down Expand Up @@ -184,6 +184,10 @@ public static bool Patch(Process process, Options patchOptions)
{
patches.AddRange(v.protocol);
}
if (patchOptions.EnableDynamicResources)
{
patches.AddRange(v.dynres_enable);
}
if (patchOptions.DisableForceOfflineOnFailedDynamicResources)
{
patches.AddRange(v.dynres_noforceoffline);
Expand Down Expand Up @@ -275,6 +279,7 @@ public struct Options
public bool SetCustomConfigDomain;
public string CustomConfigDomain;
public bool UseHttp;
public bool EnableDynamicResources;
public bool DisableForceOfflineOnFailedDynamicResources;
}

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public Settings()
DisableCertPinning = true,
AlwaysSendAuthHeader = true,
SetCustomConfigDomain = true,
EnableDynamicResources = true,
DisableForceOfflineOnFailedDynamicResources = true,
};
darkModeEnabled = false;
Expand Down
177 changes: 0 additions & 177 deletions patcher/HitmanPatcher.csproj

This file was deleted.

Loading