mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2025-07-25 21:04:01 +00:00
124 lines
3.3 KiB
Python
124 lines
3.3 KiB
Python
"""
|
|
Simple process that uses Fria to inspect the HTTP headers, and sent data during a Skyrim/Fallout login to Bethesda.NET. That data is output to the screen and can later be used to
|
|
allow Wabbajack to log into Bethesda.NET.
|
|
"""
|
|
|
|
import frida
|
|
import sys
|
|
from subprocess import Popen, PIPE
|
|
import psutil, time, json
|
|
from pathlib import Path
|
|
|
|
known_headers = {}
|
|
shutdown = False
|
|
|
|
|
|
def on_message(message, data):
|
|
msg_type, msg_data = message["payload"]
|
|
if msg_type == "header":
|
|
header, value = msg_data.split(": ")
|
|
if header not in known_headers:
|
|
known_headers[header] = value
|
|
if msg_type == "data":
|
|
try:
|
|
data = json.loads(msg_data)
|
|
if "scheme" in data and "language" in data and "payload" in data:
|
|
shutdown_and_print(data)
|
|
except:
|
|
return
|
|
|
|
|
|
def main(target_process):
|
|
session = frida.attach(target_process)
|
|
|
|
script = session.create_script("""
|
|
|
|
// Find base address of current imported jvm.dll by main process fledge.exe
|
|
var reqHeaders = Module.getExportByName('winhttp.dll', 'WinHttpAddRequestHeaders');
|
|
|
|
Interceptor.attach(reqHeaders, { // Intercept calls to our SetAesDecrypt function
|
|
|
|
// When function is called, print out its parameters
|
|
onEnter: function (args) {
|
|
send(['header', args[1].readUtf16String(args[2].toInt32())]);
|
|
|
|
},
|
|
// When function is finished
|
|
onLeave: function (retval) {
|
|
}
|
|
});
|
|
|
|
var reqHeaders = Module.getExportByName('winhttp.dll', 'WinHttpWriteData');
|
|
console.log("WinHttpAddRequestHeaders: " + reqHeaders);
|
|
|
|
Interceptor.attach(reqHeaders, { // Intercept calls to our SetAesDecrypt function
|
|
|
|
// When function is called, print out its parameters
|
|
onEnter: function (args) {
|
|
send(['data', args[1].readUtf8String(args[2].toInt32())]);
|
|
|
|
},
|
|
// When function is finished
|
|
onLeave: function (retval) {
|
|
}
|
|
});
|
|
|
|
|
|
""")
|
|
script.on('message', on_message)
|
|
script.load()
|
|
|
|
while not shutdown and psutil.pid_exists(target_process):
|
|
time.sleep(0.5)
|
|
|
|
session.detach()
|
|
sys.exit(1)
|
|
|
|
|
|
def wait_for_game(started, name):
|
|
no_exe = 0
|
|
parent_path = Path(started).parent
|
|
while True:
|
|
found = False
|
|
time.sleep(1)
|
|
for proc in psutil.process_iter():
|
|
try:
|
|
if Path(proc.exe()).parent == parent_path:
|
|
no_exe = 0
|
|
found = True
|
|
except:
|
|
pass
|
|
if proc.name() == name:
|
|
return proc.pid
|
|
|
|
if not found:
|
|
print("Not Found " + str(no_exe))
|
|
no_exe += 1
|
|
if no_exe == 3:
|
|
sys.exit(1)
|
|
|
|
|
|
def shutdown_and_print(data):
|
|
global shutdown
|
|
output = {"body": json.dumps(data), "headers": known_headers}
|
|
|
|
print(json.dumps(output))
|
|
|
|
for proc in psutil.process_iter():
|
|
if proc.pid == pid:
|
|
proc.kill()
|
|
break
|
|
|
|
shutdown = True
|
|
|
|
|
|
if __name__ == '__main__':
|
|
start = """C:\Steam\steamapps\common\Skyrim Special Edition\SkyrimSE.exe"""
|
|
wait_for = "SkyrimSE.exe"
|
|
if len(sys.argv) == 3:
|
|
start = sys.argv[1]
|
|
wait_for = sys.argv[2]
|
|
target_process = Popen([start])
|
|
pid = wait_for_game(start, wait_for)
|
|
main(pid)
|