Function bodies 388 total
generate_test_vectors function · python · L511-L573 (63 LOC)research/tools/iv_context_generator.py
def generate_test_vectors(pin_str: str, include_direct: bool = True):
"""
Generate all test vectors for all device types and all IV contexts.
Returns a list of dicts, each containing everything needed for a test.
"""
contexts = generate_all_contexts(pin_str)
# Use a fixed km for reproducibility in test vectors
km = bytes([0x41] * 16) # deterministic for vector generation
vectors = []
device_configs = DEVICE_TYPES + (DEVICE_TYPES_DIRECT if include_direct else [])
for dev in device_configs:
if dev["derive_key"] is None:
# Unknown crypto (e.g., VITA) — skip encryption but note it
for ctx, label, category in contexts:
vectors.append({
"device": dev["name"],
"menu_label": dev["menu_label"],
"client_type": dev["client_type"],
"note": dev["note"],
"context_label": label,
"context_cateverify_captured_data function · python · L580-L672 (93 LOC)research/tools/iv_context_generator.py
def verify_captured_data(pin_str: str, captured_hex: str):
"""
Try all IV context variants to decrypt captured registration data.
The captured data should be the encrypted body (without the trailing km).
If the captured data includes km appended, the last 16 bytes are km.
"""
captured = bytes.fromhex(captured_hex)
# If captured data is > 16 bytes and length-16 is divisible by 16,
# assume last 16 bytes are km
if len(captured) > 16 and (len(captured) - 16) % 16 == 0:
enc_body = captured[:-16]
km = captured[-16:]
print(f"Assuming last 16 bytes are km: {km.hex()}")
print(f"Encrypted body: {len(enc_body)} bytes")
else:
enc_body = captured
km = None
print(f"No km detected. Encrypted body: {len(enc_body)} bytes")
if len(enc_body) % 16 != 0:
print(f"ERROR: Encrypted body length ({len(enc_body)}) is not a multiple of 16!")
return
contexts = generate_all_contexts(pin_str)
print_text_output function · python · L679-L738 (60 LOC)research/tools/iv_context_generator.py
def print_text_output(vectors, pin_str):
"""Print human-readable output."""
print(f"{'='*78}")
print(f"PS3 Remote Play Registration — IV Context Test Vectors")
print(f"PIN: {pin_str}")
print(f"Total vectors: {len(vectors)}")
print(f"{'='*78}\n")
# Print static key reference
print("STATIC KEYS REFERENCE:")
print(f" SKEY0: {SKEY0.hex()}")
print(f" SKEY1: {SKEY1.hex()} <-- loaded but UNUSED in open-rp!")
print(f" SKEY2: {SKEY2.hex()}")
print(f" PSP_XOR: {PSP_XOR.hex()}")
print(f" PSP_IV: {PSP_IV.hex()}")
print(f" PHONE_XOR: {PHONE_XOR.hex()}")
print(f" PHONE_IV: {PHONE_IV.hex()}")
print(f" PC_XOR: {PC_XOR.hex()}")
print(f" PC_IV: {PC_IV.hex()}")
print()
# Group by device
current_device = None
for v in vectors:
if v["device"] != current_device:
current_device = v["device"]
print(f"\n{'='*78}")
print(f"DEVICE: {v['device']} | {v['menu_labprint_json_output function · python · L741-L759 (19 LOC)research/tools/iv_context_generator.py
def print_json_output(vectors, pin_str):
"""Print JSON output for programmatic use."""
output = {
"pin": pin_str,
"total_vectors": len(vectors),
"static_keys": {
"skey0": SKEY0.hex(),
"skey1": SKEY1.hex(),
"skey2": SKEY2.hex(),
"psp_xor": PSP_XOR.hex(),
"psp_iv": PSP_IV.hex(),
"phone_xor": PHONE_XOR.hex(),
"phone_iv": PHONE_IV.hex(),
"pc_xor": PC_XOR.hex(),
"pc_iv": PC_IV.hex(),
},
"vectors": vectors,
}
print(json.dumps(output, indent=2))print_summary function · python · L762-L781 (20 LOC)research/tools/iv_context_generator.py
def print_summary(vectors, pin_str):
"""Print summary counts."""
contexts = generate_all_contexts(pin_str)
print(f"PIN: {pin_str}")
print(f"Unique IV context values: {len(contexts)}")
# Count by category
from collections import Counter
cat_counts = Counter(c[2] for c in contexts)
print(f"\nBy category:")
for cat, count in sorted(cat_counts.items()):
print(f" {cat:20s}: {count}")
# Count by device type
active = sum(1 for d in DEVICE_TYPES if d["derive_key"] is not None)
direct = sum(1 for d in DEVICE_TYPES_DIRECT if d["derive_key"] is not None)
print(f"\nDevice types (shifted): {len(DEVICE_TYPES)} ({active} with known crypto)")
print(f"Device types (direct): {len(DEVICE_TYPES_DIRECT)} ({direct} with known crypto)")
print(f"\nTotal test vectors: {len(contexts)} contexts x {active + direct} device types = {len(contexts) * (active + direct)}")
print(f" (plus {len(contexts)} skipped for unknown VITA crypto)")main function · python · L788-L837 (50 LOC)research/tools/iv_context_generator.py
def main():
parser = argparse.ArgumentParser(
description="PS3 Remote Play Registration — IV Context Test Vector Generator",
epilog=(
"Examples:\n"
" %(prog)s 12345678 Generate all vectors for PIN 12345678\n"
" %(prog)s 12345678 --json JSON output\n"
" %(prog)s 12345678 --summary Just show counts\n"
" %(prog)s 12345678 --verify AABB... Try decrypting captured data\n"
),
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("pin", help="8-digit PIN from PS3 registration screen")
parser.add_argument("--json", action="store_true", help="Output as JSON")
parser.add_argument("--summary", action="store_true", help="Print summary counts only")
parser.add_argument("--verify", metavar="HEXDATA",
help="Hex-encoded captured registration data to try decrypting")
parser.add_argumenfind_all function · python · L7-L16 (10 LOC)research/tools/parse_xregistry.py
def find_all(data, needle):
"""Find all occurrences of needle in data"""
results = []
start = 0
while True:
pos = data.find(needle, start)
if pos == -1: break
results.append(pos)
start = pos + 1
return resultsRepobility · code-quality intelligence · https://repobility.com
read_xreg_value function · python · L18-L41 (24 LOC)research/tools/parse_xregistry.py
def read_xreg_value(data, path_str):
"""Find a registry path and try to read its associated value"""
path_bytes = path_str.encode('ascii')
positions = find_all(data, path_bytes)
results = []
for pos in positions:
# The value data is typically stored at an offset referenced before or after the path
# xRegistry format: each entry has a header with offset, type, and path
# Look at bytes before the path for metadata
if pos >= 4:
# Check 4 bytes before path start for potential offset/metadata
pre = data[pos-4:pos]
# After the path null terminator, look for value data
null_pos = data.find(b'\x00', pos + len(path_bytes))
if null_pos > 0 and null_pos < pos + len(path_bytes) + 2:
after = data[null_pos+1:null_pos+33]
results.append({
'path': path_str,
'offset': pos,
'pre_bytes': pre.hex(),
find_data_section function · python · L43-L53 (11 LOC)research/tools/parse_xregistry.py
def find_data_section(data, path_str):
"""
xRegistry entries reference data stored elsewhere.
The format has entry headers that point to data offsets.
Let's find the data area and extract values.
"""
# The xRegistry has a header section with path entries and a data section
# Data section typically starts after all path entries
# Each path entry contains: some header bytes, type byte, path string
# The data is stored at offsets referenced in the header
passmain function · python · L55-L164 (110 LOC)research/tools/parse_xregistry.py
def main():
if len(sys.argv) < 2:
print("Usage: python3 parse_xregistry.py <xRegistry.sys> [inject]")
sys.exit(1)
xreg_path = sys.argv[1]
data = open(xreg_path, 'rb').read()
print(f"xRegistry.sys: {len(data)} bytes")
# Find all premo-related paths
premo_paths = [
"/setting/premo/remoteBoot",
"/setting/premo/bootCount",
"/setting/premo/audioConfig",
]
# Find PSP slots
for slot in range(1, 9):
slot_name = f"psp{slot:02d}"
base = f"/setting/premo/{slot_name}"
for field in ['nickname', 'macAddress', 'id', 'keyType', 'key']:
path = f"{base}/{field}"
if path.encode('ascii') in data:
premo_paths.append(path)
print(f"\n=== Found {len(premo_paths)} premo registry entries ===\n")
# For each path, find where it is and dump surrounding bytes
for path in premo_paths:
path_bytes = path.encode('ascii')
pos = data.find(path_bytes)
PS3MAPIConnection class · python · L44-L121 (78 LOC)research/tools/ps3mapi_ctx_dump.py
class PS3MAPIConnection:
"""Telnet-style connection to PS3MAPI server (port 7887)."""
def __init__(self, ip, port=7887, timeout=10):
self.ip = ip
self.port = port
self.timeout = timeout
self.sock = None
self.buffer = b""
def connect(self):
print(f"[*] Connecting to PS3MAPI at {self.ip}:{self.port}...")
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(self.timeout)
try:
self.sock.connect((self.ip, self.port))
except Exception as e:
print(f"[!] Connection failed: {e}")
raise
banner = self._recv_line()
print(f"[+] Connected. Banner: {banner}")
return banner
def _recv_line(self):
"""Read until we get a complete response line."""
while b"\r\n" not in self.buffer and b"\n" not in self.buffer:
try:
chunk = self.sock.recv(4096)
if not chunk:
__init__ method · python · L47-L52 (6 LOC)research/tools/ps3mapi_ctx_dump.py
def __init__(self, ip, port=7887, timeout=10):
self.ip = ip
self.port = port
self.timeout = timeout
self.sock = None
self.buffer = b""connect method · python · L54-L65 (12 LOC)research/tools/ps3mapi_ctx_dump.py
def connect(self):
print(f"[*] Connecting to PS3MAPI at {self.ip}:{self.port}...")
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(self.timeout)
try:
self.sock.connect((self.ip, self.port))
except Exception as e:
print(f"[!] Connection failed: {e}")
raise
banner = self._recv_line()
print(f"[+] Connected. Banner: {banner}")
return banner_recv_line method · python · L67-L86 (20 LOC)research/tools/ps3mapi_ctx_dump.py
def _recv_line(self):
"""Read until we get a complete response line."""
while b"\r\n" not in self.buffer and b"\n" not in self.buffer:
try:
chunk = self.sock.recv(4096)
if not chunk:
break
self.buffer += chunk
except socket.timeout:
break
if b"\r\n" in self.buffer:
line, self.buffer = self.buffer.split(b"\r\n", 1)
elif b"\n" in self.buffer:
line, self.buffer = self.buffer.split(b"\n", 1)
else:
line = self.buffer
self.buffer = b""
return line.decode(errors="replace").strip()send method · python · L88-L95 (8 LOC)research/tools/ps3mapi_ctx_dump.py
def send(self, cmd):
"""Send a command and return the response."""
print(f" > {cmd}")
self.sock.send((cmd + "\r\n").encode())
time.sleep(0.3)
resp = self._recv_line()
print(f" < {resp}")
return respMethodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
send_raw method · python · L97-L113 (17 LOC)research/tools/ps3mapi_ctx_dump.py
def send_raw(self, cmd):
"""Send and return raw bytes (for memory reads)."""
print(f" > {cmd}")
self.sock.send((cmd + "\r\n").encode())
time.sleep(0.5)
# Read all available data
data = self.buffer
self.buffer = b""
while True:
try:
chunk = self.sock.recv(65536)
if not chunk:
break
data += chunk
except socket.timeout:
break
return dataclose method · python · L115-L121 (7 LOC)research/tools/ps3mapi_ctx_dump.py
def close(self):
if self.sock:
try:
self.send("DISCONNECT")
except:
pass
self.sock.close()dump_iv_context function · python · L124-L164 (41 LOC)research/tools/ps3mapi_ctx_dump.py
def dump_iv_context(ip, vsh_pid, addresses_to_try):
"""
Try to dump 8 bytes from the IV context struct using various addresses.
Args:
ip: PS3 IP address
vsh_pid: VSH process ID (from process enumeration)
addresses_to_try: List of (address, label) tuples to attempt
Returns:
Tuple of (raw_bytes, address_used) or (None, None) if all fail
"""
api = PS3MAPIConnection(ip)
try:
api.connect()
# Attempt auth (not always required)
for auth_cmd in ["USER anonymous", "PASS anonymous"]:
try:
api.send(auth_cmd)
except:
pass
except:
return None, None
for addr, label in addresses_to_try:
try:
print(f"\n[*] Trying address {label} (0x{addr:016X})...")
resp = api.send_raw(f"MEMORY GET {vsh_pid} {addr} 8")
if resp and len(resp) >= 8:
ctx_bytes = resp[:8]
print(f"[+] Got 8 bgenerate_test_contexts function · python · L167-L346 (180 LOC)research/tools/ps3mapi_ctx_dump.py
def generate_test_contexts(pin_str):
"""
Generate all plausible 8-byte IV context values from the PIN.
Returns dict mapping label -> bytes.
"""
pin_int = int(pin_str)
contexts = {}
def add(data, label):
assert len(data) == 8, f"Context must be 8 bytes, got {len(data)} for {label}"
contexts[label] = data
# =========================================================================
# PIN-based interpretations
# =========================================================================
add(bytes(8), "all_zeros")
add(pin_int.to_bytes(8, 'big'), "pin_be64")
add(pin_int.to_bytes(8, 'little'), "pin_le64")
add(pin_int.to_bytes(4, 'big') + b'\x00\x00\x00\x00', "pin_be32_left")
add(b'\x00\x00\x00\x00' + pin_int.to_bytes(4, 'big'), "pin_be32_right")
add(pin_int.to_bytes(4, 'little') + b'\x00\x00\x00\x00', "pin_le32_left")
add(b'\x00\x00\x00\x00' + pin_int.to_bytes(4, 'little'), "pin_le32_right")
add(pin_str.efind_vsh_pid function · python · L349-L413 (65 LOC)research/tools/ps3mapi_ctx_dump.py
def find_vsh_pid(ip):
"""
Connect to PS3MAPI and enumerate processes to find VSH.
Returns (vsh_pid, sysconf_prx_id) or (None, None) if not found.
"""
api = PS3MAPIConnection(ip)
try:
api.connect()
# Auth attempts
for auth_cmd in ["USER anonymous", "PASS anonymous"]:
try:
api.send(auth_cmd)
except:
pass
except:
print("[!] Cannot connect to PS3MAPI")
return None, None
try:
# Get all processes
print("\n[*] Enumerating processes...")
resp = api.send("PROCESS GETALLPID")
pids = []
parts = resp.split()
for part in parts:
for sub in part.split("|"):
sub = sub.strip()
try:
pid = int(sub, 0)
if pid > 0:
pids.append(pid)
except ValueError:
continue
if not pids:
main function · python · L416-L504 (89 LOC)research/tools/ps3mapi_ctx_dump.py
def main():
if len(sys.argv) < 2:
print("Usage: python3 ps3mapi_ctx_dump.py <PIN> [ps3_ip]")
print()
print("Example:")
print(" python3 ps3mapi_ctx_dump.py 12345678")
print(" python3 ps3mapi_ctx_dump.py 12345678 192.168.1.80")
sys.exit(1)
pin_str = sys.argv[1]
ps3_ip = sys.argv[2] if len(sys.argv) > 2 else "192.168.1.80"
if not pin_str.isdigit() or len(pin_str) != 8:
print("[!] PIN must be exactly 8 digits")
sys.exit(1)
print("=" * 70)
print(" PS3MAPI IV Context Dumper")
print(f" Target: {ps3_ip}")
print(f" PIN: {pin_str}")
print("=" * 70)
print()
print("IMPORTANT: PS3 must be in registration mode (showing PIN screen)")
print()
# Find VSH PID
vsh_pid, _ = find_vsh_pid(ps3_ip)
if not vsh_pid:
print("[!] Could not find VSH process. Exiting.")
sys.exit(1)
# Try various addresses for IV context struct
# sysconf base is 0x01B60000 + BSSPS3MAPIConnection class · python · L45-L130 (86 LOC)research/tools/ps3mapi_dump.py
class PS3MAPIConnection:
"""Telnet-style connection to PS3MAPI server (port 7887)."""
def __init__(self, ip, port=7887, timeout=10):
self.ip = ip
self.port = port
self.timeout = timeout
self.sock = None
self.buffer = b""
def connect(self):
print(f"[*] Connecting to PS3MAPI at {self.ip}:{self.port}...")
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(self.timeout)
self.sock.connect((self.ip, self.port))
banner = self._recv_line()
print(f"[+] Banner: {banner}")
return banner
def _recv_line(self):
"""Read until we get a complete response line."""
while b"\r\n" not in self.buffer and b"\n" not in self.buffer:
try:
chunk = self.sock.recv(4096)
if not chunk:
break
self.buffer += chunk
except socket.timeout:
break
__init__ method · python · L48-L53 (6 LOC)research/tools/ps3mapi_dump.py
def __init__(self, ip, port=7887, timeout=10):
self.ip = ip
self.port = port
self.timeout = timeout
self.sock = None
self.buffer = b""Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
connect method · python · L55-L62 (8 LOC)research/tools/ps3mapi_dump.py
def connect(self):
print(f"[*] Connecting to PS3MAPI at {self.ip}:{self.port}...")
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(self.timeout)
self.sock.connect((self.ip, self.port))
banner = self._recv_line()
print(f"[+] Banner: {banner}")
return banner_recv_line method · python · L64-L83 (20 LOC)research/tools/ps3mapi_dump.py
def _recv_line(self):
"""Read until we get a complete response line."""
while b"\r\n" not in self.buffer and b"\n" not in self.buffer:
try:
chunk = self.sock.recv(4096)
if not chunk:
break
self.buffer += chunk
except socket.timeout:
break
if b"\r\n" in self.buffer:
line, self.buffer = self.buffer.split(b"\r\n", 1)
elif b"\n" in self.buffer:
line, self.buffer = self.buffer.split(b"\n", 1)
else:
line = self.buffer
self.buffer = b""
return line.decode(errors="replace").strip()_recv_all_lines method · python · L85-L96 (12 LOC)research/tools/ps3mapi_dump.py
def _recv_all_lines(self, max_lines=50):
"""Read multiple response lines (for multi-line responses)."""
lines = []
for _ in range(max_lines):
line = self._recv_line()
if not line:
break
lines.append(line)
# If we got a status code line, that's the end
if line and line[0].isdigit():
break
return linessend method · python · L98-L105 (8 LOC)research/tools/ps3mapi_dump.py
def send(self, cmd):
"""Send a command and return the response."""
print(f" > {cmd}")
self.sock.send((cmd + "\r\n").encode())
time.sleep(0.3)
resp = self._recv_line()
print(f" < {resp}")
return respsend_raw method · python · L107-L122 (16 LOC)research/tools/ps3mapi_dump.py
def send_raw(self, cmd):
"""Send and return raw bytes (for memory reads)."""
self.sock.send((cmd + "\r\n").encode())
time.sleep(0.5)
# Read all available data
data = self.buffer
self.buffer = b""
while True:
try:
chunk = self.sock.recv(65536)
if not chunk:
break
data += chunk
except socket.timeout:
break
return dataclose method · python · L124-L130 (7 LOC)research/tools/ps3mapi_dump.py
def close(self):
if self.sock:
try:
self.send("DISCONNECT")
except:
pass
self.sock.close()phase1_ps3mapi function · python · L133-L299 (167 LOC)research/tools/ps3mapi_dump.py
def phase1_ps3mapi(ip):
"""Phase 1: Enumerate processes and modules via PS3MAPI telnet."""
print("\n" + "=" * 60)
print("PHASE 1: PS3MAPI Process & Module Enumeration")
print("=" * 60)
api = PS3MAPIConnection(ip)
try:
api.connect()
except Exception as e:
print(f"[!] Cannot connect to PS3MAPI port {PS3MAPI_PORT}: {e}")
print(" Is webMAN-MOD installed? Is PS3MAPI enabled in webMAN settings?")
return None
# Some PS3MAPI implementations need authentication
for auth_cmd in [
"USER anonymous", "PASS anonymous",
"USER root", "PASS root",
]:
try:
resp = api.send(auth_cmd)
if "230" in resp or "OK" in resp.upper():
print(f"[+] Authenticated: {resp}")
break
except:
pass
# Get PS3 info
try:
resp = api.send("PS3 GETFWVERSION")
print(f"[+] FW Version: {resp}")
resp = api.send("PS3 GETFWTYPE")
phase2_webman_recon function · python · L302-L332 (31 LOC)research/tools/ps3mapi_dump.py
def phase2_webman_recon(ip):
"""Phase 2: Gather info via webMAN's HTTP interface as backup."""
print("\n" + "=" * 60)
print("PHASE 2: webMAN HTTP Reconnaissance")
print("=" * 60)
urls = [
f"http://{ip}/cpursx.ps3",
f"http://{ip}/setup.ps3mapi",
f"http://{ip}/home.ps3mapi",
]
for url in urls:
try:
print(f"\n[*] Fetching {url}...")
req = urllib.request.Request(url, headers={"User-Agent": "PsOldRemotePlay/1.0"})
resp = urllib.request.urlopen(req, timeout=5)
html = resp.read().decode(errors="replace")
# Save raw HTML
fname = url.split("/")[-1].replace(".", "_") + ".html"
fpath = os.path.join(OUTPUT_DIR, fname)
with open(fpath, "w") as f:
f.write(html)
print(f" Saved to {fpath} ({len(html)} bytes)")
# Print relevant snippets
for line in html.split("\n"):
line_clean Repobility · code-quality intelligence platform · https://repobility.com
phase3_memory_dump function · python · L335-L442 (108 LOC)research/tools/ps3mapi_dump.py
def phase3_memory_dump(ip, vsh_pid, text_base, data_base=None):
"""Phase 3: Dump memory ranges via PS3MAPI."""
print("\n" + "=" * 60)
print("PHASE 3: Memory Dump")
print("=" * 60)
# Calculate runtime addresses
# The ELF virtual addresses need to be mapped to runtime addresses
# For PS3 SPRX: runtime_addr = segment_base + (target_va - segment_va_start)
#
# Common PS3 SPRX text segment VA starts: 0x10000, 0x100000, etc.
# We'll try to figure out the ELF base from the target addresses
#
# If TARGET_START = 0x00100168 and the ELF text segment starts at 0x00100000
# Then offset from segment start = 0x168
# Runtime address = text_base + 0x168
# Possible ELF text bases (we'll try the most likely)
elf_text_bases = [0x00100000, 0x00000000, 0x00010000]
print(f"[*] VSH PID: {vsh_pid}")
print(f"[*] Runtime text segment base: 0x{text_base:016X}")
print(f"[*] Target ELF addresses: 0x{TARGET_START:08X} - 0x{TARGET_END:08X}phase3_webman_peek function · python · L445-L497 (53 LOC)research/tools/ps3mapi_dump.py
def phase3_webman_peek(ip, vsh_pid, text_base, elf_base=0x00100000):
"""Alternative Phase 3: Read memory via webMAN's HTTP peek interface."""
print("\n" + "=" * 60)
print("PHASE 3 (alt): Memory Read via webMAN HTTP")
print("=" * 60)
offset = TARGET_START - elf_base
runtime_addr = text_base + offset
print(f"[*] Runtime address: 0x{runtime_addr:016X}")
print(f"[*] Reading {TARGET_SIZE} bytes in 4-byte chunks...")
# webMAN's peek reads 4 bytes at a time
# URL format: http://<ip>/peek.lv2?<hex_address>
# But that's for LV2 (kernel) memory, not process memory
# For process memory: http://<ip>/getmem.ps3mapi?proc=<pid>&addr=<hex>&len=<hex>
url = f"http://{ip}/getmem.ps3mapi?proc={vsh_pid}&addr={runtime_addr:X}&len={TARGET_SIZE:X}"
print(f"[*] Trying: {url}")
try:
req = urllib.request.Request(url, headers={"User-Agent": "PsOldRemotePlay/1.0"})
resp = urllib.request.urlopen(req, timeout=30)
data = resp.reaphase4_analysis_helper function · python · L500-L576 (77 LOC)research/tools/ps3mapi_dump.py
def phase4_analysis_helper(dump_file):
"""Phase 4: Analyze dump and create Ghidra import script."""
print("\n" + "=" * 60)
print("PHASE 4: Analysis Helper")
print("=" * 60)
if not dump_file or not os.path.exists(dump_file):
print("[!] No dump file to analyze.")
return
with open(dump_file, "rb") as f:
data = f.read()
print(f"[*] Dump size: {len(data)} bytes")
print(f"[*] First 64 bytes (hex):")
for i in range(0, min(len(data), 64), 16):
hex_str = " ".join(f"{b:02X}" for b in data[i:i+16])
ascii_str = "".join(chr(b) if 32 <= b < 127 else "." for b in data[i:i+16])
print(f" {i:04X}: {hex_str:48s} {ascii_str}")
# Look for known patterns
known_xor_key = bytes([0xF1, 0x16, 0xF0, 0xDA, 0x44, 0x2C, 0x06, 0xC2,
0x45, 0xB1, 0x5E, 0x48, 0xF9, 0x04, 0xE3, 0xE6])
known_iv = bytes([0x29, 0x0D, 0xE9, 0x07, 0xE2, 0x3B, 0xE2, 0xFC,
0x34, 0x08, 0xCA, 0x4main function · python · L579-L654 (76 LOC)research/tools/ps3mapi_dump.py
def main():
print("=" * 60)
print(" PS3MAPI Memory Dumper — sysconf_plugin Registration Handler")
print(f" Target: {PS3_IP}")
print("=" * 60)
print()
print("IMPORTANT: The PS3 should be in registration mode (showing PIN)")
print(" so sysconf_plugin is actively handling registration.")
print()
# Quick connectivity check
print("[*] Checking PS3 connectivity...")
for port, name in [(80, "webMAN HTTP"), (PS3MAPI_PORT, "PS3MAPI"), (21, "FTP")]:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(3)
s.connect((PS3_IP, port))
s.close()
print(f" Port {port} ({name}): OPEN")
except:
print(f" Port {port} ({name}): CLOSED/FILTERED")
# Phase 1: PS3MAPI enumeration
results = phase1_ps3mapi(PS3_IP)
# Save enumeration results
if results:
results_path = os.path.join(OUTPUT_DIR, "ps3mapi_enumeration.json")
derive_key_phone function · python · L37-L42 (6 LOC)research/tools/ps3_register_bruteforce_iv.py
def derive_key_phone(km):
"""Phone: key[i] = (km[i] - i - 0x28) ^ PHONE_XOR[i]"""
k = bytearray(16)
for i in range(16):
k[i] = ((km[i] - i - 0x28) & 0xFF) ^ PHONE_XOR[i]
return bytes(k)derive_key_psp function · python · L44-L49 (6 LOC)research/tools/ps3_register_bruteforce_iv.py
def derive_key_psp(km):
"""PSP: key[i] = (km[i] ^ PSP_XOR[i]) - i - 0x25"""
k = bytearray(16)
for i in range(16):
k[i] = ((km[i] ^ PSP_XOR[i]) - i - 0x25) & 0xFF
return bytes(k)derive_iv_phone function · python · L51-L56 (6 LOC)research/tools/ps3_register_bruteforce_iv.py
def derive_iv_phone(ctx8):
"""Phone: XOR second 8 bytes"""
iv = bytearray(PHONE_IV)
for i in range(8):
iv[8 + i] ^= ctx8[i]
return bytes(iv)derive_iv_psp function · python · L58-L63 (6 LOC)research/tools/ps3_register_bruteforce_iv.py
def derive_iv_psp(ctx8):
"""PSP: XOR first 8 bytes"""
iv = bytearray(PSP_IV)
for i in range(8):
iv[i] ^= ctx8[i]
return bytes(iv)Repobility · code-quality intelligence · https://repobility.com
generate_contexts function · python · L65-L147 (83 LOC)research/tools/ps3_register_bruteforce_iv.py
def generate_contexts(pin_str):
"""Generate all plausible 8-byte IV context values from the PIN"""
pin_int = int(pin_str)
contexts = []
# 1. Zeros (baseline)
contexts.append((bytes(8), "zeros"))
# 2. PIN as big-endian longlong (from code analysis)
contexts.append((pin_int.to_bytes(8, 'big'), "PIN BE longlong"))
# 3. PIN as little-endian longlong
contexts.append((pin_int.to_bytes(8, 'little'), "PIN LE longlong"))
# 4. PIN as big-endian 32-bit, zero-padded left
contexts.append((b'\x00\x00\x00\x00' + pin_int.to_bytes(4, 'big'), "PIN BE32 left-pad"))
# 5. PIN as big-endian 32-bit, zero-padded right
contexts.append((pin_int.to_bytes(4, 'big') + b'\x00\x00\x00\x00', "PIN BE32 right-pad"))
# 6. PIN as little-endian 32-bit, zero-padded right
contexts.append((pin_int.to_bytes(4, 'little') + b'\x00\x00\x00\x00', "PIN LE32 right-pad"))
# 7. PIN as little-endian 32-bit, zero-padded left
contexts.append((b'\x00\x00\x00\x00' attempt function · python · L149-L213 (65 LOC)research/tools/ps3_register_bruteforce_iv.py
def attempt(ps3_ip, enc_type, client_type, key_fn, iv_fn, ctx8, label, km=None):
"""Try a registration attempt"""
body = (f"Client-Type: {client_type}\r\n"
f"Client-Id: {DEVICE_ID.hex()}\r\n"
f"Client-Mac: {DEVICE_MAC.hex()}\r\n"
f"Client-Nickname: PsOldRemotePlay\r\n")
if km is None:
km = os.urandom(16)
key = key_fn(km)
iv = iv_fn(ctx8)
plain = body.encode("ascii")
padded = plain + b'\x00' * (16 - len(plain) % 16) if len(plain) % 16 != 0 else plain
enc = AES.new(key, AES.MODE_CBC, iv).encrypt(padded)
full = enc + km
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(8)
s.connect((ps3_ip, 9293))
req = f"POST /sce/premo/regist HTTP/1.1\r\nContent-Length: {len(full)}\r\n\r\n"
s.sendall(req.encode() + full)
resp = b""
while True:
try:
c = s.recv(4096)
if not c: break
main function · python · L215-L279 (65 LOC)research/tools/ps3_register_bruteforce_iv.py
def main():
if len(sys.argv) < 3:
print("Usage: python3 ps3_register_bruteforce_iv.py <PS3_IP> <PIN> [--start N]")
print()
print("PS3 must be in registration mode (Settings > Remote Play > Register Device)")
print("Select 'Mobile Phone' on PS3 menu for Phone encryption tests")
print("Select 'PSP' on PS3 menu for PSP encryption tests")
print()
print("Options:")
print(" --start N Skip first N attempts (for resuming after PS3 restart)")
sys.exit(1)
ip = sys.argv[1]
pin = sys.argv[2]
start_at = 0
if "--start" in sys.argv:
idx = sys.argv.index("--start")
start_at = int(sys.argv[idx + 1])
print(f"PS3: {ip}, PIN: {pin}")
if start_at > 0:
print(f"Skipping first {start_at} attempts (already tried)")
print(f"Max 3 attempts per registration session — restart PS3 registration between batches!")
print(f"IMPORTANT: Select 'Mobile Phone' on PS3 menu for Phone testsderive_key function · python · L37-L48 (12 LOC)research/tools/ps3_register_final.py
def derive_key(km, enc_type):
k = bytearray(16)
xor = REG_XOR[enc_type]
if enc_type == "PSP":
# PSP: key[i] = (material[i] XOR static[i]) - i - 0x25
for i in range(16):
k[i] = (((km[i] ^ xor[i]) & 0xFF) - i - 0x25) & 0xFF
else:
# Phone: key[i] = (material[i] - i - 0x28) XOR static[i]
for i in range(16):
k[i] = (((km[i] - i - 0x28) & 0xFF) ^ xor[i]) & 0xFF
return bytes(k)derive_iv function · python · L50-L56 (7 LOC)research/tools/ps3_register_final.py
def derive_iv(enc_type, ctx8):
iv = bytearray(REG_IV[enc_type])
if enc_type == "Phone":
for i in range(8): iv[8+i] ^= ctx8[i] # Phone: XOR second 8 bytes
else:
for i in range(8): iv[i] ^= ctx8[i] # PSP: XOR first 8 bytes
return bytes(iv)attempt function · python · L58-L131 (74 LOC)research/tools/ps3_register_final.py
def attempt(ps3_ip, enc_type, client_type, ctx8, label):
print(f"\n>>> Encrypt={enc_type}, Client-Type={client_type}, Ctx={label} ({ctx8.hex()})")
body = (f"Client-Type: {client_type}\r\n"
f"Client-Id: {DEVICE_ID.hex()}\r\n"
f"Client-Mac: {DEVICE_MAC.hex()}\r\n"
f"Client-Nickname: PsOldRemotePlay\r\n")
km = os.urandom(16)
key = derive_key(km, enc_type)
iv = derive_iv(enc_type, ctx8)
plain = body.encode("ascii")
padded = plain.ljust(((len(plain)+15)//16)*16, b'\x00')
enc = AES.new(key, AES.MODE_CBC, iv).encrypt(padded)
print(f" Key:{key.hex()}")
print(f" IV: {iv.hex()}")
print(f" KM: {km.hex()}")
print(f" Body plaintext ({len(plain)}b): {body.strip()[:60]}...")
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(10)
s.connect((ps3_ip, 9293))
full = enc + km
req = f"POST /sce/premo/regist HTTP/1.1\r\nContent-Length: {len(fullmain function · python · L133-L169 (37 LOC)research/tools/ps3_register_final.py
def main():
if len(sys.argv) < 3:
print("Usage: python3 ps3_register_final.py <IP> <PIN> [attempt 1-6, or 0 for auto-3]")
print(" 1=PSP+Phone+zeros 2=Phone+PC+zeros 3=PSP+Phone+PIN")
print(" 4=Phone+PC+PIN 5=PSP+Phone+sock 6=Phone+PC+sock")
sys.exit(1)
ip=sys.argv[1]; pin=sys.argv[2]
n=int(sys.argv[3]) if len(sys.argv)>3 else 0
zeros=bytes(8)
pin_ascii=pin.encode("ascii")[:8].ljust(8,b'\x00')
sa_wifi=bytes([0x00,0x02,0x24,0x4D,0xC0,0xA8,0x01,0x01])
# enc_type, client_type, context, label
attempts=[
("PSP", "Phone", zeros, "zeros"), # 1: If PS3 treats Mobile Phone as PSP type
("Phone","PC", zeros, "zeros"), # 2: If PS3 uses Phone type, shifted Client-Type
("PSP", "Phone", pin_ascii, "PIN-ascii"), # 3
("Phone","PC", pin_ascii, "PIN-ascii"), # 4
("PSP", "Phone", sa_wifi, "sockaddr"), # 5
("Phone","PC", sa_wifi, "sockaddr"), log function · python · L43-L45 (3 LOC)research/tools/ps3_register.py
def log(tag, msg):
ts = datetime.now().strftime("%H:%M:%S.%f")[:-3]
print(f"[{ts}][{tag}] {msg}")Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
derive_key_phone function · python · L47-L52 (6 LOC)research/tools/ps3_register.py
def derive_key_phone(key_material):
"""Phone: key[i] = (material[i] - i - 0x28) XOR static[i]"""
key = bytearray(16)
for i in range(16):
key[i] = ((key_material[i] - i - 0x28) ^ REG_XOR_PHONE[i]) & 0xFF
return bytes(key)derive_key_psp function · python · L54-L59 (6 LOC)research/tools/ps3_register.py
def derive_key_psp(key_material):
"""PSP: key[i] = (material[i] XOR static[i]) - i - 0x25"""
key = bytearray(16)
for i in range(16):
key[i] = ((key_material[i] ^ REG_XOR_PSP[i]) - i - 0x25) & 0xFF
return bytes(key)derive_key_pc function · python · L61-L66 (6 LOC)research/tools/ps3_register.py
def derive_key_pc(key_material):
"""PC: key[i] = (material[i] XOR static[i]) - i - 0x2B"""
key = bytearray(16)
for i in range(16):
key[i] = ((key_material[i] ^ REG_XOR_PC[i]) - i - 0x2B) & 0xFF
return bytes(key)