Skip to content

Commit

Permalink
Add FVP Support
Browse files Browse the repository at this point in the history
  • Loading branch information
marcussacana committed Aug 11, 2024
1 parent 3a4610e commit 34ed334
Show file tree
Hide file tree
Showing 13 changed files with 271 additions and 120 deletions.
1 change: 1 addition & 0 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ First, dowload the SRL [HERE](https://github.com/marcussacana/StringReloads/rele
- CMVS32 and CMVS64
- ExHIBIT
- EntisGLS
- Favorite (FVP)

Some SoftPal games needs a manual setup with the help of the Auto-Installer, click below to see the example:
[![SRL SoftPal Auto-Install Feature](http://img.youtube.com/vi/RAgZQBWqiJQ/0.jpg)](http://www.youtube.com/watch?v=RAgZQBWqiJQ "SRL SoftPal Auto-Install Feature")
Expand Down
8 changes: 4 additions & 4 deletions SRLNative/SRLNative.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
Expand Down
130 changes: 20 additions & 110 deletions StringReloads/AutoInstall/CMVS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using Iced.Intel;
using StringReloads.Engine;
using StringReloads.Engine.Interface;
using StringReloads.Engine.Unmanaged;
using StringReloads.Hook.Base;
using StringReloads.Hook.Others;
using StringReloads.Tools;

namespace StringReloads.AutoInstall
{
Expand Down Expand Up @@ -95,51 +97,35 @@ private void EnsureMultiArch()
if (!AltSRLAvailable)
Log.Warning($"Failed to Find the {AltSRL}.");
else
Patcher.Tools.ThirdPartyApplyPatch(AltExe, AltSRL);
Patcher.ExeTools.ThirdPartyApplyPatch(AltExe, AltSRL);

Patcher.Tools.ApplyWrapperPatch(CurrentSRL);
Patcher.ExeTools.ApplyWrapperPatch(CurrentSRL);
}

void SearchOffset()
{
var Imports = ModuleInfo.GetModuleImports((byte*)Config.GameBaseAddress);
var ShellExec = Imports.Where(x => x.Function == "ShellExecuteA").Single();

var Bitness = Environment.Is64BitProcess ? 64 : 32;

ulong? Address = null;
byte?[] Pattern = new byte?[] { 0xFF, 0x15 };
foreach (var lAddress in Scan(Pattern))
var Bitness = Environment.Is64BitProcess ? 64 : 32;
foreach (var lAddress in Scanner.SearchExportCall("ShellExecuteA"))
{
Decoder Dissassembler = Decoder.Create(Bitness, new MemoryCodeReader((byte*)lAddress));
Dissassembler.IP = (ulong)lAddress;
var Call = Dissassembler.PeekDecode();
var MemAddress = Call.IPRelativeMemoryAddress;
//if (Environment.Is64BitProcess)
// MemAddress = Call.IPRelativeMemoryAddress + (ulong)lAddress + 6ul;

if (MemAddress == (ulong)ShellExec.ImportAddress)
var Pattern = new byte?[] { 0xE8 };
foreach (var lgetTextAddress in Scanner.Scan(Pattern, (ulong)lAddress, true))
{
Log.Debug($"Call dword ptr ds: [&ShellExecuteA] - Found at 0x{lAddress:X16}");
Pattern = new byte?[] { 0xE8 };
foreach (var lgetTextAddress in Scan(Pattern, (ulong)lAddress, true))
var Dissassembler = Decoder.Create(Bitness, new MemoryCodeReader((byte*)lgetTextAddress));
Dissassembler.IP = (ulong)lgetTextAddress;
var Call = Dissassembler.PeekDecode();

var Immediate = Environment.Is64BitProcess ? Call.MemoryDisplacement64 : Call.MemoryDisplacement32;

if (Address != Immediate)
{
Dissassembler = Decoder.Create(Bitness, new MemoryCodeReader((byte*)lgetTextAddress));
Dissassembler.IP = (ulong)lgetTextAddress;
Call = Dissassembler.PeekDecode();

var Immediate = Environment.Is64BitProcess ? Call.MemoryDisplacement64 : Call.MemoryDisplacement32;

if (Address != Immediate)
{
Address = Immediate;
continue;
}
else
break;
Address = Immediate;
continue;
}
break;
else
break;
}
break;
}

if (Address == null)
Expand All @@ -152,82 +138,6 @@ void SearchOffset()
Log.Debug($"CMVS Injection Offset Found: 0x{Offset:X16}");
}

private IEnumerable<long> Scan(byte?[] Pattern, ulong? BeginAddress = null, bool Up = false)
{
ulong? Match = BeginAddress;
do
{
if (Match != null) {

if (Up)
Match--;
else
Match++;

}

Match = Up ? ScanUp(Pattern, Match ?? ulong.MaxValue) : ScanDown(Pattern, Match ?? 0ul);

if (Match != null)
yield return (long)Match;

} while (Match != null);
}

private unsafe ulong? ScanUp(byte?[] Pattern, ulong BeginAddress = ulong.MaxValue)
{
var Info = ModuleInfo.GetCodeInfo((byte*)Config.GameBaseAddress);

if (BeginAddress == ulong.MaxValue)
BeginAddress = (ulong)Info.CodeAddress + Info.CodeSize;

ulong CodeAdd = (ulong)Info.CodeAddress;
for (ulong i = BeginAddress - CodeAdd; i >= 0; i--)
{
byte* pAddress = (byte*)(CodeAdd + i);
if (!CheckPattern(pAddress, Pattern))
continue;

return (ulong)pAddress;
}

return null;
}

private unsafe ulong? ScanDown(byte?[] Pattern, ulong BeginAddress = 0)
{
var Info = ModuleInfo.GetCodeInfo((byte*)Config.GameBaseAddress);

ulong CodeAdd = (ulong)Info.CodeAddress;
ulong CodeLen = Info.CodeSize;

if (BeginAddress != 0)
BeginAddress = BeginAddress - CodeAdd;

for (ulong i = BeginAddress; i < CodeLen; i++)
{
byte* pAddress = (byte*)(CodeAdd + i);
if (!CheckPattern(pAddress, Pattern))
continue;

return (ulong)pAddress;
}

return null;
}

private bool CheckPattern(byte* Buffer, byte?[] Pattern)
{
for (int i = 0; i < Pattern.Length; i++)
{
if (Pattern[i] == null)
continue;
byte bPattern = Pattern[i].Value;
if (bPattern != Buffer[i])
return false;
}
return true;
}

public bool IsCompatible() => Config.Default.GameExePath.GetFilenameNoExt().ToLowerInvariant().StartsWith("cmvs");

Expand Down
117 changes: 117 additions & 0 deletions StringReloads/AutoInstall/Favorite.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using Iced.Intel;
using StringReloads.Engine;
using StringReloads.Engine.Interface;
using StringReloads.Engine.String;
using StringReloads.Engine.Unmanaged;
using StringReloads.Hook;
using StringReloads.Hook.Base;
using StringReloads.Tools;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace StringReloads.AutoInstall
{
internal class Favorite : IAutoInstall
{
long Address = 0;
Register Register = Register.None;
Intercept Interceptor = null;

public string Name => "FavoriteViewPoint";

public void Install()
{
DetectHookConfig();
Interceptor.Install();
}
unsafe void DetectHookConfig()
{
var Settings = Config.Default.GetValues("Favorite");

if (Settings == null)
{
foreach (var Import in Scanner.SearchExportCall("lstrlenA"))
{
for (var i = 0; i < 10; i++)
{
var Addr = Import - i;
var Dissassembler = Decoder.Create(32, new MemoryCodeReader((byte*)Addr));
Dissassembler.IP = (ulong)Addr;
var Instruction = Dissassembler.PeekDecode();

switch (Instruction.Code)
{
case Code.Push_r32:
Register = Instruction.Op0Register;
break;
default:
continue;
}

Address = Import;
break;
}
}

Settings = new Dictionary<string, string>();
Settings["Address"] = Address.ToString();
Settings["Register"] = ((int)Register).ToString();
Config.Default.SetValues("Favorite", Settings);
Config.Default.SaveSettings();
}
else
{
Address = long.Parse(Settings["address"]);
Register = (Register)int.Parse(Settings["register"]);
}

Interceptor = new ManagedInterceptor((void*)Address, onIntercepted);
Log.Information($"Favorite Engine Intercepted at 0x{Address:X8}");
}

private unsafe void onIntercepted(ref ulong ESP, ref ulong EAX, ref ulong ECX, ref ulong EDX, ref ulong EBX, ref ulong EBP, ref ulong ESI, ref ulong EDI)
{
switch (Register)
{
case Register.EBX:
EBX = (ulong)EntryPoint.Process((void*)EBX);
EAX = (ulong)((CString)EBX).Count();
break;
case Register.ECX:
ECX = (ulong)EntryPoint.Process((void*)ECX);
EAX = (ulong)((CString)ECX).Count();
break;
case Register.EDX:
EDX = (ulong)EntryPoint.Process((void*)EDX);
EAX = (ulong)((CString)EDX).Count();
break;
case Register.EBP:
EBP = (ulong)EntryPoint.Process((void*)EBP);
EAX = (ulong)((CString)EBP).Count();
break;
case Register.ESI:
ESI = (ulong)EntryPoint.Process((void*)ESI);
EAX = (ulong)((CString)ESI).Count();
break;
case Register.EDI:
EDI = (ulong)EntryPoint.Process((void*)EDI);
EAX = (ulong)((CString)EDI).Count();
break;
}
}

public bool IsCompatible()
{
return Directory.GetFiles(".\\", "*.hcb").Any();
}

public void Uninstall()
{
Interceptor.Uninstall();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace StringReloads.AutoInstall.Patcher
{
static class Tools
static class ExeTools
{
static readonly string[] SupportedWrappers = new string[] {
"version.dll", "d3d9.dll", "d3d10.dll", "d3d11.dll",
Expand Down
6 changes: 3 additions & 3 deletions StringReloads/AutoInstall/SoftPalMethodA.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public bool IsCompatible()
}
}

Tools.ApplyWrapperPatch();
ExeTools.ApplyWrapperPatch();
SetupMode = true;
}

Expand Down Expand Up @@ -289,11 +289,11 @@ private void FinishSetup() {
Config.SaveSettings();

ShowMessageBox($"Perfect! SRL is now ready to use! Enjoy!", "StringReloads", MBButtons.Ok, MBIcon.Information);
Tools.Restart();
ExeTools.Restart();
}
private void SetupFailed() {
ShowMessageBox("Hmm, looks like SRL can't perform Auto-Install in this game at the moment. Please report an issue in the GitHub repository.", "StringReloads Setup Wizard", MBButtons.Ok, MBIcon.Error);
Tools.Restart();
ExeTools.Restart();
}
}
}
2 changes: 1 addition & 1 deletion StringReloads/AutoInstall/SoftPalMethodB.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public bool IsCompatible()
SoftPal_DrawText.AltName = true;
}

Tools.ApplyWrapperPatch();
ExeTools.ApplyWrapperPatch();
Hook = new SoftPal_DrawText();
return true;
}
Expand Down
3 changes: 2 additions & 1 deletion StringReloads/Engine/SRL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ where typeof(IPlugin).IsAssignableFrom(Typ) && !Typ.IsInterface
new SoftPalMethodA(),
new SoftPalMethodB(),
new CMVS(),
new EntisGLS()
new EntisGLS(),
new Favorite()
};

internal IEncoding[] Encodings = new IEncoding[0];
Expand Down
2 changes: 2 additions & 0 deletions StringReloads/Engine/String/CString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ private CString(byte* Ptr) : base(Ptr) { }
public Encoding WriteEncoding = Config.Default.WriteEncoding;

public static implicit operator CString(byte* Ptr) => new CString(Ptr);
public static implicit operator CString(long Ptr) => new CString((byte*)Ptr);
public static implicit operator CString(ulong Ptr) => new CString((byte*)Ptr);
public static implicit operator CString(void* Ptr) => new CString((byte*)Ptr);
public static implicit operator CString(IntPtr Ptr) => new CString((byte*)Ptr.ToPointer());

Expand Down
2 changes: 2 additions & 0 deletions StringReloads/Engine/String/WCString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public unsafe class WCString : StringBufferW
private WCString(byte* Ptr) : base(Ptr) { }

public static implicit operator WCString(byte* Ptr) => new WCString(Ptr);
public static implicit operator WCString(long Ptr) => new WCString((byte*)Ptr);
public static implicit operator WCString(ulong Ptr) => new WCString((byte*)Ptr);
public static implicit operator WCString(void* Ptr) => new WCString((byte*)Ptr);
public static implicit operator WCString(IntPtr Ptr) => new WCString((byte*)Ptr.ToPointer());

Expand Down
Loading

0 comments on commit 34ed334

Please sign in to comment.