diff --git a/.SRCINFO b/.SRCINFO index c520b1a0534c..050fb8ef3ef9 100644 --- a/.SRCINFO +++ b/.SRCINFO @@ -1,20 +1,30 @@ pkgbase = bakkesmod-steam pkgdesc = A mod aimed at making you better at Rocket League! pkgver = 2.58 - pkgrel = 1 + pkgrel = 2 url = https://bakkesmod.com/ arch = x86_64 license = GPL makedepends = python source = dll-2-0-58.zip::https://github.com/bakkesmodorg/BakkesModInjectorCpp/releases/download/2.0.58/bakkesmod.zip source = src-2-0-58.zip::https://github.com/bakkesmodorg/BakkesModInjectorCpp/archive/refs/tags/2.0.58.zip - source = loopback-2-58-1.zip::https://github.com/kentslaney/bakkesmod-arch/archive/refs/tags/2.58-1-steam.zip + source = loopback-2-58-2.zip::https://github.com/kentslaney/bakkesmod-arch/archive/refs/tags/2.58-2-steam.zip source = https://github.com/kentslaney/bakkesmod-arch/releases/download/c369f24-1/inject.exe - source = pwshwrapper-05ea332.zip::https://github.com/PietJankbal/powershell-wrapper-for-wine/archive/05ea332209f52b796a78246a89757a291f254fb6.zip + source = https://github.com/kentslaney/bakkesmod-arch/releases/download/05ea332-1/powershell32.exe + source = https://github.com/kentslaney/bakkesmod-arch/releases/download/05ea332-1/powershell64.exe + source = https://github.com/PowerShell/PowerShell/releases/download/v7.4.1/PowerShell-7.4.1-win-x64.msi + source = https://github.com/Maximus5/ConEmu/releases/download/v23.07.24/ConEmuPack.230724.7z + source = https://www.7-zip.org/a/7z2501-x64.exe + source = https://raw.githubusercontent.com/PietJankbal/powershell-wrapper-for-wine/master/profile.ps1 sha256sums = 4184981c03f1d2df6458844c676d0fd7bf09d69d8d1894051f98c1638fc0609b sha256sums = 99d1c6dfa5ec37113fc1ed4f1763c45aacd93981ffeefe6828330d234ff2a87b sha256sums = SKIP sha256sums = 0e038a4f0a2799f6aaa34f6560f5d1d41fba0cf26f8814571cebc94f5bb67a6e - sha256sums = 79ac12ff72dad9c0f79f5658fa4fed7c4d92476c6eea77427aa2bc84964fcf94 + sha256sums = 196886b557e632547d32354f20834e88ba3726df29a486c85d6409900064f364 + sha256sums = e8dae4079a66d5a1564c577bd27caf8c890a1044d9c56948581591e196e4ac8c + sha256sums = 66c7c35ed9a46bd27e3d915dcf9a05e38b3f5ebb039883b92aa62ffea20fb187 + sha256sums = 2a9b98ebecaede62665ef427b05b3a5ccdac7bd3202414fc0f4c10825b4f4ea2 + sha256sums = 78afa2a1c773caf3cf7edf62f857d2a8a5da55fb0fff5da416074c0d28b2b55f + sha256sums = b0fd5df54a2b281348ab03c2942b1e83278bee62c71e06d3d671724b49946593 pkgname = bakkesmod-steam diff --git a/.gitignore b/.gitignore index f7f551732262..e42425d1147e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,9 @@ *.zip *.exe *.tar.* - +/build +/dist +/ConEmuPack.*.7z +/PowerShell-*.msi +/profile.ps1 +/.github diff --git a/Makefile b/Makefile new file mode 100644 index 000000000000..bd635d7bcbdc --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +all: inject sandbox + +inject: + mkdir -p build/include dist;\ + [ ! -d build/BakkesModInjectorCpp ] && git clone https://github.com/bakkesmodorg/BakkesModInjectorCpp.git build/BakkesModInjectorCpp;\ + git apply -q --directory=build/BakkesModInjectorCpp mingw.patch;\ + ln -sf /usr/x86_64-w64-mingw32/include/windows.h "build/include/Windows.h";\ + ln -sf /usr/x86_64-w64-mingw32/include/sdkddkver.h "build/include/SDKDDKVer.h";\ + ln -sf /usr/x86_64-w64-mingw32/include/shlobj.h "build/include/shlobj_core.h";\ + ln -sf "../BakkesModInjectorCpp/BakkesModWPF/Resource.h" "build/include/resource.h";\ + ln -sf "../BakkesModInjectorCpp/BakkesModInjectorC++/WindowsUtils.h" "build/include/windowsutils.h";\ + x86_64-w64-mingw32-g++ -std=c++17 -static-libgcc -static-libstdc++ -static -municode -mconsole -lpsapi -w -Ibuild/include -I/usr/x86_64-w64-mingw32/include -Ibuild/BakkesModInjectorCpp/BakkesModInjectorC++ \ + "build/BakkesModInjectorCpp/BakkesModInjectorC++/WindowsUtils.cpp" \ + "build/BakkesModInjectorCpp/BakkesModWPF/BakkesModWPF.cpp" \ + "build/BakkesModInjectorCpp/BakkesModInjectorC++/DllInjector.cpp" \ + "main.cpp" -o "dist/inject.exe" + +sandbox: + mkdir -p build dist;\ + [ ! -d build/powershell-wrapper-for-wine ] && git clone https://github.com/PietJankbal/powershell-wrapper-for-wine.git build/powershell-wrapper-for-wine;\ + git apply -q --directory=build/powershell-wrapper-for-wine sandbox.patch;\ + x86_64-w64-mingw32-gcc -O1 -fno-ident -fno-stack-protector -fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables -falign-functions=1 -falign-jumps=1 -falign-loops=1 -fwhole-program \ + -mconsole -municode -mno-stack-arg-probe -Xlinker --stack=0x200000,0x200000 -nostdlib -Wall -Wextra -ffreestanding build/powershell-wrapper-for-wine/main.c -lurlmon -lkernel32 -lucrtbase -nostdlib -lshell32 -lshlwapi -s -o dist/powershell64.exe;\ + i686-w64-mingw32-gcc -O1 -fno-ident -fno-stack-protector -fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables -falign-functions=1 -falign-jumps=1 -falign-loops=1 -fwhole-program \ + -mconsole -municode -mno-stack-arg-probe -Xlinker --stack=0x200000,0x200000 -nostdlib -Wall -Wextra -ffreestanding build/powershell-wrapper-for-wine/main.c -lurlmon -lkernel32 -lucrtbase -nostdlib -lshell32 -lshlwapi -s -o dist/powershell32.exe + +clean: + rm -rf build dist diff --git a/PKGBUILD b/PKGBUILD index eda7dbbc1a10..84f15371f8be 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -2,7 +2,7 @@ pkgname=bakkesmod-steam rlver=( 2 0 58 ) pkgver="${rlver[0]}.${rlver[2]}" -pkgrel=1 +pkgrel=2 pkgdesc="A mod aimed at making you better at Rocket League!" arch=('x86_64') url="https://bakkesmod.com/" @@ -21,21 +21,33 @@ optdepends=() rlstr=$(IFS=. ; echo "${rlver[*]}") rlesc=$(IFS=- ; echo "${rlver[*]}") pkgesc=`echo "$pkgver" | sed 's%\.%-%g'` -pwsh_sum='05ea332209f52b796a78246a89757a291f254fb6' source=( "dll-$rlesc.zip::https://github.com/bakkesmodorg/BakkesModInjectorCpp/releases/download/$rlstr/bakkesmod.zip" "src-$rlesc.zip::https://github.com/bakkesmodorg/BakkesModInjectorCpp/archive/refs/tags/$rlstr.zip" "loopback-$pkgesc-$pkgrel.zip::https://github.com/kentslaney/bakkesmod-arch/archive/refs/tags/$pkgver-$pkgrel-steam.zip" "https://github.com/kentslaney/bakkesmod-arch/releases/download/c369f24-1/inject.exe" - "pwshwrapper-${pwsh_sum:0:7}.zip::https://github.com/PietJankbal/powershell-wrapper-for-wine/archive/$pwsh_sum.zip" + + "https://github.com/kentslaney/bakkesmod-arch/releases/download/05ea332-1/powershell32.exe" + "https://github.com/kentslaney/bakkesmod-arch/releases/download/05ea332-1/powershell64.exe" + "https://github.com/PowerShell/PowerShell/releases/download/v7.4.1/PowerShell-7.4.1-win-x64.msi" + "https://github.com/Maximus5/ConEmu/releases/download/v23.07.24/ConEmuPack.230724.7z" + "https://www.7-zip.org/a/7z2501-x64.exe" + "https://raw.githubusercontent.com/PietJankbal/powershell-wrapper-for-wine/master/profile.ps1" ) + sha256sums=( '4184981c03f1d2df6458844c676d0fd7bf09d69d8d1894051f98c1638fc0609b' '99d1c6dfa5ec37113fc1ed4f1763c45aacd93981ffeefe6828330d234ff2a87b' 'SKIP' '0e038a4f0a2799f6aaa34f6560f5d1d41fba0cf26f8814571cebc94f5bb67a6e' - '79ac12ff72dad9c0f79f5658fa4fed7c4d92476c6eea77427aa2bc84964fcf94' + + '196886b557e632547d32354f20834e88ba3726df29a486c85d6409900064f364' + 'e8dae4079a66d5a1564c577bd27caf8c890a1044d9c56948581591e196e4ac8c' + '66c7c35ed9a46bd27e3d915dcf9a05e38b3f5ebb039883b92aa62ffea20fb187' + '2a9b98ebecaede62665ef427b05b3a5ccdac7bd3202414fc0f4c10825b4f4ea2' + '78afa2a1c773caf3cf7edf62f857d2a8a5da55fb0fff5da416074c0d28b2b55f' + 'b0fd5df54a2b281348ab03c2942b1e83278bee62c71e06d3d671724b49946593' ) build() { @@ -46,6 +58,7 @@ build() { unzip -qd "$tmp" "$srcdir/loopback-$pkgesc-$pkgrel.zip" mv "$tmp"/*/* "$srcdir" rm -fr "$tmp"/* "$tmp" + rm -rf "$srcdir/7zr.exe" && cp "$srcdir"/7z*-x64.exe "$srcdir/7zr.exe" } compile() { @@ -61,34 +74,6 @@ compile() { CXX_FLAGS=( "-std=c++17" "-static-libgcc" "-static-libstdc++" "-static" "-municode" "-mconsole" "-lpsapi" "-w" ) CXX_LD=( "-I$patches" "-I/usr/x86_64-w64-mingw32/include" "-I$ref/BakkesModInjectorC++" ) - # call injector with patched dll - cat <<" EOF" > "$srcdir/main.cpp" - #include "DllInjector.h" - #include - - int wmain(int argc, wchar_t* argv[]) { - std::wstring ps = L"RocketLeague.exe"; - const wchar_t* launcher = L"C:\\users\\steamuser\\AppData\\Roaming\\bakkesmod\\bakkesmod\\dll\\bakkesmod.dll"; - DllInjector dllInjector; - bool launching = false; - for (int i = 1; i < argc; i++) { - auto arg = std::wstring(argv[i]); - if (arg == L"launching") { - launching = true; - } - } - if (launching) { - std::cout << "Injector waiting for launch" << std::endl; - while (dllInjector.GetProcessID64(ps) == 0) { - Sleep(1000); - } - std::cout << "Found PID, attempting injection" << std::endl; - } - dllInjector.InjectDLL(ps, launcher); - return 0; - } - EOF - # std::search is defined in std::algorithm includes="#include " sed "s%pragma once%pragma once\n$includes%" \ @@ -120,6 +105,7 @@ proton_paths=$(cat <<'EOF' compat="$steamapps/compatdata/252950" if [ ! -f "$steamapps/compatdata/252950/config_info" ]; then echo "could not find steam's proton config for Rocket League" >&2 + echo "if on SteamOS, re-run from the deck account" >&2 exit 1 fi proton=`sed -n 3p "$compat/config_info" | xargs -d '\n' dirname` @@ -140,13 +126,29 @@ build_version() { echo "$RL_version.$( cat "$srcdir/version.txt" ).$pkgver.$pkgrel" } -powershell() { - cp -rf powershell64.exe "$WINEPREFIX/drive_c/windows/system32/WindowsPowerShell/v1.0/powershell.exe" - cp -rf powershell32.exe "$WINEPREFIX/drive_c/windows/syswow64/WindowsPowerShell/v1.0/powershell.exe" +powershell_installer() { "$1" 'C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe' -noni -c 'echo "powershell64_installed"' "$1" 'C:\windows\syswow64\WindowsPowerShell\v1.0\powershell.exe' -noni -c 'echo "powershell32_installed"' } +powershell() { + rm -f fsync + python sandbox.py > fsync & + sandbox_pid=$! + trap "if kill -0 '$sandbox_pid' &> /dev/null; then kill '$sandbox_pid'; fi" EXIT + echo -n "waiting for sandbox port " + tail -f fsync | grep -m 1 "." + + pth32="$WINEPREFIX/drive_c/windows/system32/WindowsPowerShell/v1.0/powershell.exe" + pth64="$WINEPREFIX/drive_c/windows/syswow64/WindowsPowerShell/v1.0/powershell.exe" + + cp -f powershell32_.exe "$pth32"; cp -f powershell64_.exe "$pth64"; + ( powershell_installer "$1" ) 2>/dev/null + cp -f powershell32.exe "$pth32"; cp -f powershell64.exe "$pth64"; + if kill -0 "$sandbox_pid" &> /dev/null; then kill "$sandbox_pid"; fi + rm -f fsync +} + package() { # used in this function and for running resulting exe files eval "$proton_paths" @@ -215,7 +217,7 @@ package() { if [ -f "$compat/pfx/drive_c/Program Files/PowerShell/7/pwsh.exe" ]; then echo "skipping powershell installation in favor of existing pwsh.exe" else - ( cd "$srcdir/powershell-wrapper-for-wine-$pwsh_sum" && WINEPREFIX="$compat/pfx/" powershell "$proton/bin/wine64") 2> /dev/null + ( cd "$srcdir" && WINEPREFIX="$compat/pfx/" powershell "$proton/bin/wine64" ) fi echo "to finish installing, update your launch options by prepending \"BAKKES=1\" or by setting them to \"BAKKES=1 %command%\" if none have been set yet" echo "to inject the bakkesmod DLL without the message box about version verification, also prepend \"PROMPTLESS=1\"" diff --git a/README.md b/README.md index 92a8ef181299..a39fbfa62c95 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,45 @@ # BakkesMod for (Arch) Linux and Steam Deck -> [!WARNING] -> EGS support is currently broken. Tracked in [issue #5](https://github.com/kentslaney/bakkesmod-arch/issues/5). - TL;DR: [AUR for steam](https://aur.archlinux.org/packages/bakkesmod-steam), [AUR for Heroic/Legendary](https://aur.archlinux.org/packages/bakkesmod-legendary) + ## Supported Environments There are two versions of the Rocket League: Steam and Epic Games Store (EGS). The EGS version is the only one available going forwards and support for that version is primarily built around the [Heroic Launcher](https://heroicgameslauncher.com/) ([GitHub](https://github.com/Heroic-Games-Launcher)). Heroic Launcher supports EGS games through a CLI tool called [Legendary](https://github.com/derrod/legendary) (which is why the AUR is called `bakkesmod-legendary`), but Heroic Launcher's settings will be updated as well if it's installed. This guide is built for Arch or its derivative SteamOS, which runs on the Steam Deck. SteamOS requires some additional steps to enable modifying the game files, which will be covered below. If you already have an Arch Linux setup with `yay`, you can skip to the [Platforms Section](#platforms). This repo currently relies on Arch Linux's `makepkg`, but most of the installation logic is portable, so it's possible that other distros will be added in the future. In the meantime, you can find cross-platform instructions at [CrumblyLiquid/BakkesLinux](https://github.com/CrumblyLiquid/BakkesLinux/blob/master/README.md), or read the [Bakkesmod issues thread for Linux](https://github.com/bakkesmodorg/BakkesMod2-Plugins/issues/2). -## Steam Deck Prep + +## Steam Deck The SteamOS file system is read-only by default and is re-imaged on SteamOS upgrade. This means that you will have to repeat this process when Rocket League (and therefore BakkesMod) updates, if there has been a system update since you last installed it. Steam system updates will not affect the existing BakkesMod installation. There is an alternative method for the Steam Deck without some of these problems in the [cross-platform instructions](https://github.com/CrumblyLiquid/BakkesLinux/blob/master/README.md). -Switch to [Desktop mode](https://help.steampowered.com/en/faqs/view/671A-4453-E8D2-323C) then open [Konsole](https://en.wikipedia.org/wiki/Konsole). +To start, switch to [Desktop mode](https://help.steampowered.com/en/faqs/view/671A-4453-E8D2-323C). + +### Install Heroic (EGS) +Open Discover (Flatpak GUI) +![The Discover application on SteamOS desktop mode](/../docs/discover.png) +Install Heroic +![Heroic on Flatpak GUI](/../docs/flatpak.png) +To make the launcher accessable directly from gaming mode, open Steam's desktop interface +![Steam GUI in desktop mode via icon shortcut](/../docs/desktop.png) +Add Heroic as a Non-Steam game via the bottom left menu +![Add Heroic Launcher to Gaming Mode](/../docs/non-steam.png) +You may also want to check "Add games to Steam automatically" in settings to make the games more directly accessable. + +### Switch from Proton to Wine (EGS & bakkesmod on SteamOS) +This step can be done after running the command to install via `yay`, but the game has to have been downloaded and run at least once for the install to work. Proton-GE (Heroic's default) is currently unsupported, so, in Heroic, go to Wine Manager and download Wine-GE latest +![Heroic's Wine Manager screen for Wine-GE](/../docs/manager.jpg) +then switch Rocket League's Wine version to Wine-GE +![Wine version selection on Rocket League's settings page in Heroic](/../docs/wine-select.jpg) + +### Install Yay (BakkesMod) +Open [Konsole](https://en.wikipedia.org/wiki/Konsole). ![The Konsole application on SteamOS desktop mode](/../docs/konsole.png) Don't do anything in this app with untrusted sources. [tinyurl.com/yay-steam](https://tinyurl.com/yay-steam) links to [`yay-steam.sh`](https://raw.githubusercontent.com/kentslaney/bakkesmod-arch/refs/heads/master/yay-steam.sh) in this repo. TinyURLs are changable, so this is still bad practice. Enter and run the following: ```bash curl -L tinyurl.com/yay-steam | sh ``` + ## Platforms -In order to disable BakkesMod, set the `BAKKES` enviornment variable to `0`. If you have the EGS version, continue reading. Otherwise, skip to the [Steam section](#steam). -## EGS (Heroic/Legendary) -> [!WARNING] -> EGS support is currently broken. Tracked in [issue #5](https://github.com/kentslaney/bakkesmod-arch/issues/5). +In order to disable BakkesMod, set the `BAKKES` enviornment variable to `0`. If you have the Steam version, continue reading. Otherwise, skip to the [EGS section](#egs-heroiclegendary). -Install the package with -```bash -yay -S bakkesmod-legendary -``` -Launching the game should now also launch BakkesMod, but to find the enviornment variable mentioned above, go to the settings icon on the upper right side of Rocket League's game page: - -![The Rocket League game page on Heroic](/../docs/heroic-settings.png) - -go to the advanced tab - -![The advanced tab](/../docs/advanced.png) - -and scroll down to the `Environment Variables` section - -![The environment variables section](/../docs/env.png) -## Steam +### Steam Install the package with ```bash yay -S bakkesmod-steam @@ -60,5 +62,25 @@ BAKKES=1 PROMPTLESS=1 %command% ``` My personal `Launch Options` on desktop are ```bash -BAKKES=1 PROMPTLESS=1 PROTON_LOG=1 WINEDEBUG=trace-unwind,warn+seh gamemoderun %command% -NoKeyboardUI +BAKKES=1 PROMPTLESS=1 PROTON_LOG=1 WINEDEBUG=trace-unwind,warn+seh gamemoderun %command% -NoKeyboardUI -nomovie ``` + +### EGS (Heroic/Legendary) +Install the package with +```bash +yay -S bakkesmod-legendary +``` +Launching the game should now also launch BakkesMod, but to find the enviornment variable mentioned above, go to the settings icon on the upper right side of Rocket League's game page: + +![The Rocket League game page on Heroic](/../docs/heroic-settings.png) + +go to the advanced tab + +![The advanced tab](/../docs/advanced.png) + +and scroll down to the `Environment Variables` section + +![The environment variables section](/../docs/env.png) + +## Disk recommendations +If you're running arch on desktop, LVM2 makes the filesystem management easier. If you're using the defaults on desktop, full disk encryption is also recommended, especially if advertising "arch btw". diff --git a/main.cpp b/main.cpp new file mode 100644 index 000000000000..38613953de14 --- /dev/null +++ b/main.cpp @@ -0,0 +1,24 @@ +#include "DllInjector.h" +#include + +int wmain(int argc, wchar_t* argv[]) { + std::wstring ps = L"RocketLeague.exe"; + const wchar_t* launcher = L"C:\\users\\steamuser\\AppData\\Roaming\\bakkesmod\\bakkesmod\\dll\\bakkesmod.dll"; + DllInjector dllInjector; + bool launching = false; + for (int i = 1; i < argc; i++) { + auto arg = std::wstring(argv[i]); + if (arg == L"launching") { + launching = true; + } + } + if (launching) { + std::cout << "Injector waiting for launch" << std::endl; + while (dllInjector.GetProcessID64(ps) == 0) { + Sleep(1000); + } + std::cout << "Found PID, attempting injection" << std::endl; + } + dllInjector.InjectDLL(ps, launcher); + return 0; +} diff --git a/mingw.patch b/mingw.patch new file mode 100644 index 000000000000..f366be9c233e --- /dev/null +++ b/mingw.patch @@ -0,0 +1,59 @@ +diff --git a/BakkesModInjectorC++/DllInjector.cpp b/BakkesModInjectorC++/DllInjector.cpp +index 1a5bf75..d578fdf 100644 +--- a/BakkesModInjectorC++/DllInjector.cpp ++++ b/BakkesModInjectorC++/DllInjector.cpp +@@ -48,7 +48,7 @@ void DllInjector::SetInjectionParameters(InjectionParameters ip) + } + + +-DWORD DllInjector::InjectDLL(std::wstring processName, std::filesystem::path path) ++DWORD DllInjector::InjectDLL(std::wstring processName, const wchar_t* path) + { + DWORD processID = GetProcessID64(processName); + if (processID == 0) +@@ -58,7 +58,7 @@ DWORD DllInjector::InjectDLL(std::wstring processName, std::filesystem::path pat + if (h) + { + LPVOID LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW"); +- auto ws = path.wstring().c_str(); ++ auto ws = path; + auto wslen = (std::wcslen(ws) + 1) * sizeof(WCHAR); + LPVOID dereercomp = VirtualAllocEx(h, NULL, wslen, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + WriteProcessMemory(h, dereercomp, ws, wslen, NULL); +diff --git a/BakkesModInjectorC++/DllInjector.h b/BakkesModInjectorC++/DllInjector.h +index 205f670..7a24705 100644 +--- a/BakkesModInjectorC++/DllInjector.h ++++ b/BakkesModInjectorC++/DllInjector.h +@@ -31,7 +31,7 @@ public: + ~DllInjector(); + InjectionParameters* GetInjectionParameters(); + void SetInjectionParameters(InjectionParameters ip); +- DWORD InjectDLL(std::wstring processName, std::filesystem::path path); ++ DWORD InjectDLL(std::wstring processName, const wchar_t* path); + DWORD GetProcessID64(std::wstring processName); + std::vector GetProcessIDS(std::wstring processName); + DWORD IsBakkesModDllInjected(std::wstring processName); +diff --git a/BakkesModInjectorC++/WindowsUtils.cpp b/BakkesModInjectorC++/WindowsUtils.cpp +index 3cc04c2..12eebd4 100644 +--- a/BakkesModInjectorC++/WindowsUtils.cpp ++++ b/BakkesModInjectorC++/WindowsUtils.cpp +@@ -20,8 +20,7 @@ WindowsUtils::~WindowsUtils() + { + } + +-std::string WindowsUtils::GetMyDocumentsFolder() +-{ ++std::string WindowsUtils::GetMyDocumentsFolder() { return "C:\\users\\steamuser\\Documents"; + LPWSTR wszPath = NULL; + HRESULT hr; + +diff --git a/BakkesModInjectorC++/WindowsUtils.h b/BakkesModInjectorC++/WindowsUtils.h +index 47458b2..1daddd0 100644 +--- a/BakkesModInjectorC++/WindowsUtils.h ++++ b/BakkesModInjectorC++/WindowsUtils.h +@@ -1,4 +1,5 @@ + #pragma once ++#include + #include + #include + #include diff --git a/sandbox.patch b/sandbox.patch new file mode 100644 index 000000000000..4745e1ce3703 --- /dev/null +++ b/sandbox.patch @@ -0,0 +1,37 @@ +diff --git a/main.c b/main.c +index 596f259..5222ad8 100644 +--- a/main.c ++++ b/main.c +@@ -81,7 +81,7 @@ int mainCRTStartup(void) + { + ExpandEnvironmentStringsW( L"%TMP%\\PowerShell-7.4.1-win-x64.msi", bufW, MAX_PATH + 1 ); + fputws(L"\033[1;33mDownloading Powershell Core",stderr);fputws(L"\033[0m\n",stderr); +- if( URLDownloadToFileW( NULL, L"https://github.com/PowerShell/PowerShell/releases/download/v7.4.1/PowerShell-7.4.1-win-x64.msi", bufW, 0, NULL ) != S_OK ) ++ if( URLDownloadToFileW( NULL, L"http://127.0.0.1:00000?pad=&url=https%3A%2F%2Fgithub.com%2FPowerShell%2FPowerShell%2Freleases%2Fdownload%2Fv7.4.1%2FPowerShell-7.4.1-win-x64.msi", bufW, 0, NULL ) != S_OK ) + { fputs("download failed",stderr ); exit(1); } + + memset( &si, 0, sizeof( STARTUPINFO )); si.cb = sizeof( STARTUPINFO ); memset( &pi, 0, sizeof( PROCESS_INFORMATION )); +@@ -91,12 +91,12 @@ int mainCRTStartup(void) + + ExpandEnvironmentStringsW( L"%TMP%\\ConEmuPack.230724.7z", bufW, MAX_PATH + 1 ); + fputws(L"\033[1;33mDownloading ConEmu",stderr);fputws(L"\033[0m\n",stderr); +- if( URLDownloadToFileW( NULL, L"https://github.com/Maximus5/ConEmu/releases/download/v23.07.24/ConEmuPack.230724.7z", bufW, 0, NULL ) != S_OK ) ++ if( URLDownloadToFileW( NULL, L"http://127.0.0.1:00000?pad=&url=https%3A%2F%2Fgithub.com%2FMaximus5%2FConEmu%2Freleases%2Fdownload%2Fv23.07.24%2FConEmuPack.230724.7z", bufW, 0, NULL ) != S_OK ) + { fputs("download failed",stderr ); exit(1); } + + ExpandEnvironmentStringsW( L"%TMP%\\7zr.exe", bufW, MAX_PATH + 1 ); + fputws(L"\033[1;33mDownloading 7zr",stderr);fputws(L"\033[0m\n",stderr); +- if( URLDownloadToFileW( NULL, L"https://www.7-zip.org/a/7zr.exe", bufW, 0, NULL ) != S_OK ) ++ if( URLDownloadToFileW( NULL, L"http://127.0.0.1:00000?pad=&url=https%3A%2F%2Fwww.7-zip.org%2Fa%2F7zr.exe", bufW, 0, NULL ) != S_OK ) + { fputs("download failed",stderr ); exit(1); } + + memset( &si, 0, sizeof( STARTUPINFO ) ); si.cb = sizeof( STARTUPINFO ); memset( &pi , 0, sizeof( PROCESS_INFORMATION ) ); +@@ -106,7 +106,7 @@ int mainCRTStartup(void) + + fputws(L"\033[1;33mDownloading profile.ps1",stderr);fputws(L"\033[0m\n",stderr); + ExpandEnvironmentStringsW( L"%ProgramW6432%\\Powershell\\7\\profile.ps1", bufW, MAX_PATH + 1 ); +- if( URLDownloadToFileW(NULL, L"https://raw.githubusercontent.com/PietJankbal/powershell-wrapper-for-wine/master/profile.ps1", bufW, 0, NULL) != S_OK ) ++ if( URLDownloadToFileW(NULL, L"http://127.0.0.1:00000?pad=&url=https%3A%2F%2Fraw.githubusercontent.com%2FPietJankbal%2Fpowershell-wrapper-for-wine%2Fmaster%2Fprofile.ps1", bufW, 0, NULL) != S_OK ) + { fputs("download failed",stderr ); exit(1); } + } + /* Main program: wrap the original powershell-commandline into correct syntax, and send it to pwsh.exe */ diff --git a/sandbox.py b/sandbox.py new file mode 100644 index 000000000000..8142229797de --- /dev/null +++ b/sandbox.py @@ -0,0 +1,58 @@ +import sys, http.server +from urllib.parse import urlparse, parse_qs + +urls = { + "https://github.com/PowerShell/PowerShell/releases/download/v7.4.1/PowerShell-7.4.1-win-x64.msi": "application/octet-stream", + "https://github.com/Maximus5/ConEmu/releases/download/v23.07.24/ConEmuPack.230724.7z": "application/octet-stream", + "https://www.7-zip.org/a/7zr.exe": "application/octet-stream", + "https://raw.githubusercontent.com/PietJankbal/powershell-wrapper-for-wine/master/profile.ps1": "text/plain; charset=utf-8" +} + +class SourcesSandbox(http.server.BaseHTTPRequestHandler): + def do_GET(self): + query = parse_qs(urlparse(self.path).query) + try: + url = next(iter(query.get("url", []))) + except StopIteration: + self.send_error(400) + return + if url not in urls: + self.send_error(404) + return + fname = url.rsplit("/", 1)[-1] + with open(fname, 'rb') as fp: + content = fp.read() + + self.send_response(200) + self.send_header('content-type', urls[url]) + self.send_header('content-length', str(len(content))) + self.send_header('content-disposition', f'attachment; filename={fname}') + self.end_headers() + self.wfile.write(content) + +widen = lambda x: bytes(sum(([i, 0] for i in x), [])) +placeholder = widen(b'http://127.0.0.1:00000?pad=&url=') + +def padded(port): + assert 0 < int(port) <= 65_535 + pad = 5 - len(str(port)) + res = widen(f"http://127.0.0.1:{port}?pad={'-' * pad}&url=".encode()) + assert len(res) == len(placeholder) + return res + +def patch(port): + for arch in [32, 64]: + with open(f"powershell{arch}.exe", 'rb') as fp: + f = fp.read() + with open(f"powershell{arch}_.exe", 'wb') as fp: + fp.write(f.replace(placeholder, padded(port))) + print(port) + sys.stdout.flush() + +def run_server(): + httpd = http.server.HTTPServer(('', 0), SourcesSandbox) + patch(httpd.server_address[1]) + httpd.serve_forever() + +if __name__ == "__main__": + run_server()