Skip to content

Commit

Permalink
remove core dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
xMiraiChan committed Jul 28, 2022
1 parent a8df81f commit cbbdbaf
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 27 deletions.
19 changes: 1 addition & 18 deletions AstralBypass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Reflection;
using System.Windows.Forms;

[assembly: MelonInfo(typeof(Astrum.AstralBypass), nameof(Astrum.AstralBypass), "0.2.0", downloadLink: "github.com/Astrum-Project/" + nameof(Astrum.AstralBypass))]
[assembly: MelonInfo(typeof(Astrum.AstralBypass), nameof(Astrum.AstralBypass), "0.2.1", downloadLink: "github.com/Astrum-Project/" + nameof(Astrum.AstralBypass))]
[assembly: MelonColor(ConsoleColor.DarkMagenta)]

namespace Astrum
Expand All @@ -19,23 +19,6 @@ public partial class AstralBypass : MelonPlugin

public override void OnApplicationEarlyStart()
{
if (!System.IO.File.Exists("UserData/.AstralBypass.nag.finished"))
{
Console.Beep();
MessageBox.Show( // if you are a paster, you can create that file inside your .zip folder to prevent this message
"AstralBypass is under attack from \"wholesome\" modders\n"
+ "The VRCMG is an oligarchy intent on restrict the freedom of modding\n"
+ "Please, urge your friends and mod developers to use BepInEx\n"
+ "BepInEx is a unbiased mod loader, better than MelonLoader\n"
+ "(this message will only appear once)",
"Important message from AstralBypass",
MessageBoxButtons.OK,
MessageBoxIcon.Stop
);

System.IO.File.Create("UserData/.AstralBypass.nag.finished");
}

HarmonyInstance.Patch(
typeof(Assembly).GetMethod(nameof(Assembly.Load), new Type[2] { typeof(byte[]), typeof(byte[]) }),
typeof(AstralBypass).GetMethod(nameof(AssemblyLoadPre), PrivateStatic).ToNewHarmonyMethod(),
Expand Down
11 changes: 7 additions & 4 deletions AstralBypass.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<RootNamespace>Astrum</RootNamespace>
<AssemblyName>AstralBypass</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<LangVersion>preview</LangVersion>
<LangVersion>preview</LangVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
Expand Down Expand Up @@ -39,9 +39,6 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\0Harmony.dll</HintPath>
</Reference>
<Reference Include="AstralCore">
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\VRChat\Mods\AstralCore.dll</HintPath>
</Reference>
<Reference Include="MelonLoader">
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\MelonLoader.dll</HintPath>
</Reference>
Expand All @@ -53,6 +50,8 @@
<ItemGroup>
<Compile Include="AstralBypass.cs" />
<Compile Include="IntegrityChecks.cs" />
<Compile Include="MemoryUtils.cs" />
<Compile Include="PatternScanner.cs" />
<Compile Include="PEBKACHelper.cs" />
</ItemGroup>
<ItemGroup>
Expand All @@ -62,4 +61,8 @@
<PropertyGroup>
<PostBuildEvent>COPY "$(TargetPath)" "C:\Program Files (x86)\Steam\steamapps\common\VRChat\Plugins\$(TargetFileName)"</PostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
</PropertyGroup>
</Project>
12 changes: 7 additions & 5 deletions IntegrityChecks.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma warning disable CS0618 // Type or member is obsolete

using MelonLoader;
using System;
using System.Collections.Generic;
Expand All @@ -14,17 +16,17 @@ static IntegrityChecks()
{
if (!versionSigs.TryGetValue((string)typeof(BuildInfo).GetField(nameof(BuildInfo.Version)).GetValue(null), out (string, int) data))
{
AstralCore.Logger.Warn("[AstralBypass] Missing signature for your version of MelonLoader");
MelonLogger.Warning("[AstralBypass] Missing signature for your version of MelonLoader");
return;
}

pIC = AstralCore.Utils.PatternScanner.Scan(
pIC = PatternScanner.Scan(
"bootstrap.dll",
data.Item1,
data.Item2
);

AstralCore.Logger.Debug("Integrity Check = 0x" + pIC.ToInt64().ToString("X"));
MelonLogger.Log("Integrity Check = 0x" + pIC.ToInt64().ToString("X"));
}

private static readonly Dictionary<string, (string, int)> versionSigs = new Dictionary<string, (string, int)>()
Expand Down Expand Up @@ -109,13 +111,13 @@ static IntegrityChecks()
public static void Bypass()
{
if (pIC == IntPtr.Zero) return;
AstralCore.Utils.MemoryUtils.WriteBytes(pIC, new byte[2] { 0x66, 0x90 });
MemoryUtils.WriteBytes(pIC, new byte[2] { 0x66, 0x90 });
}

public static void Repair()
{
if (pIC == IntPtr.Zero) return;
AstralCore.Utils.MemoryUtils.WriteBytes(pIC, new byte[2] { 0xFF, 0xD3 });
MemoryUtils.WriteBytes(pIC, new byte[2] { 0xFF, 0xD3 });
}
}
}
Expand Down
25 changes: 25 additions & 0 deletions MemoryUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Astrum
{
public static class MemoryUtils
{
const uint PAGE_EXECUTE_READWRITE = 0x40;

public static void WriteBytes(IntPtr address, byte[] bytes)
{
IntPtr process = Process.GetCurrentProcess().Handle;
VirtualProtectEx(process, address, (UIntPtr)bytes.Length, PAGE_EXECUTE_READWRITE, out uint oldProtect);
Marshal.Copy(bytes, 0, address, bytes.Length);
VirtualProtectEx(process, address, (UIntPtr)bytes.Length, oldProtect, out _);
}

[DllImport("kernel32.dll")] static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
}
}
71 changes: 71 additions & 0 deletions PatternScanner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Astrum
{
// writen by dom1n1k and Patrick
// converted to c# by atom0s [aka Wiccaan]
// adapted by Astral Astrum
// changes:
// works on 64 bit
// static instead of instance
// todo:
// cache result
public static class PatternScanner
{
private static bool MaskCheck(byte[] mem, int nOffset, string pattern)
{
for (int x = 0; x < pattern.Length / 2; x++)
{
string bite = pattern.Substring(x * 2, 2);
if (bite == "??") continue;
if (byte.Parse(bite, System.Globalization.NumberStyles.HexNumber) != mem[nOffset + x]) return false;
}

return true;
}

public static IntPtr Scan(string module, string pattern, int offset = 0)
{
Process process = Process.GetCurrentProcess();
IntPtr baseAddr = GetModuleHandle(module);

if (!GetModuleInformation(process.Handle, baseAddr, out MODULEINFO info, 24))
return IntPtr.Zero;

int size = (int)info.SizeOfImage;

pattern = pattern.Replace(" ", "");

try
{
if (baseAddr == IntPtr.Zero) return IntPtr.Zero;
if (size == 0) return IntPtr.Zero;

byte[] mem = new byte[size];

if (!ReadProcessMemory(process.Handle, baseAddr, mem, size, out int nBytesRead) || nBytesRead != size)
return IntPtr.Zero;

for (int x = 0; x < mem.Length; x++)
if (MaskCheck(mem, x, pattern))
return new IntPtr(baseAddr.ToInt64() + x + offset);

return IntPtr.Zero;
}
catch { return IntPtr.Zero; }
}

[DllImport("kernel32.dll", SetLastError = true)] private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out()] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("psapi.dll", SetLastError = true)] static extern bool GetModuleInformation(IntPtr hProcess, IntPtr hModule, out MODULEINFO lpmodinfo, uint cb);
[StructLayout(LayoutKind.Sequential)]
public struct MODULEINFO
{
public IntPtr lpBaseOfDll;
public uint SizeOfImage;
public IntPtr EntryPoint;
}
}
}

0 comments on commit cbbdbaf

Please sign in to comment.