Skip to content

Commit d457dde

Browse files
committed
Merge branch 'dev'
2 parents 4e9456e + b32ee06 commit d457dde

12 files changed

Lines changed: 245 additions & 34 deletions

File tree

Makefile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ CXXFLAGS := -O3 -flto=auto -fPIC -m32 -std=c++20 -Wall -Wextra -Wpedantic -Wno-e
1313

1414
LDFLAGS := -shared -Wl,--no-undefined
1515
LDFLAGS += $(shell pkg-config --libs "openssl")
16+
LDFLAGS += $(shell pkg-config --libs "libcurl")
1617

17-
DATE := $(shell date "+%Y%m%d%H%M%S")
18+
#DATE := $(shell date "+%Y%m%d%H%M%S")
19+
DATE := $(shell cat res/version.txt)
1820

1921
ifeq ($(shell echo $$NATIVE),1)
2022
CXXFLAGS += -march=native
@@ -32,6 +34,11 @@ bin/SLSsteam.so: $(objs) $(libs)
3234
@mkdir -p bin
3335
$(CXX) $(CXXFLAGS) $^ -o bin/SLSsteam.so $(LDFLAGS)
3436

37+
obj/update.o: src/update.cpp res/version.txt
38+
$(shell ./embed-version.sh)
39+
@mkdir -p $(dir $@)
40+
$(CXX) $(CXXFLAGS) -isysteminclude -MMD -MP -c $< -o $@
41+
3542
-include $(deps)
3643
obj/config.o: src/config.cpp res/config.yaml
3744
$(shell ./embed-config.sh)

embed-version.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/bash
2+
3+
VERSION="$(cat "./res/version.txt")"
4+
5+
echo "#pragma once
6+
7+
#include <cstdint>
8+
9+
10+
constexpr uint64_t VERSION = $VERSION;" > src/version.hpp

res/updates.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SafeModeHashes:
2+
20251226083318:
3+
- 8cd7cd0cf872396c47371c23bbd805d4e5aa8088a9d5b1518f60c24e6f3c444d #ubuntu12_32
4+
- 1e9ddfe86369edb365458bc1973381625e01d3c0c687e3e87150b59a1c84a871 #steamdeck_stable

res/version.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
20251226083318

src/hooks.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,13 @@ static void hkClientApps_PipeLoop(void* pClientApps, void* a1, void* a2, void* a
471471
Hooks::IClientApps_PipeLoop.tramp.fn(pClientApps, a1, a2, a3);
472472
}
473473

474+
static void hkClientControllerSerialized_PipeLoop(void* pClientControllerSerialized, void* a1, void* a2, void* a3)
475+
{
476+
FakeAppIds::pipeLoop(false);
477+
Hooks::IClientControllerSerialized_PipeLoop.tramp.fn(pClientControllerSerialized, a1, a2, a3);
478+
FakeAppIds::pipeLoop(true);
479+
}
480+
474481
static bool hkClientRemoteStorage_IsCloudEnabledForApp(void* pClientRemoteStorage, uint32_t appId)
475482
{
476483
const bool enabled = Hooks::IClientRemoteStorage_IsCloudEnabledForApp.originalFn.fn(pClientRemoteStorage, appId);
@@ -873,6 +880,7 @@ namespace Hooks
873880

874881
DetourHook<IClientAppManager_PipeLoop_t> IClientAppManager_PipeLoop;
875882
DetourHook<IClientApps_PipeLoop_t> IClientApps_PipeLoop;
883+
DetourHook<IClientControllerSerialized_PipeLoop_t> IClientControllerSerialized_PipeLoop;
876884
DetourHook<IClientRemoteStorage_PipeLoop_t> IClientRemoteStorage_PipeLoop;
877885
DetourHook<IClientUGC_PipeLoop_t> IClientUGC_PipeLoop;
878886
DetourHook<IClientUtils_PipeLoop_t> IClientUtils_PipeLoop;
@@ -932,6 +940,7 @@ bool Hooks::setup()
932940

933941
&& IClientApps_PipeLoop.setup(Patterns::IClientApps::PipeLoop, hkClientApps_PipeLoop)
934942
&& IClientAppManager_PipeLoop.setup(Patterns::IClientAppManager::PipeLoop, hkClientAppManager_PipeLoop)
943+
&& IClientControllerSerialized_PipeLoop.setup(Patterns::IClientControllerSerialized::PipeLoop, hkClientControllerSerialized_PipeLoop)
935944
&& IClientRemoteStorage_PipeLoop.setup(Patterns::IClientRemoteStorage::PipeLoop, hkClientRemoteStorage_PipeLoop)
936945
&& IClientUGC_PipeLoop.setup(Patterns::IClientUGC::PipeLoop, hkClientUGC_PipeLoop)
937946
&& IClientUtils_PipeLoop.setup(Patterns::IClientUtils::PipeLoop, hkClientUtils_PipeLoop)

src/hooks.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ namespace Hooks
7272

7373
typedef void(*IClientAppManager_PipeLoop_t)(void*, void*, void*, void*);
7474
typedef void(*IClientApps_PipeLoop_t)(void*, void*, void*, void*);
75+
typedef void(*IClientControllerSerialized_PipeLoop_t)(void*, void*, void*, void*);
7576
typedef void(*IClientRemoteStorage_PipeLoop_t)(void*, void*, void*, void*);
7677
typedef void(*IClientUGC_PipeLoop_t)(void*, void*, void*, void*);
7778
typedef void(*IClientUtils_PipeLoop_t)(void*, void*, void*, void*);
@@ -104,6 +105,7 @@ namespace Hooks
104105

105106
extern DetourHook<IClientAppManager_PipeLoop_t> IClientAppManager_PipeLoop;
106107
extern DetourHook<IClientApps_PipeLoop_t> IClientApps_PipeLoop;
108+
extern DetourHook<IClientControllerSerialized_PipeLoop_t> IClientControllerSerialized_PipeLoop;
107109
extern DetourHook<IClientRemoteStorage_PipeLoop_t> IClientRemoteStorage_PipeLoop;
108110
extern DetourHook<IClientUGC_PipeLoop_t> IClientUGC_PipeLoop;
109111
extern DetourHook<IClientUtils_PipeLoop_t> IClientUtils_PipeLoop;

src/main.cpp

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "hooks.hpp"
55
#include "log.hpp"
66
#include "patterns.hpp"
7+
#include "update.hpp"
78
#include "utils.hpp"
89

910
#include "libmem/libmem.h"
@@ -22,8 +23,6 @@
2223
#include <unistd.h>
2324

2425

25-
static const char* EXPECTED_STEAMCLIENT_HASH = "8cd7cd0cf872396c47371c23bbd805d4e5aa8088a9d5b1518f60c24e6f3c444d";
26-
2726
static bool cleanEnvVar(const char* varName)
2827
{
2928
char* var = getenv(varName);
@@ -55,36 +54,6 @@ static bool cleanEnvVar(const char* varName)
5554
return true;
5655
}
5756

58-
static bool verifySteamClientHash()
59-
{
60-
61-
auto path = std::filesystem::path(g_modSteamClient.path);
62-
auto dir = path.parent_path();
63-
64-
g_pLog->info
65-
(
66-
"steamclient.so loaded from %s/%s at %p to %p\n",
67-
dir.filename().c_str(),
68-
path.filename().c_str(),
69-
g_modSteamClient.base,
70-
g_modSteamClient.end
71-
);
72-
73-
try
74-
{
75-
std::string sha256 = Utils::getFileSHA256(path.c_str());
76-
g_pLog->info("steamclient.so hash is %s\n", sha256.c_str());
77-
78-
//TODO: Research if there's a better way to compare const char* to std::string
79-
return strcmp(sha256.c_str(), EXPECTED_STEAMCLIENT_HASH) == 0;
80-
}
81-
catch(std::runtime_error& err)
82-
{
83-
g_pLog->debug("Unable to read steamclient.so hash!\n");
84-
return false;
85-
}
86-
}
87-
8857
//Looking at /proc/self/maps it seems like this isn't needed for processes that aren't steam
8958
//__attribute__((noreturn))
9059
static void unload()
@@ -148,6 +117,8 @@ static void setup()
148117
ldLibPath.append("/usr/lib:/usr/lib32");
149118
setenv("LD_LIBRARY_PATH", ldLibPath.c_str(), true);
150119

120+
Updater::init();
121+
151122
setupSuccess = true;
152123
}
153124

@@ -165,7 +136,19 @@ static void load()
165136
return;
166137
}
167138

168-
if (!verifySteamClientHash())
139+
auto path = std::filesystem::path(g_modSteamClient.path);
140+
auto dir = path.parent_path();
141+
142+
g_pLog->info
143+
(
144+
"steamclient.so loaded from %s/%s at %p to %p\n",
145+
dir.filename().c_str(),
146+
path.filename().c_str(),
147+
g_modSteamClient.base,
148+
g_modSteamClient.end
149+
);
150+
151+
if (!Updater::verifySafeModeHash())
169152
{
170153
if (g_config.safeMode.get())
171154
{

src/patterns.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,17 @@ namespace Patterns
165165
};
166166
}
167167

168+
namespace IClientControllerSerialized
169+
{
170+
Pattern_t PipeLoop
171+
{
172+
"IClientControllerSerialized::PipeLoop",
173+
"FF B5 ? ? ? ? 50 8D 83 ? ? ? ? 68 58 15 00 00",
174+
SigFollowMode::PrologueUpwards,
175+
std::vector<uint8_t> { 0x56, 0x57, 0xe5, 0x89, 0x55 }
176+
};
177+
}
178+
168179
namespace IClientRemoteStorage
169180
{
170181
Pattern_t PipeLoop

src/patterns.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ namespace Patterns
6666
extern Pattern_t PipeLoop;
6767
}
6868

69+
namespace IClientControllerSerialized
70+
{
71+
extern Pattern_t PipeLoop;
72+
}
73+
6974
namespace IClientRemoteStorage
7075
{
7176
extern Pattern_t PipeLoop;

src/update.cpp

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#include "update.hpp"
2+
3+
#include "config.hpp"
4+
#include "globals.hpp"
5+
#include "log.hpp"
6+
#include "utils.hpp"
7+
#include "version.hpp"
8+
9+
#include <curl/curl.h>
10+
#include <curl/easy.h>
11+
#include "yaml-cpp/yaml.h"
12+
13+
#include <filesystem>
14+
#include <fstream>
15+
#include <map>
16+
#include <map>
17+
#include <string>
18+
19+
static CURL* curl = nullptr;
20+
21+
std::map<uint64_t, std::unordered_set<std::string>> Updater::clientHashMap = std::map<uint64_t, std::unordered_set<std::string>>();
22+
23+
static size_t writeCallback(const char* content, size_t size, size_t memberSize, std::string* data)
24+
{
25+
data->append(content, size * memberSize);
26+
return size * memberSize;
27+
}
28+
29+
bool Updater::init()
30+
{
31+
std::string data;
32+
33+
curl = curl_easy_init();
34+
curl_easy_setopt(curl, CURLOPT_URL, "https://raw.githubusercontent.com/AceSLS/SLSsteam/refs/heads/main/res/updates.yaml");
35+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
36+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
37+
38+
auto res = curl_easy_perform(curl);
39+
g_pLog->info("Curl Res: %u\n", res);
40+
41+
curl_easy_cleanup(curl);
42+
43+
if(res != 0)
44+
{
45+
data = loadFromCache();
46+
if(data.size() < 1)
47+
{
48+
return false;
49+
}
50+
51+
g_pLog->info("Using cached updates.yaml\n");
52+
}
53+
54+
g_pLog->debug("updates.yaml:\n%s\n", data.c_str());
55+
56+
try
57+
{
58+
YAML::Node node = YAML::Load(data);
59+
for (const auto& sub : node["SafeModeHashes"])
60+
{
61+
uint64_t version = sub.first.as<uint64_t>();
62+
clientHashMap[version] = std::unordered_set<std::string>();
63+
64+
g_pLog->debug("Parsing version %llu\n", version);
65+
66+
for(const auto& hash : sub.second)
67+
{
68+
auto str = hash.as<std::string>();
69+
clientHashMap[version].emplace(str);
70+
71+
g_pLog->debug("Added %s to SLSsteam version %llu\n", str.c_str(), version);
72+
}
73+
}
74+
}
75+
catch(...)
76+
{
77+
g_pLog->info("Failed to parse updates!\n");
78+
return false;
79+
}
80+
81+
saveToCache(data);
82+
return true;
83+
}
84+
85+
std::string Updater::getCacheFilePath()
86+
{
87+
auto path = g_config.getDir().append("/.updates.yaml");
88+
return path;
89+
}
90+
91+
void Updater::saveToCache(std::string yaml)
92+
{
93+
auto path = Updater::getCacheFilePath();
94+
95+
std::ofstream stream = std::ofstream(path.c_str());
96+
stream << yaml;
97+
stream.close();
98+
99+
g_pLog->debug("Cached res/updates.yaml!\n");
100+
}
101+
102+
std::string Updater::loadFromCache()
103+
{
104+
auto path = Updater::getCacheFilePath();
105+
if (!std::filesystem::exists(path))
106+
{
107+
return std::string();
108+
}
109+
110+
g_pLog->debug("Loading updates.ymal from disk!\n");
111+
112+
std::ifstream fstream = std::ifstream(path.c_str());
113+
std::stringstream buf;
114+
buf << fstream.rdbuf();
115+
116+
fstream.close();
117+
return buf.str();
118+
}
119+
120+
bool Updater::verifySafeModeHash()
121+
{
122+
auto path = std::filesystem::path(g_modSteamClient.path);
123+
124+
try
125+
{
126+
std::string sha256 = Utils::getFileSHA256(path.c_str());
127+
g_pLog->info("steamclient.so hash is %s\n", sha256.c_str());
128+
129+
for (const auto& safeHash : clientHashMap)
130+
{
131+
g_pLog->debug("SafeHash %llu -> %llu\n", safeHash.first, VERSION);
132+
if (VERSION > safeHash.first)
133+
{
134+
continue;
135+
}
136+
137+
if (safeHash.second.contains(sha256))
138+
{
139+
return true;
140+
}
141+
}
142+
143+
return false;
144+
}
145+
catch(std::runtime_error& err)
146+
{
147+
g_pLog->debug("Unable to read steamclient.so hash!\n");
148+
return false;
149+
}
150+
151+
return true;
152+
}

0 commit comments

Comments
 (0)