Skip to content

Commit

Permalink
1.4.4
Browse files Browse the repository at this point in the history
Added a hook to force Creation mods to be "achievement safe" and a new patch to fix achievement awarding
  • Loading branch information
server-imp committed Jun 11, 2024
1 parent 09f6111 commit d92c9c4
Show file tree
Hide file tree
Showing 11 changed files with 268 additions and 31 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "external/minhook"]
path = external/minhook
url = https://github.com/TsudaKageyu/minhook.git
5 changes: 5 additions & 0 deletions DLLProxy.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>vcruntime140_1</TargetName>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)external\minhook\include;</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>vcruntime140_1</TargetName>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)external\minhook\include;</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
Expand Down Expand Up @@ -125,6 +127,7 @@
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);$(SolutionDir)lib\$(Configuration)\libMinHook.x64.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
Expand All @@ -147,11 +150,13 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);$(SolutionDir)lib\$(Configuration)\libMinHook.x64.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="asi.h" />
<ClInclude Include="cfg.h" />
<ClInclude Include="hook.h" />
<ClInclude Include="log.h" />
<ClInclude Include="memory.h" />
<ClInclude Include="util.h" />
Expand Down
3 changes: 3 additions & 0 deletions DLLProxy.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
<ClInclude Include="util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="hook.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
Expand Down
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# Project archived as of Jun 10 2024
No longer functioning as of the Creation update, archived as I do not have the time to look into it right now

# SFAE - Starfield Achievement Enabler

Allows you to earn achievements while using mods and console commands
Expand Down
15 changes: 14 additions & 1 deletion SFAE.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34024.191
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLLProxy", "DLLProxy.vcxproj", "{94C1BB19-29DC-49AE-96CA-94EE024BDA84}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SFAE", "DLLProxy.vcxproj", "{94C1BB19-29DC-49AE-96CA-94EE024BDA84}"
ProjectSection(ProjectDependencies) = postProject
{F142A341-5EE0-442D-A15F-98AE9B48DBAE} = {F142A341-5EE0-442D-A15F-98AE9B48DBAE}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libMinHook", "external\minhook\build\VC17\libMinHook.vcxproj", "{F142A341-5EE0-442D-A15F-98AE9B48DBAE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -21,6 +26,14 @@ Global
{94C1BB19-29DC-49AE-96CA-94EE024BDA84}.Release|x64.Build.0 = Release|x64
{94C1BB19-29DC-49AE-96CA-94EE024BDA84}.Release|x86.ActiveCfg = Release|Win32
{94C1BB19-29DC-49AE-96CA-94EE024BDA84}.Release|x86.Build.0 = Release|Win32
{F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.ActiveCfg = Debug|x64
{F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.Build.0 = Debug|x64
{F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x86.ActiveCfg = Debug|Win32
{F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x86.Build.0 = Debug|Win32
{F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.ActiveCfg = Release|x64
{F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.Build.0 = Release|x64
{F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x86.ActiveCfg = Release|Win32
{F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
1 change: 1 addition & 0 deletions external/minhook
Submodule minhook added at 1cc461
113 changes: 113 additions & 0 deletions hook.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#ifndef _HOOK
#define _HOOK

#include "pch.h"
#include "log.h"
#include "memory.h"

class Hook
{
protected:
LPVOID hookFunction;

LPVOID _target{};
LPVOID _original{};
bool _enabled{};

public:
const std::string name{};

public:
Hook(const std::string name, LPVOID hookFunction)
: name(name), hookFunction(hookFunction)
{}

bool enabled() const
{
return _enabled;
}

virtual bool enable() = 0;
virtual bool disable() = 0;

template <typename T>
T original() const
{
return (T)_original;
}
};

class DetourHook : public Hook
{
public:
DetourHook(const std::string name, LPVOID target, LPVOID hookFunction)
: Hook(name, hookFunction)
{
_target = target;
}

bool enable() override
{
if (_enabled)
{
//err("Hook \"%s\": Already enabled", this->name.c_str());
return false;
}

auto result = MH_Initialize();
if (result != MH_OK && result != MH_ERROR_ALREADY_INITIALIZED)
{
err("Hook \"%s\": MH_Initialize failed: %s", this->name.c_str(), MH_StatusToString(result));
return false;
}

result = MH_CreateHook(_target, (LPVOID)this->hookFunction, &_original);
if (result != MH_OK && result != MH_ERROR_ALREADY_CREATED)
{
err("Hook \"%s\": MH_CreateHook failed: %s", this->name.c_str(), MH_StatusToString(result));
return false;
}

result = MH_EnableHook(_target);
if (result != MH_OK && result != MH_ERROR_ENABLED)
{
err("Hook \"%s\": MH_EnableHook failed: %s", this->name.c_str(), MH_StatusToString(result));
return false;
}

//info("Hook \"%s\": Enabled", this->name.c_str());
_enabled = true;

return true;
}

bool disable() override
{
if (!_enabled)
{
//err("Hook \"%s\": Already disabled", this->name.c_str());
return false;
}

auto result = MH_Initialize();
if (result != MH_OK && result != MH_ERROR_ALREADY_INITIALIZED)
{
err("Hook \"%s\": MH_Initialize failed: %s", this->name.c_str(), MH_StatusToString(result));
return false;
}

result = MH_DisableHook(_target);
if (result != MH_OK && result != MH_ERROR_DISABLED && result != MH_ERROR_NOT_CREATED)
{
err("Hook \"%s\": MH_DisableHook failed: %s", this->name.c_str(), MH_StatusToString(result));
return false;
}

//info("Hook \"%s\": Disabled", this->name.c_str());
_enabled = false;

return true;
}
};

#endif
3 changes: 2 additions & 1 deletion memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ namespace memory
bool enabled;

public:
Patch(const char* name, std::vector<uint8_t> buffer, std::vector<const char*> patterns, const char* moduleName = nullptr)
Patch(const char* name, std::vector<uint8_t> buffer, std::vector<const char*> patterns, const size_t offset = 0x00, const char* moduleName = nullptr)
{
this->name = name;
this->buffer = buffer;
Expand All @@ -342,6 +342,7 @@ namespace memory
if (pattern::find(pattern, &pointer, moduleName))
{
valid = true;
pointer = pointer.add(offset);
break;
}
}
Expand Down
64 changes: 63 additions & 1 deletion notes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Mod Check:
Mod Check:
7FF6980649C1: 45 8B C2 - mov r8d,r10d
7FF6980649C4: E8 17 7C ED 00 - call 7FF698F3C5E0
7FF6980649C9: F7 00 00 80 00 00 - test [rax],00008000
Expand Down Expand Up @@ -26,6 +26,68 @@ Mod Check:
40 ? 48 ? ? ? C6 ? ? ? 00 48 ? ? ? ? 74 ? 48 // rex push
? 48 ? ? ? C6 ? ? ? 00 48 ? ? ? ? 74 ? 48 // push

Achievement Awarded:
.text:0000000002B52180 48 89 5C 24 08 mov [rsp+arg_0], rbx
.text:0000000002B52185 48 89 74 24 10 mov [rsp+arg_8], rsi
.text:0000000002B5218A 57 push rdi
.text:0000000002B5218B 48 81 EC 40 04 00 00 sub rsp, 440h
.text:0000000002B52192 41 8B F1 mov esi, r9d
.text:0000000002B52195 48 8B F9 mov rdi, rcx
.text:0000000002B52198 4C 8D 05 31 E3 88 02 lea r8, aAchievementDAw ; "Achievement %d awarded"
.text:0000000002B5219F BA 00 04 00 00 mov edx, 400h ; BufferCount
.text:0000000002B521A4 48 8D 4C 24 40 lea rcx, [rsp+448h+Buffer] ; Buffer
.text:0000000002B521A9 E8 EA 46 6D FE call sprintf_s
.text:0000000002B521AE 48 8B 07 mov rax, [rdi]
.text:0000000002B521B1 48 8B 98 10 02 00 00 mov rbx, [rax+210h]
.text:0000000002B521B8 48 8D 05 59 58 7C 02 lea rax, off_5317A18
.text:0000000002B521BF 48 89 44 24 20 mov [rsp+448h+var_428], rax
.text:0000000002B521C4 48 8D 44 24 40 lea rax, [rsp+448h+Buffer]
.text:0000000002B521C9 48 89 44 24 28 mov [rsp+448h+var_420], rax
.text:0000000002B521CE 48 8D 4C 24 30 lea rcx, [rsp+448h+var_418]
.text:0000000002B521D3 E8 38 65 C3 FD call sub_788710
.text:0000000002B521D8 90 nop
.text:0000000002B521D9 45 33 C0 xor r8d, r8d
.text:0000000002B521DC 48 8D 54 24 20 lea rdx, [rsp+448h+var_428]
.text:0000000002B521E1 48 8B CF mov rcx, rdi
.text:0000000002B521E4 FF D3 call rbx
.text:0000000002B521E6 90 nop
.text:0000000002B521E7 48 8D 4C 24 30 lea rcx, [rsp+448h+var_418]
.text:0000000002B521EC E8 17 A1 C3 FD call sub_78C308
.text:0000000002B521F1 90 nop
.text:0000000002B521F2 48 8B 05 77 1F D2 03 mov rax, cs:qword_6874170
.text:0000000002B521F9 83 78 54 01 cmp dword ptr [rax+54h], 1
.text:0000000002B521FD 75 11 jnz short loc_2B52210 <--- nop this
.text:0000000002B521FF E8 50 71 C2 00 call sub_3779354
.text:0000000002B52204 4C 8B 00 mov r8, [rax]
.text:0000000002B52207 8B D6 mov edx, esi
.text:0000000002B52209 48 8B C8 mov rcx, rax
.text:0000000002B5220C 41 FF 50 28 call qword ptr [r8+28h]
.text:0000000002B52210
.text:0000000002B52210 loc_2B52210: ; CODE XREF: achievementAwarded+7D↑j
.text:0000000002B52210 4C 8D 9C 24 40 04 00 00 lea r11, [rsp+448h+var_8]
.text:0000000002B52218 49 8B 5B 10 mov rbx, [r11+10h]
.text:0000000002B5221C 49 8B 73 18 mov rsi, [r11+18h]
.text:0000000002B52220 49 8B E3 mov rsp, r11
.text:0000000002B52223 5F pop rdi
.text:0000000002B52224 C3 retn

48 ? ? ? ? ? ? 83 ? ? 01 75 ? E8 ? ? ? ? 4C
+11

Achievement Friendly:
.text:0000000001089B2C C6 83 50 07 00 00 01 mov byte ptr [rbx+750h], 1
.text:0000000001089B33
.text:0000000001089B33 loc_1089B33: ; CODE XREF: sub_10893F0+725↑j
.text:0000000001089B33 ; sub_10893F0+73A↑j
.text:0000000001089B33 4C 8D 83 58 07 00 00 lea r8, [rbx+758h]
.text:0000000001089B3A C6 44 24 20 00 mov [rsp+5F0h+var_5D0], 0
.text:0000000001089B3F 45 33 C9 xor r9d, r9d
.text:0000000001089B42 48 8D 15 5F AD 12 04 lea rdx, aAchievementFri ; "achievement_friendly"
.text:0000000001089B49 48 8D 4C 24 40 lea rcx, [rsp+5F0h+var_5B0]
.text:0000000001089B4E E8 BD E6 01 00 call jsonReadBool <--- hook this

C6 ? ? ? ? ? 01 4C ? ? ? ? ? ? C6 ? ? ? 00 ? ? ? 48 ? ? ? ? ? ? 48 ? ? ? ? E8 ? ? ? ? ? ? ? ? ? ? ? ? 4C ? ? ? ? ? ? C6 ? ? ? 00 45 ? ?
+35 and rip()

Mods Message:
Starfield.exe+24DEE27: E9 19 01 00 00 - jmp Starfield.exe+24DEF45
Expand Down
3 changes: 3 additions & 0 deletions pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#include <filesystem>
#include <functional>
#include <windows.h>
#include <cstdint>
#include <psapi.h>
Expand All @@ -21,4 +22,6 @@
using namespace std::chrono_literals;
namespace fs = std::filesystem;

#include "MinHook.h"

#endif
Loading

0 comments on commit d92c9c4

Please sign in to comment.