mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-10-15 11:47:14 -04:00
x86-64 client: redirect the web helper's exec instead of editing Steam
The client checksums its files as it starts (a CRC pass on its own restart, not only sizes), so the size-padded steamwebhelper.sh can be caught: "bad CRC on steamrt64/steamwebhelper.sh", then a 2-3 minute reinstall on every start (seen in Bannerlator's port). The session shim's exec hook (preload/net.c) now turns steamrt64's `exec ./steamwebhelper` into the arm64 web helper's launcher when BL_X64_ARM_WEBHELPER names it (set by bannerlator-steam-x64 for the client); nothing of Steam's is edited, and the arm64 helper's own path (steamrtarm64) never matches.
This commit is contained in:
1 parent
2fa4bf28d6
commit
0e1cdcd5de
3 files changed
+55
-32
No files matched your search
@@ -557,33 +557,14 @@ export BL_WEBHELPER_HIDE_TRACER=1
|
||||
x64_exec() {
|
||||
x64_env
|
||||
cd "$STEAM_X64"
|
||||
# The client's own web helper launcher, pointed at the arm64 client's helper (FEX hands that arm64
|
||||
# program to the CPU). The client checks its files' sizes at every start and reinstalls itself
|
||||
# over one that differs (device: install loop, "steamwebhelper.sh is 176 bytes, expected 84"), so
|
||||
# the replacement is padded to the size of the client's own copy. It is pointed again whenever it
|
||||
# differs, for as long as this client runs: a full check puts the client's copy back.
|
||||
case "${1:-}" in
|
||||
-shutdown|steam://*) ;;
|
||||
*) if [ "${BL_X64_X86_WEBHELPER:-0}" != 1 ] && [ -x /usr/local/bin/bannerlator-x64-arm-webhelper ] &&
|
||||
[ -x "$ARM_STEAM/steamrtarm64/steamwebhelper" ]; then
|
||||
(
|
||||
client=$$ wh=$STEAM_X64/steamrt64/steamwebhelper.sh
|
||||
base=$(printf '#!/bin/sh\nexec /usr/local/bin/bannerlator-x64-arm-webhelper "$@"\n#')
|
||||
size= want=
|
||||
while kill -0 "$client" 2>/dev/null; do
|
||||
if [ -f "$wh" ] && ! grep -q bannerlator-x64-arm-webhelper "$wh" 2>/dev/null; then
|
||||
size=$(stat -c %s "$wh") want=
|
||||
pad=$((size - ${#base} - 1))
|
||||
[ "$pad" -ge 0 ] && want=$base$(printf '%*s' "$pad" '' | tr ' ' '-')
|
||||
fi
|
||||
if [ -n "$want" ] && [ "$(cat "$wh" 2>/dev/null)" != "$want" ]; then
|
||||
printf '%s\n' "$want" > "$wh.new" && chmod 755 "$wh.new" && mv -f "$wh.new" "$wh"
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
) &
|
||||
fi ;;
|
||||
esac
|
||||
# The client's web helper is the arm64 client's (bannerlator-x64-arm-webhelper; FEX hands that arm64
|
||||
# program to the CPU): the session shim turns steamrt64/steamwebhelper.sh's exec of ./steamwebhelper
|
||||
# into it (preload/net.c). Nothing of the client's is edited - it checksums its files as it starts
|
||||
# and reinstalled itself over an edited launcher (2-3 minutes) on every start.
|
||||
if [ "${BL_X64_X86_WEBHELPER:-0}" != 1 ] && [ -x /usr/local/bin/bannerlator-x64-arm-webhelper ] &&
|
||||
[ -x "$ARM_STEAM/steamrtarm64/steamwebhelper" ]; then
|
||||
export BL_X64_ARM_WEBHELPER=/usr/local/bin/bannerlator-x64-arm-webhelper
|
||||
fi
|
||||
exec "${BL_FEX:-/usr/local/bin/FEX}" "$STEAM_X64/steamrt64/steam" "$@"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#!/bin/bash
|
||||
# The x86-64 client's web helper (its whole UI) is the arm64 client's, run natively: both clients are
|
||||
# the same Steam build, and steamrt64/steamwebhelper.sh is pointed here (bannerlator-steam-x64) through
|
||||
# an arm64 binary, which FEX hands to the CPU. Under FEX the x86 helper could not have the GPU (its GPU
|
||||
# process needs libgbm, which FEX does not thunk) and drew on SwiftShader; this one draws with ANGLE on
|
||||
# Turnip and takes the session's preloads (KGSL poll fix, fast path), as from the arm64 client.
|
||||
# the same Steam build, and the session shim turns the x86 client's exec of its own helper into this
|
||||
# (preload/net.c, BL_X64_ARM_WEBHELPER); FEX hands the arm64 program here to the CPU. Under FEX the
|
||||
# x86 helper could not have the GPU (its GPU process needs libgbm, which FEX does not thunk) and drew
|
||||
# on SwiftShader; this one draws with ANGLE on Turnip and takes the session's preloads (KGSL poll fix,
|
||||
# fast path), as from the arm64 client.
|
||||
x64_home=$HOME
|
||||
arm=/root/.local/share/Steam/steamrtarm64
|
||||
|
||||
@@ -11,7 +12,7 @@ arm=/root/.local/share/Steam/steamrtarm64
|
||||
for v in $(compgen -e); do
|
||||
case $v in FEX_*) unset "$v" ;; esac
|
||||
done
|
||||
unset LD_PRELOAD LIBGL_ALWAYS_SOFTWARE LIBGL_DRI3_DISABLE BL_WEBHELPER_HIDE_TRACER
|
||||
unset LD_PRELOAD LIBGL_ALWAYS_SOFTWARE LIBGL_DRI3_DISABLE BL_WEBHELPER_HIDE_TRACER BL_X64_ARM_WEBHELPER
|
||||
# The arm64 session's GPU settings (saved by bannerlator-steam-x64 at start).
|
||||
if [ -f "$x64_home/arm-session.env" ]; then
|
||||
eval "$(grep -E '^declare -x (VK_ICD_FILENAMES|VK_DRIVER_FILES|GALLIUM_DRIVER|MESA_LOADER_DRIVER_OVERRIDE|LIBGL_KOPPER_DRI2|TU_DEBUG|ZINK_DEBUG|ZINK_DESCRIPTORS|MESA_NO_ERROR|MESA_DISK_CACHE_DATABASE)=' "$x64_home/arm-session.env")"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/netlink.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -194,10 +195,44 @@ static int maybe_answer_lsof(const char *path, char *const argv[]) {
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/* The x86-64 Steam client's web helper is the arm64 client's (bannerlator-x64-arm-webhelper, named
|
||||
* by BL_X64_ARM_WEBHELPER, which bannerlator-steam-x64 sets for the client): steamrt64's
|
||||
* steamwebhelper.sh ends in `exec ./steamwebhelper`, and that exec becomes the launcher with the same
|
||||
* arguments. Steam's own files stay as shipped - the client checksums them as it starts and
|
||||
* reinstalled itself over an edited launcher every time. The arm64 helper (steamrtarm64) never
|
||||
* matches. Returns the launcher's argv to exec instead, or NULL. */
|
||||
static char **web_helper_redirect(const char *path, char *const argv[], const char **launcher) {
|
||||
const char *want = getenv("BL_X64_ARM_WEBHELPER");
|
||||
if (!want || !*want || !path) return NULL;
|
||||
const char *base = strrchr(path, '/');
|
||||
if (strcmp(base ? base + 1 : path, "steamwebhelper") != 0) return NULL;
|
||||
if (!strstr(path, "/steamrt64/")) {
|
||||
char cwd[PATH_MAX];
|
||||
size_t n;
|
||||
if (path[0] == '/' || !getcwd(cwd, sizeof(cwd))) return NULL;
|
||||
n = strlen(cwd);
|
||||
if (n < 10 || strcmp(cwd + n - 10, "/steamrt64") != 0) return NULL;
|
||||
}
|
||||
int argc = 0;
|
||||
while (argv && argv[argc]) argc++;
|
||||
char **out = calloc((size_t)argc + 2, sizeof(char *));
|
||||
if (!out) return NULL;
|
||||
out[0] = (char *)want;
|
||||
for (int i = 1; i < argc; i++) out[i] = argv[i];
|
||||
*launcher = want;
|
||||
return out;
|
||||
}
|
||||
|
||||
int execve(const char *path, char *const argv[], char *const envp[]) {
|
||||
static int (*real)(const char *, char *const[], char *const[]);
|
||||
if (!real) real = (int (*)(const char *, char *const[], char *const[]))dlsym(RTLD_NEXT, "execve");
|
||||
maybe_answer_lsof(path, argv);
|
||||
const char *launcher = NULL;
|
||||
char **redirected = web_helper_redirect(path, argv, &launcher);
|
||||
if (redirected) {
|
||||
real(launcher, redirected, envp);
|
||||
free(redirected); /* only on failure: the original exec runs */
|
||||
}
|
||||
return real(path, argv, envp);
|
||||
}
|
||||
|
||||
@@ -229,6 +264,12 @@ int execv(const char *path, char *const argv[]) {
|
||||
static int (*real)(const char *, char *const[]);
|
||||
if (!real) real = (int (*)(const char *, char *const[]))dlsym(RTLD_NEXT, "execv");
|
||||
maybe_answer_lsof(path, argv);
|
||||
const char *launcher = NULL;
|
||||
char **redirected = web_helper_redirect(path, argv, &launcher);
|
||||
if (redirected) {
|
||||
real(launcher, redirected);
|
||||
free(redirected);
|
||||
}
|
||||
return real(path, argv);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user