Skip to content

Commit

Permalink
Optimization + New Features
Browse files Browse the repository at this point in the history
- CMVS64 Support Added
- Trimmed Match Feature Added
- x64 Trampoline don't affect any Register
- x64 Hook Code Move Algorithm Improved
- Explicity Added FromAsian in the SRL.ini
  • Loading branch information
marcussacana committed Aug 28, 2020
1 parent a07d975 commit 13ab90b
Show file tree
Hide file tree
Showing 29 changed files with 517 additions and 293 deletions.
12 changes: 8 additions & 4 deletions README.MD
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# StringsReloads v7.1
# StringsReloads v7.2
[![Build Status](https://ci.appveyor.com/api/projects/status/github/marcussacana/StringReloads?branch=master&retina=true)](https://ci.appveyor.com/project/marcussacana/StringReloads)


Expand All @@ -12,7 +12,7 @@ This is a tool created to inject strings using low level code


---
Our strategy to inject the string is create a new section using tools like the Stud_PE or CFF Explorer to have space in the executable to append the new code, a commom method is replace a original command and jump to your code, generally a jump have 5 bytes of length, sometimes you need replace more than one command and don't forget to place original commands like CMP and TEST after the execution of your code, of course, if have one.
Our strategy to inject the string is create a new section using tools like the Stud_PE or CFF Explorer to have space in the executable to append the new code, a commom method is replace a original instruction and jump to your code, generally a jump have 5 bytes of length, sometimes you need replace more than one instruction and don't forget to place original instructions like CMP and TEST after the execution of your code, of course, if have one.

### Sample Call Algorithm:
```Assembly
Expand Down Expand Up @@ -74,13 +74,17 @@ After some problems with games that reload string inside a loop I created the Ge
dd 0 ;Here is the @Nxt: + 0x21
```
You don't give pass nothing to this method, just call and catch the EAX, the EAX is a pointer to the Process function, using this pointer will be more fast to call the function, Keep in mind, the pointer given by the GetDirectProcess
You don't give nothing to this method, just call and catch the EAX, the EAX is a pointer to the Process function, using this pointer will be more fast to call the function, Keep in mind, the pointer given by the GetDirectProcess

---

### Auto-Install Feature:
The SRL have a feature to automatically install the SRL in the game engine without you need know how to patch the game, just rename the SRLx32.dll to d3d9.dll; dinput8.dll or any other supported wrapper [See Here what is supported](https://github.com/marcussacana/StringReloads/tree/master/SRLWrapper/Wrapper), then in the SRL.ini set the AutoInstall to true.
*Currently only the AdvHD and SoftPal engine is supported by this feature.*

#### Supported By:
- AdvHD
- SoftPal
- CMVS32 and CMVS64

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
180 changes: 180 additions & 0 deletions StringReloads/AutoInstall/CMVS.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using StringReloads.Engine;
using StringReloads.Engine.Interface;
using StringReloads.Engine.Unmanaged;
using StringReloads.Hook.Others;

namespace StringReloads.AutoInstall
{
/*
How to found the GetStr Function Manually
1 - Find for the function that call the ShellExecuteA
2 - Scroll up (Ignore the Indirect Call)
3 - You will found 3 calls of a same function, this function is our GetStr
*/
unsafe class CMVS : IAutoInstall
{
ulong? Offset = null;
CMVS_GetText Hook;

public CMVS()
{
var CFG = Config.Default.GetValues("CMVS");
if (CFG == null)
return;

var Size = CFG["filesize"].ToInt64();

if (Size != new FileInfo(Config.Default.GameExePath).Length)
return;

Offset = CFG["offset"].ToUInt64();
}

public string Name => $"CMVS{(Environment.Is64BitProcess ? 64 : 32)}";

public void Install()
{
if (Offset == null)
{
SearchOffset();

if (Offset == null)
return;

EnsureMultiArch();

var Dic = new Dictionary<string, string>();
Dic["FileSize"] = new FileInfo(Config.Default.GameExePath).Length.ToString();
Dic["Offset"] = Offset.Value.ToString();

Config.Default.SetValues("CMVS", Dic);
Config.Default.SaveSettings();
}

if (Hook == null)
Hook = new CMVS_GetText((void*)((ulong)Config.Default.GameBaseAddress + Offset.Value));

Hook.Install();
}

private void EnsureMultiArch()
{
if (EntryPoint.CurrentDll.GetFilename().ToLowerInvariant().StartsWith("srlx"))
return;

Log.Debug("CMVS Multiarch Patch Not Applied.");

var CurrentExe = Config.Default.GameExePath;
var AltExe = Path.Combine(Path.GetDirectoryName(Config.Default.GameExePath), Environment.Is64BitProcess ? "cmvs32.exe" : "cmvs64.exe");

var CurrentSRL = Environment.Is64BitProcess ? "SRLx64.dll" : "SRLx32.dll";
var AltSRL = Environment.Is64BitProcess ? "SRLx32.dll" : "SRLx64.dll";

if (!File.Exists(AltExe))
Log.Warning($"Failed to Find the {Path.GetFileName(AltExe)}.");

bool AltSRLAvailable = File.Exists(Path.Combine(Path.GetDirectoryName(CurrentExe), AltSRL));

if (!AltSRLAvailable)
Log.Warning($"Failed to Find the {AltSRL}.");
else
Patcher.Tools.ThirdPartyApplyPatch(AltExe, AltSRL);

Patcher.Tools.ApplyWrapperPatch(CurrentSRL);
}

byte?[][] Patterns => new[] {
//x64
new byte?[] {
0x4C, null, null, //mov ???, ???
0x25, 0x00, 0x00, 0x00, 0xC0, //and eax, 0xC0000000
0x74, null, //je ??
0x3D, 0x00, 0x00, 0x00, 0x40, //cmp eax, 0x40000000
0x74, null //je ??
},
//x32
new byte?[] {
0x25, 0x00, 0x00, 0x00, 0xC0, //and eax, 0xC0000000
0x3D, 0x00, 0x00, 0x00, 0x80, //cmp eax, 0x80000000
0x77, null, //ja ??
0x74, null //je ??
}
};

void SearchOffset()
{
byte* Address = null;
foreach (var Pattern in Patterns)
{
if (Scan(out Address, Pattern))
break;
Address = null;
}

if (Address == null)
{
Log.Error("Failed to find the Game injection point");
return;
}

uint[] Prefixes = new uint[] { 0x4CC28BCC, 0xEC8B55CC };

while (!Prefixes.Contains((*(uint*)Address)))
Address--;

Address++;//Skip int3

Offset = ((ulong)Address) - (ulong)Config.Default.GameBaseAddress;
Log.Debug($"CMVS Injection Offset Found: 0x{Offset:X16}");
}

private bool Scan(out byte* Address, byte?[] Pattern)
{
var Info = ModuleInfo.GetCodeInfo((byte*)Config.Default.GameBaseAddress);

Address = null;
long CodeAdd = (long)Info.CodeAddress;
long CodeLen = Info.CodeSize - Pattern.Length;
for (int i = 0; i < CodeLen; i++)
{
byte* pBuffer = (byte*)(Info.CodeAddress) + i;
if (!CheckPattern(pBuffer, Pattern))
continue;
Log.Debug($"CMVS Pattern Found At: 0x{(ulong)pBuffer:X16}");
for (long x = (long)pBuffer; x > CodeAdd; x--)
{
byte* pFunc = (byte*)x;
if (!CheckPattern(pFunc, Pattern))
continue;
Address = pFunc;
return true;
}
}
return false;
}

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");

public void Uninstall()
{
Hook?.Uninstall();
}
}
}
124 changes: 0 additions & 124 deletions StringReloads/AutoInstall/CMVS32.cs

This file was deleted.

Loading

0 comments on commit 13ab90b

Please sign in to comment.