Skip to content

Commit

Permalink
ER 1.15 support
Browse files Browse the repository at this point in the history
  • Loading branch information
vswarte committed Oct 2, 2024
1 parent 1003776 commit 140bb25
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 67 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ log = "0.4.1"
serde = { version = "1.0.160", features = ["derive"]}
toml = "0.7.2"
broadsword = { git = "https://github.com/vswarte/broadsword.git" }
region = "3.0.2"

[dependencies.windows]
version = "0.48.0"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ for loading DLLs. Make sure to back up your save games because if this mod loads
vanilla save file first.

This mod has been extensively tested with [ModEngine2](https://github.com/soulsmods/ModEngine2). And somewhat with
TechieW's Elden Mod Loader.
~~TechieW's Elden Mod Loader.~~ Do not use Elden Mod loader to load this. It will be flaky and not work at times. I will offer no support for this combination.

#### How do I back up my save files?
You can find your save files in the folder `%appdata%/EldenRing/<steam ID>`. Making a copy of that folder should suffice.
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use broadsword::{dll, runtime, scanner};

#[dll::entrypoint]
pub fn entry(_: usize) -> bool {
broadsword::logging::init("alt-saves.log");
file::hook();
regulation::hook();
true
Expand Down
77 changes: 11 additions & 66 deletions src/regulation.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,9 @@
use std::mem::transmute;
use region::Protection;
use retour::static_detour;

Check warning on line 2 in src/regulation.rs

View workflow job for this annotation

GitHub Actions / Cargo build

unused import: `retour::static_detour`
use std::mem::transmute;

Check warning on line 3 in src/regulation.rs

View workflow job for this annotation

GitHub Actions / Cargo build

unused import: `std::mem::transmute`

use crate::match_instruction_pattern;

static_detour! {
static REGULATIONMANAGER_CONSTRUCTOR: unsafe extern "system" fn(u64, u64) -> u64;
}

const REGULATIONMANAGER_CONSTRUCTOR_PATTERN: &str = concat!(
// MOV qword ptr [RPS+0x8], RCX
"01001... 10001001 01001100 ..100100 00001000",
// PUSH RBX
"01010011",
// PUSH RSI
"01010110",
// PUSH RDI
"01010111",
// SUB RSP, 0x30
"01001... 10000011 11101100 00110000",
// MOV qword ptr [RSP+0x20], -0x2
"01001... 11000111 01000100 ..100100 00100000 11111110 11111111 11111111 11111111",
// MOV RBX, RCX
"01001... 10001011 11011001",
// LEA RAX, <CSRegulationManagerImp::vftable>
"01001... 10001101 00000101 ........ ........ ........ ........",
// MOV qword ptr [RCX], RAX
"01001... 10001001 00000001",
// MOV qword ptr [RCX+0x8], RDX
"01001... 10001001 01010001 00001000",
// LEA RDI, [RCX+0x10]
"01001... 10001101 01111001 00010000",
// MOV qword ptr [RSP+0x60], RDI
"01001... 10001001 01111100 ..100100 01100000",
);

const REGBIN_CHECK_FLAG_SETTER_PATTERN: &str = concat!(
// MOV RAX, qword ptr [RBX+0x8]
"01001... 10001011 01000011 00001000",
Expand All @@ -50,45 +20,20 @@ const REGBIN_CHECK_FLAG_SETTER_PATTERN: &str = concat!(
// MOV [RegBinFlags + 1], AL
"10001000 00000101 ........ ........ ........ ........",
// MOV [RegBinFlags + 2], AL
"10001000 00000101 [........ ........ ........ ........]",
"[10001000 00000101 ........ ........ ........ ........]",
);

pub fn hook() {
// Find the constructor's pointer
let regulationmanager_constructor = match_instruction_pattern(REGULATIONMANAGER_CONSTRUCTOR_PATTERN)
.expect("Could not find regulation manager constructor")
.location;

// Find the regbin check flag by matching the second IBO and checking what offsets the code
// references.
let regbin_check_flag = {
let matched = match_instruction_pattern(REGBIN_CHECK_FLAG_SETTER_PATTERN)
.expect("Could not find the regbin check flag setter");

let capture = matched.captures.first().unwrap();
let offset = u32::from_le_bytes(capture.bytes.as_slice().try_into().unwrap());

// We take the occurence location, add the offset from the bytes and add the size of the
// instruction itself (minus capture group offset in instruction) to find the
// absolute position.
capture.location + offset as usize + 4
};
let safety_flag_initializer_va = match_instruction_pattern(REGBIN_CHECK_FLAG_SETTER_PATTERN)
.map(|m| m.captures.first().map(|c| c.location as *mut u8))
.flatten()
.expect("Could not find the regbin check flag setter");

unsafe {
REGULATIONMANAGER_CONSTRUCTOR
.initialize(
transmute(regulationmanager_constructor),
move |allocated_space: u64, param_2: u64| {
let result = REGULATIONMANAGER_CONSTRUCTOR.call(allocated_space, param_2);
// Overwrites the flag that seems to determine if the regulation
// bin file should be checked against a particular hash in the sl2.
*(regbin_check_flag as *mut u8) = 0x0;

result
}
)
.unwrap();
region::protect(safety_flag_initializer_va, 1, Protection::READ_WRITE_EXECUTE)
.expect("Could not change memory protection for flag initializer");

REGULATIONMANAGER_CONSTRUCTOR.enable().unwrap();
// XOR in stead of MOV so we clear out the flag
*safety_flag_initializer_va = 0x30;
}
}

0 comments on commit 140bb25

Please sign in to comment.