Created
August 16, 2021 04:26
-
-
Save bburky/9abb40556bba56e745a5e78e47797733 to your computer and use it in GitHub Desktop.
Inject Steam GameOverlayRenderer DLL into a game with Frida
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Inject Steam GameOverlayRenderer DLL into a game | |
// | |
// Inspired by https://gist.github.com/Andon13/d439d5334d8173e5b959f383f1c49b03 | |
// | |
// Must be run during process initialization, cannot be run after the game is | |
// started. | |
// | |
// GameOverlayRenderer will use an appid from the SteamGameId environment | |
// variable. This is injected too. GameOverlayRenderer does not support | |
// steam_appid.txt, but this script will parse the file to discover the appid. | |
// | |
// Usage: | |
// cd the\game\directory | |
// frida -f "game.exe" -l C:\somewhere\GameOverlayRenderer.js --no-pause | |
function getSteamPath() { | |
const HKEY_LOCAL_MACHINE = ptr("0x80000002"); | |
const ERROR_SUCCESS = 0; | |
const RRF_RT_REG_SZ = 0x00000002; | |
const reg_subkey_32 = Memory.allocUtf8String("Software\\Valve\\Steam"); | |
const reg_subkey_64 = Memory.allocUtf8String("SOFTWARE\\WOW6432Node\\Valve\\Steam"); | |
const reg_value = Memory.allocUtf8String("InstallPath"); | |
const reg_data = Memory.alloc(255); | |
const reg_data_size = Memory.alloc(4); | |
reg_data_size.writeInt(255); | |
const RegGetValueA_ptr = Module.findExportByName("Advapi32.dll", "RegGetValueA"); | |
const RegGetValueA = new NativeFunction(RegGetValueA_ptr, "int32", ["pointer", "pointer", "pointer", "uint32", "pointer", "pointer", "pointer"]); | |
if (ERROR_SUCCESS == RegGetValueA(HKEY_LOCAL_MACHINE, reg_subkey_32, reg_value, RRF_RT_REG_SZ, ptr(0), reg_data, reg_data_size)) { | |
return Memory.readAnsiString(reg_data); | |
} else if (ERROR_SUCCESS == RegGetValueA(HKEY_LOCAL_MACHINE, reg_subkey_64, reg_value, RRF_RT_REG_SZ, ptr(0), reg_data, reg_data_size)) { | |
return Memory.readAnsiString(reg_data); | |
} else { | |
return null; | |
} | |
} | |
function readSteamAppIdTxt() { | |
const buffer = Memory.alloc(256) | |
let appid; | |
const fopen_ptr = Module.findExportByName("msvcrt.dll", "fopen"); | |
const fopen = new NativeFunction(fopen_ptr, "pointer", ["pointer", "pointer"]); | |
const fread_ptr = Module.findExportByName("msvcrt.dll", "fread"); | |
const fread = new NativeFunction(fread_ptr, "size_t", ["pointer", "size_t", "size_t", "pointer"]); | |
const fclose_ptr = Module.findExportByName("msvcrt.dll", "fclose"); | |
const fclose = new NativeFunction(fclose_ptr, "int", ["pointer"]); | |
const file = fopen(Memory.allocUtf8String("steam_appid.txt"), Memory.allocUtf8String("r")) | |
if (file.isNull()) { | |
return null; | |
} | |
if (fread(buffer, 1, 255, file)) { | |
appid = Memory.readCString(buffer); | |
} | |
if (fclose(file)) { | |
console.log("Failed to close steam_appid.txt file handle"); | |
} | |
// Return appid cast to a number | |
return +appid; | |
} | |
function setEnvironmentVariable(name, value) { | |
const name_ptr = Memory.allocUtf8String(name); | |
const value_ptr = Memory.allocUtf8String(value); | |
const SetEnvironmentVariableA_ptr = Module.findExportByName("kernel32.dll", "SetEnvironmentVariableA"); | |
const SetEnvironmentVariableA = new NativeFunction(SetEnvironmentVariableA_ptr, "int", ["pointer", "pointer"]); | |
return SetEnvironmentVariableA(name_ptr, value_ptr); | |
} | |
rpc.exports = { | |
init: function(stage, parameters) { | |
try { | |
console.log("Injecting GameOverlayRenderer..."); | |
const dll_name = Process.arch == "x64" ? "GameOverlayRenderer64.dll" : "GameOverlayRenderer.dll"; | |
const steam_path = getSteamPath(); | |
if (!steam_path) { | |
console.log("Failed to find Steam install path in registry"); | |
return; | |
} | |
const appid = readSteamAppIdTxt(); | |
if (appid) { | |
if (!setEnvironmentVariable("SteamGameId", `${appid}`)) { | |
console.log("Failed to set SteamGameId environment variable"); | |
} | |
} else { | |
console.log("Failed to read appid from steam_appid.txt (is the current working directory set correctly?)"); | |
} | |
if (!Module.load(`${steam_path}\\${dll_name}`)) { | |
console.log("Failed to load GameOverlayRenderer"); | |
return; | |
} | |
console.log("Done injecting GameOverlayRenderer."); | |
} catch (e) { | |
console.log(e) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment