← back to dsdmsa__PsOldRemotePlay

Function bodies 388 total

All specs Real LLM only Function bodies
derive_iv function · python · L68-L85 (18 LOC)
research/tools/ps3_register.py
def derive_iv(platform, context_bytes=None):
    """Derive IV with optional context XOR"""
    if context_bytes is None:
        context_bytes = bytes(8)

    if platform == "Phone":
        iv = bytearray(REG_IV_PHONE)
        for i in range(8):
            iv[8 + i] ^= context_bytes[i]  # Phone: XOR second 8 bytes
    elif platform == "PSP":
        iv = bytearray(REG_IV_PSP)
        for i in range(8):
            iv[i] ^= context_bytes[i]
    else:  # PC
        iv = bytearray(REG_IV_PC)
        for i in range(8):
            iv[i] ^= context_bytes[i]
    return bytes(iv)
try_register function · python · L87-L220 (134 LOC)
research/tools/ps3_register.py
def try_register(ps3_ip, pin, platform, device_id, device_mac, device_name, context_bytes):
    """Attempt registration with given parameters"""
    platform_names = {"Phone": "Phone", "PSP": "PSP", "PC": "PC"}
    pname = platform_names.get(platform, platform)

    log("REG", f"--- Trying platform={pname}, context={context_bytes.hex()} ---")

    # Build plaintext body
    body_text = (
        f"Client-Type: {pname}\r\n"
        f"Client-Id: {device_id.hex()}\r\n"
        f"Client-Mac: {device_mac.hex()}\r\n"
        f"Client-Nickname: {device_name}\r\n"
    )
    log("REG", f"Body: {body_text.strip()}")

    # Generate 16 random bytes as key material
    key_material = os.urandom(16)
    log("REG", f"Key material: {key_material.hex()}")

    # Derive AES key
    if platform == "Phone":
        aes_key = derive_key_phone(key_material)
    elif platform == "PSP":
        aes_key = derive_key_psp(key_material)
    else:
        aes_key = derive_key_pc(key_material)
    log("REG", f"AES
main function · python · L223-L304 (82 LOC)
research/tools/ps3_register.py
def main():
    if len(sys.argv) < 3:
        print("Usage: python3 ps3_register.py <PS3_IP> <8-digit-PIN>")
        print("Example: python3 ps3_register.py 192.168.1.75 78831915")
        sys.exit(1)

    ps3_ip = sys.argv[1]
    pin = sys.argv[2]

    log("MAIN", f"PS3 IP: {ps3_ip}")
    log("MAIN", f"PIN: {pin}")

    # Generate a device identity
    device_id = os.urandom(16)
    device_mac = os.urandom(6)
    device_name = "PsOldRemotePlay"

    log("MAIN", f"Device ID: {device_id.hex()}")
    log("MAIN", f"Device MAC: {device_mac.hex()}")
    log("MAIN", "")

    # Context byte candidates
    pin_bytes = pin.encode("ascii")[:8].ljust(8, b'\x00')
    pin_int = int(pin) if pin.isdigit() else 0
    pin_be = pin_int.to_bytes(8, "big")

    context_candidates = [
        (bytes(8), "zeros"),
        (pin_bytes, "PIN as ASCII"),
        (pin_be, "PIN as big-endian int"),
        (bytes.fromhex(pin.ljust(16, '0'))[:8], "PIN as hex bytes"),
    ]

    # Try each platform with each contex
derive_key_phone function · python · L21-L25 (5 LOC)
research/tools/ps3_register_single.py
def derive_key_phone(km):
    k = bytearray(16)
    for i in range(16):
        k[i] = ((km[i] - i - 0x28) ^ REG_XOR_PHONE[i]) & 0xFF
    return bytes(k)
derive_iv_phone function · python · L27-L31 (5 LOC)
research/tools/ps3_register_single.py
def derive_iv_phone(ctx8):
    iv = bytearray(REG_IV_PHONE)
    for i in range(8):
        iv[8+i] ^= ctx8[i]
    return bytes(iv)
attempt function · python · L33-L114 (82 LOC)
research/tools/ps3_register_single.py
def attempt(ps3_ip, pin, ctx8, ctx_name, client_type_str="Phone"):
    print(f"\n>>> Client-Type={client_type_str}, Context={ctx_name} ({ctx8.hex()})")

    body = (f"Client-Type: {client_type_str}\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)
    aes_key = derive_key_phone(km)
    aes_iv = derive_iv_phone(ctx8)

    plain = body.encode("ascii")
    padded = plain.ljust(((len(plain)+15)//16)*16, b'\x00')

    encrypted = AES.new(aes_key, AES.MODE_CBC, aes_iv).encrypt(padded)
    full_body = encrypted + km

    print(f"    AES Key: {aes_key.hex()}")
    print(f"    AES IV:  {aes_iv.hex()}")
    print(f"    KeyMat:  {km.hex()}")
    print(f"    Body size: {len(full_body)}")

    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(10)
        sock.connect((ps3_ip, 9293))

        req = f"POST /sce/premo/regist HTTP
main function · python · L116-L177 (62 LOC)
research/tools/ps3_register_single.py
def main():
    if len(sys.argv) < 3:
        print("PS3 Registration — Single Shot v3")
        print("Usage: python3 ps3_register_single.py <IP> <PIN> [attempt]")
        print("")
        print("Attempts:")
        print("  1 = Phone, Client-Type:Phone, ctx=zeros")
        print("  2 = Phone, Client-Type:Phone, ctx=PIN-ascii")
        print("  3 = Phone, Client-Type:Phone, ctx=PIN-be-int")
        print("  4 = Phone, Client-Type:PC, ctx=zeros      (shifted mapping)")
        print("  5 = Phone, Client-Type:PC, ctx=PIN-ascii   (shifted mapping)")
        print("  6 = Phone, Client-Type:PC, ctx=PIN-be-int  (shifted mapping)")
        print("  7 = Phone, Client-Type:Phone, ctx=PIN-le-int")
        print("  8 = Phone, Client-Type:Phone, ctx=SSID-suffix-padded")
        print("  9 = Phone, Client-Type:Phone, ctx=PIN-first4-repeated")
        print("  0 = Try ALL (3 per PS3 session)")
        sys.exit(1)

    ip = sys.argv[1]
    pin = sys.argv[2]
    n = int(sys.argv[3]) if len(sys.argv)
Repobility · code-quality intelligence platform · https://repobility.com
derive_key function · python · L71-L96 (26 LOC)
research/tools/ps3_register_v2.py
def derive_key(material: bytes, platform_type: int) -> bytes:
    """Derive the AES key from 16 bytes of key material using the platform-specific formula."""
    params = CRYPTO_KEYS[platform_type]
    xor_key = params["xor_key"]
    const = params["constant"]
    formula = params["formula"]

    result = bytearray(16)
    for i in range(16):
        mat = material[i]
        key = xor_key[i]

        if formula == "sub_first":
            # Phone (type 2): subtract first, then XOR
            # result = (material - counter - constant) XOR key
            val = (mat - i - const) & 0xFF
            val = val ^ key
        else:  # xor_first
            # PSP (type 1) and PC (type 3): XOR first, then subtract
            # result = (material XOR key) - counter - constant
            val = mat ^ key
            val = (val - i - const) & 0xFF

        result[i] = val

    return bytes(result)
get_iv function · python · L99-L101 (3 LOC)
research/tools/ps3_register_v2.py
def get_iv(platform_type: int) -> bytes:
    """Get the IV base for the given platform type."""
    return CRYPTO_KEYS[platform_type]["iv_base"]
build_registration_body function · python · L104-L125 (22 LOC)
research/tools/ps3_register_v2.py
def build_registration_body(device_id: bytes, device_mac: bytes, device_name: str,
                            client_type: str, key_material: bytes = None) -> tuple:
    """Build the plaintext body for registration, returns (body, key_material)."""
    # For Phone type, the client generates 16 random bytes as key material
    if key_material is None:
        key_material = os.urandom(16)

    # Build plaintext body
    body_lines = []
    body_lines.append(f"Client-Type: {client_type}")
    body_lines.append(f"Client-Id: {device_id.hex()}")
    body_lines.append(f"Client-Mac: {device_mac.hex()}")
    body_lines.append(f"Client-Nickname: {device_name}")

    plaintext = "\r\n".join(body_lines) + "\r\n"

    # Pad to AES block size (16 bytes)
    pt_bytes = plaintext.encode("ascii")
    pad_len = 16 - (len(pt_bytes) % 16)
    pt_bytes += bytes([pad_len] * pad_len)  # PKCS7 padding

    return pt_bytes, key_material
attempt_registration function · python · L128-L222 (95 LOC)
research/tools/ps3_register_v2.py
def attempt_registration(ps3_ip: str, pin: str, platform_type: int):
    """Attempt a single registration with the given platform type."""
    params = CRYPTO_KEYS[platform_type]
    print(f"\n{'='*60}")
    print(f"REGISTRATION ATTEMPT — Platform: {params['name']} (type {platform_type})")
    print(f"  Formula: {params['formula']}, constant: 0x{params['constant']:02X}")
    print(f"  XOR key: {params['xor_key'].hex()}")
    print(f"  IV base: {params['iv_base'].hex()}")
    print(f"{'='*60}")

    # WiFi password = PIN halves swapped
    wifi_pw = pin[4:] + pin[:4]
    print(f"  PIN: {pin}, WiFi password: {wifi_pw}")

    # Generate key material (16 random bytes for Phone type)
    key_material = os.urandom(16)
    print(f"  Key material: {key_material.hex()}")

    # Derive AES key
    aes_key = derive_key(key_material, platform_type)
    print(f"  Derived AES key: {aes_key.hex()}")

    # Get IV
    iv = get_iv(platform_type)
    print(f"  AES IV: {iv.hex()}")

    # Device info
   
main function · python · L225-L263 (39 LOC)
research/tools/ps3_register_v2.py
def main():
    print("PS3 Remote Play Registration v2")
    print(f"Target: {PS3_IP}:{PORT}")
    print(f"PIN: {PIN}")
    print(f"Requested platform: {PLATFORM}")
    print()

    # Check connectivity
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(3)
        sock.connect((PS3_IP, PORT))
        sock.close()
        print(f"[+] Port {PORT} is OPEN")
    except:
        print(f"[!] Cannot connect to {PS3_IP}:{PORT}")
        print("    Make sure PS3 is in registration mode (showing PIN)")
        return

    # Try the requested platform type
    if attempt_registration(PS3_IP, PIN, PLATFORM):
        return

    # If that failed, try all platform types
    print(f"\n\nPlatform {PLATFORM} failed. Trying all types...")
    for pt in [1, 2, 3]:
        if pt == PLATFORM:
            continue
        if attempt_registration(PS3_IP, PIN, pt):
            return

    print("\n\n[!] All platform types failed.")
    print("    The key derivati
derive_key_phone function · python · L25-L29 (5 LOC)
research/tools/ps3_register_v4.py
def derive_key_phone(km):
    k = bytearray(16)
    for i in range(16):
        k[i] = ((km[i] - i - 0x28) ^ REG_XOR_PHONE[i]) & 0xFF
    return bytes(k)
derive_iv_phone function · python · L31-L35 (5 LOC)
research/tools/ps3_register_v4.py
def derive_iv_phone(ctx8):
    iv = bytearray(REG_IV_PHONE)
    for i in range(8):
        iv[8+i] ^= ctx8[i]
    return bytes(iv)
send_registration function · python · L37-L89 (53 LOC)
research/tools/ps3_register_v4.py
def send_registration(ps3_ip, body_bytes):
    """Send raw registration POST and return response"""
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(10)
        sock.connect((ps3_ip, 9293))

        req = f"POST /sce/premo/regist HTTP/1.1\r\nContent-Length: {len(body_bytes)}\r\n\r\n"
        sock.sendall(req.encode("ascii") + body_bytes)
        print("    Sent! Waiting...")

        resp = b""
        while True:
            try:
                c = sock.recv(4096)
                if not c: break
                resp += c
                if b"\r\n\r\n" in resp:
                    he = resp.index(b"\r\n\r\n") + 4
                    hdr = resp[:he].decode("ascii", errors="replace")
                    cl = 0
                    for l in hdr.split("\r\n"):
                        if l.lower().startswith("content-length:"): cl = int(l.split(":")[1].strip())
                    if len(resp) - he >= cl: break
            except: break
     
Repobility analyzer · published findings · https://repobility.com
try_encrypted function · python · L91-L110 (20 LOC)
research/tools/ps3_register_v4.py
def try_encrypted(ps3_ip, ctx8, ctx_name, client_type="Phone", line_ending="\r\n"):
    print(f"\n>>> Encrypted: Client-Type={client_type}, Context={ctx_name} ({ctx8.hex()}), endings={'CRLF' if line_ending == chr(13)+chr(10) else 'LF'}")

    body = (f"Client-Type: {client_type}{line_ending}"
            f"Client-Id: {DEVICE_ID.hex()}{line_ending}"
            f"Client-Mac: {DEVICE_MAC.hex()}{line_ending}"
            f"Client-Nickname: PsOldRemotePlay{line_ending}")

    km = os.urandom(16)
    aes_key = derive_key_phone(km)
    aes_iv = derive_iv_phone(ctx8)

    plain = body.encode("ascii")
    padded = plain.ljust(((len(plain)+15)//16)*16, b'\x00')

    encrypted = AES.new(aes_key, AES.MODE_CBC, aes_iv).encrypt(padded)
    full_body = encrypted + km

    print(f"    Key:{aes_key.hex()} IV:{aes_iv.hex()}")
    return send_registration(ps3_ip, full_body)
try_unencrypted function · python · L112-L121 (10 LOC)
research/tools/ps3_register_v4.py
def try_unencrypted(ps3_ip, client_type="Phone"):
    print(f"\n>>> UNENCRYPTED: Client-Type={client_type}")

    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")

    print(f"    Raw body: {len(body)} bytes")
    return send_registration(ps3_ip, body.encode("ascii"))
main function · python · L123-L160 (38 LOC)
research/tools/ps3_register_v4.py
def main():
    if len(sys.argv) < 3:
        print("Usage: python3 ps3_register_v4.py <IP> <PIN> [attempt 1-9]")
        print("  1 = Phone, ctx=PS3 ethernet MAC+00+00")
        print("  2 = Phone, ctx=PS3 MAC reversed")
        print("  3 = Phone, ctx=PS3 MAC+01+00 (WiFi MAC = eth+1?)")
        print("  4 = UNENCRYPTED body (Phone)")
        print("  5 = UNENCRYPTED body (PC)")
        print("  6 = Phone, ctx=zeros, LF line endings")
        print("  7 = Phone, ctx=PS3 MAC first 4 + PIN first 4")
        print("  8 = Phone, ctx=all 0xFF")
        print("  9 = Phone, ctx=PS3 MAC XOR PIN bytes")
        sys.exit(1)

    ip = sys.argv[1]
    pin = sys.argv[2]
    n = int(sys.argv[3]) if len(sys.argv) > 3 else 1

    # PS3 ethernet MAC: FC:0F:E6:D5:67:95
    mac8_padded = PS3_ETH_MAC + bytes(2)                              # fc0fe6d5679500 00
    mac8_reversed = bytes(reversed(PS3_ETH_MAC)) + bytes(2)           # 9567d5e60ffc00 00
    mac8_wifi = bytes([PS3_ETH_MAC[0], PS3_ETH_MAC[1], PS
derive_key function · python · L26-L29 (4 LOC)
research/tools/ps3_register_v5.py
def derive_key(km):
    k = bytearray(16)
    for i in range(16): k[i] = ((km[i] - i - 0x28) ^ REG_XOR_PHONE[i]) & 0xFF
    return bytes(k)
derive_iv function · python · L31-L34 (4 LOC)
research/tools/ps3_register_v5.py
def derive_iv(ctx8):
    iv = bytearray(REG_IV_PHONE)
    for i in range(8): iv[8+i] ^= ctx8[i]
    return bytes(iv)
attempt function · python · L36-L100 (65 LOC)
research/tools/ps3_register_v5.py
def attempt(ps3_ip, ctx8, label, ctype="Phone"):
    print(f"\n>>> {label}: ctx={ctx8.hex()}, Client-Type={ctype}")

    body = (f"Client-Type: {ctype}\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)
    iv = derive_iv(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()} IV:{iv.hex()}")

    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(10)
        s.connect((ps3_ip, 9293))
        req = f"POST /sce/premo/regist HTTP/1.1\r\nContent-Length: {len(enc)+16}\r\n\r\n"
        s.sendall(req.encode() + enc + km)
        print("    Sent!")

        resp = b""
        while True:
            try:
                c = s.recv(4096)
                if not c: break
    
main function · python · L102-L141 (40 LOC)
research/tools/ps3_register_v5.py
def main():
    if len(sys.argv) < 3:
        print("Usage: python3 ps3_register_v5.py <IP> <PIN> [1-9]")
        sys.exit(1)

    ip = sys.argv[1]
    pin = sys.argv[2]
    n = int(sys.argv[3]) if len(sys.argv)>3 else 0

    # sockaddr_in: family(2) + port(2) + addr(4) = 8 bytes
    # PS3 WiFi AP typically uses 192.168.1.1
    sa_wifi = bytes([0x00,0x02, 0x24,0x4D, 0xC0,0xA8,0x01,0x01])
    ip_wifi = bytes([0xC0,0xA8,0x01,0x01, 0x00,0x00,0x00,0x00])
    wifi_mac = bytes([0xFC,0x0F,0xE6,0xD5,0x67,0x96,0x00,0x00])  # eth+1
    eth_mac  = bytes([0xFC,0x0F,0xE6,0xD5,0x67,0x95,0x00,0x00])
    sa_wired = bytes([0x00,0x02, 0x24,0x4D, 0xC0,0xA8,0x01,0x4B])  # 192.168.1.75
    sa_be_port = bytes([0x00,0x02, 0x4D,0x24, 0xC0,0xA8,0x01,0x01]) # swapped port bytes
    sa_noport = bytes([0x00,0x02, 0x00,0x00, 0xC0,0xA8,0x01,0x01])

    attempts = [
        (sa_wifi,    "sockaddr(WiFi 192.168.1.1:9293)", "Phone"),
        (ip_wifi,    "IP 192.168.1.1 padded",           "Phone"),
        (wifi_mac,  
detect_format function · python · L77-L114 (38 LOC)
research/tools/repo_analysis/binary_analyzer.py
def detect_format(data: bytes) -> dict:
    """Detect binary format from headers."""
    info = {'format': 'unknown', 'bits': 0, 'arch': 'unknown'}

    if len(data) < 4:
        return info

    # PE (MZ header)
    if data[:2] == b'MZ':
        info['format'] = 'PE'
        if len(data) > 0x3C + 4:
            pe_offset = struct.unpack_from('<I', data, 0x3C)[0]
            if pe_offset < len(data) - 6 and data[pe_offset:pe_offset+4] == b'PE\x00\x00':
                machine = struct.unpack_from('<H', data, pe_offset + 4)[0]
                info['arch'] = {0x14c: 'x86', 0x8664: 'x64', 0x1c0: 'ARM',
                                0xaa64: 'ARM64'}.get(machine, f'0x{machine:04x}')
                magic_offset = pe_offset + 24
                if magic_offset < len(data) - 2:
                    opt_magic = struct.unpack_from('<H', data, magic_offset)[0]
                    info['bits'] = 64 if opt_magic == 0x20b else 32

    # ELF
    elif data[:4] == b'\x7fELF':
        info['format'] =
Repobility (the analyzer behind this table) · https://repobility.com
extract_strings function · python · L117-L165 (49 LOC)
research/tools/repo_analysis/binary_analyzer.py
def extract_strings(data: bytes, min_len: int = MIN_STRING_LEN) -> list:
    """Extract ASCII and wide (UTF-16LE) strings."""
    strings = []

    # ASCII strings
    current = bytearray()
    start = 0
    for i, b in enumerate(data):
        if 32 <= b < 127:
            if not current:
                start = i
            current.append(b)
        else:
            if len(current) >= min_len:
                strings.append({
                    'offset': start,
                    'value': current.decode('ascii'),
                    'encoding': 'ascii',
                    'length': len(current)
                })
            current = bytearray()
    if len(current) >= min_len:
        strings.append({
            'offset': start,
            'value': current.decode('ascii'),
            'encoding': 'ascii',
            'length': len(current)
        })

    # Wide strings (UTF-16LE): printable char followed by 0x00
    current = bytearray()
    start = 0
    for i in range(0, l
find_pattern function · python · L168-L186 (19 LOC)
research/tools/repo_analysis/binary_analyzer.py
def find_pattern(data: bytes, pattern: bytes) -> list:
    """Find all occurrences of a byte pattern in data."""
    results = []
    start = 0
    while True:
        pos = data.find(pattern, start)
        if pos == -1:
            break
        # Get context: 16 bytes before and after
        ctx_start = max(0, pos - 16)
        ctx_end = min(len(data), pos + len(pattern) + 16)
        context_hex = data[ctx_start:ctx_end].hex()
        results.append({
            'offset': pos,
            'offset_hex': f'0x{pos:x}',
            'context': context_hex,
        })
        start = pos + 1
    return results
count_prologues function · python · L189-L203 (15 LOC)
research/tools/repo_analysis/binary_analyzer.py
def count_prologues(data: bytes) -> dict:
    """Count function prologues to estimate architecture usage."""
    counts = {}
    for name, pattern in PROLOGUES.items():
        count = 0
        start = 0
        while True:
            pos = data.find(pattern, start)
            if pos == -1:
                break
            count += 1
            start = pos + 1
        if count > 0:
            counts[name] = count
    return counts
analyze_file function · python · L206-L269 (64 LOC)
research/tools/repo_analysis/binary_analyzer.py
def analyze_file(filepath: str, quiet: bool = False, strings_only: bool = False) -> dict:
    """Analyze a single binary file."""
    result = {
        'file': filepath,
        'size': os.path.getsize(filepath),
    }

    try:
        with open(filepath, 'rb') as f:
            data = f.read()
    except (OSError, PermissionError) as e:
        result['error'] = str(e)
        return result

    if not quiet:
        print(f"  Analyzing: {filepath} ({len(data)} bytes)")

    # Format detection
    result['format'] = detect_format(data)

    # Strings
    if not quiet:
        print(f"    Extracting strings...")
    strings = extract_strings(data)
    result['strings_count'] = len(strings)
    # Filter interesting strings
    interesting_keywords = ['aes', 'cbc', 'encrypt', 'decrypt', 'key', 'iv', 'nonce',
                           'regist', 'premo', 'remote', 'play', 'session', 'auth',
                           'pin', 'cert', 'ssl', 'tls', 'http', 'sce/', 'sie/',
                 
main function · python · L272-L351 (80 LOC)
research/tools/repo_analysis/binary_analyzer.py
def main():
    parser = argparse.ArgumentParser(
        description='Analyze binary files for crypto patterns and structure')
    parser.add_argument('target', help='File or directory to analyze')
    parser.add_argument('-o', '--output', help='Output JSON file path')
    parser.add_argument('-q', '--quiet', action='store_true', help='Suppress progress')
    parser.add_argument('--strings-only', action='store_true', help='Only extract strings')
    args = parser.parse_args()

    target = args.target
    if not os.path.exists(target):
        print(f"ERROR: Path not found: {target}", file=sys.stderr)
        sys.exit(1)

    # Collect files
    files = []
    if os.path.isfile(target):
        files.append(target)
    else:
        for root, dirs, filenames in os.walk(target):
            dirs[:] = [d for d in dirs if not d.startswith('.')]
            for fname in filenames:
                ext = os.path.splitext(fname)[1].lower()
                if ext in BINARY_EXTENSIONS:
       
ps3_derive_key function · python · L70-L88 (19 LOC)
research/tools/repo_analysis/compare_key_derivation.py
def ps3_derive_key(device_type: str, km: bytes) -> bytes:
    """Derive AES key from key material for a PS3 device type."""
    info = PS3_KEYS[device_type]
    xor_key = info['xor_key']
    base = info['key_subtract_base']
    key = bytearray(16)

    for i in range(16):
        if device_type == 'PSP':
            # key[i] = (km[i] ^ XOR[i]) - i - 0x25
            key[i] = ((km[i] ^ xor_key[i]) - i - 0x25) & 0xFF
        elif device_type == 'Phone':
            # key[i] = (km[i] - i - 0x28) ^ XOR[i]
            key[i] = ((km[i] - i - 0x28) & 0xFF) ^ xor_key[i]
        elif device_type == 'PC':
            # key[i] = (km[i] + i + 0x29) ^ XOR[i]
            key[i] = ((km[i] + i + 0x29) & 0xFF) ^ xor_key[i]

    return bytes(key)
ps3_derive_iv function · python · L91-L108 (18 LOC)
research/tools/repo_analysis/compare_key_derivation.py
def ps3_derive_iv(device_type: str, ctx8: bytes) -> bytes:
    """Derive AES IV from IV base and 8-byte context value."""
    iv = bytearray(PS3_KEYS[device_type]['iv_base'])

    if device_type == 'PSP':
        # XOR first 8 bytes
        for i in range(8):
            iv[i] ^= ctx8[i]
    elif device_type == 'Phone':
        # XOR last 8 bytes
        for i in range(8):
            iv[8 + i] ^= ctx8[i]
    elif device_type == 'PC':
        # XOR first 8 bytes
        for i in range(8):
            iv[i] ^= ctx8[i]

    return bytes(iv)
ps4_derive_handshake_key function · python · L115-L121 (7 LOC)
research/tools/repo_analysis/compare_key_derivation.py
def ps4_derive_handshake_key(nonce: bytes, morning: bytes) -> bytes:
    """
    PS4 (chiaki-ng): HMAC-SHA256 based key derivation.
    key = HMAC-SHA256(morning, nonce)[:16]
    """
    h = hmac.new(morning, nonce, hashlib.sha256).digest()
    return h[:16]
Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
ps4_derive_regist_key function · python · L124-L133 (10 LOC)
research/tools/repo_analysis/compare_key_derivation.py
def ps4_derive_regist_key(pin: str, rpkey: bytes) -> bytes:
    """
    PS4 registration key derivation (chiaki pattern):
    Uses PIN + static key to derive AES key via HMAC/SHA.
    This is a simplified model based on chiaki-ng source.
    """
    pin_bytes = pin.encode('ascii')
    # chiaki uses: key = HMAC-SHA256(rpkey, pin_bytes)[:16]
    h = hmac.new(rpkey, pin_bytes, hashlib.sha256).digest()
    return h[:16]
generate_iv_contexts function · python · L140-L205 (66 LOC)
research/tools/repo_analysis/compare_key_derivation.py
def generate_iv_contexts(pin_str: str) -> list:
    """Generate all plausible 8-byte IV context values from PIN."""
    pin_int = int(pin_str)
    contexts = []

    # 1. All zeros (baseline)
    contexts.append(('zeros', bytes(8)))

    # 2. PIN as big-endian int64
    contexts.append(('PIN BE i64', pin_int.to_bytes(8, 'big')))

    # 3. PIN as little-endian int64
    contexts.append(('PIN LE i64', pin_int.to_bytes(8, 'little')))

    # 4. PIN as BE i32 left-padded
    contexts.append(('PIN BE i32 left', b'\x00\x00\x00\x00' + pin_int.to_bytes(4, 'big')))

    # 5. PIN as BE i32 right-padded
    contexts.append(('PIN BE i32 right', pin_int.to_bytes(4, 'big') + b'\x00\x00\x00\x00'))

    # 6. PIN as LE i32 left-padded
    contexts.append(('PIN LE i32 left', b'\x00\x00\x00\x00' + pin_int.to_bytes(4, 'little')))

    # 7. PIN as LE i32 right-padded
    contexts.append(('PIN LE i32 right', pin_int.to_bytes(4, 'little') + b'\x00\x00\x00\x00'))

    # 8. PIN ASCII bytes zero-padded to 8
    
hex_str function · python · L208-L210 (3 LOC)
research/tools/repo_analysis/compare_key_derivation.py
def hex_str(data: bytes) -> str:
    """Format bytes as hex string."""
    return ' '.join(f'{b:02X}' for b in data)
main function · python · L213-L310 (98 LOC)
research/tools/repo_analysis/compare_key_derivation.py
def main():
    pin = sys.argv[1] if len(sys.argv) > 1 else '12345678'

    if pin in ('-h', '--help'):
        print(__doc__.strip())
        sys.exit(0)

    print(f"{'='*70}")
    print(f"PS3/PS4 Registration Key Derivation Comparison")
    print(f"{'='*70}")
    print(f"PIN: {pin}")
    print()

    # Sample key material (would come from PS3 in real handshake)
    km = bytes(range(16))  # Placeholder
    print(f"Sample KM (key material): {hex_str(km)}")
    print()

    # ============================================================
    # PS3 Key Derivation — All 3 device types
    # ============================================================
    print(f"{'='*70}")
    print(f"PS3 KEY DERIVATION")
    print(f"{'='*70}")

    for dtype in ['PSP', 'Phone', 'PC']:
        info = PS3_KEYS[dtype]
        key = ps3_derive_key(dtype, km)
        print(f"\n  --- {dtype} ---")
        print(f"  Formula:   {info['key_formula']}")
        print(f"  XOR key:   {hex_str(info['xor_key'])}")
    
Match class · python · L73-L79 (7 LOC)
research/tools/repo_analysis/extract_aes_patterns.py
class Match:
    file: str
    line_num: int
    pattern_type: str
    matched_text: str
    context_before: list = field(default_factory=list)
    context_after: list = field(default_factory=list)
scan_file function · python · L82-L112 (31 LOC)
research/tools/repo_analysis/extract_aes_patterns.py
def scan_file(filepath: Path) -> list:
    """Scan a single source file for crypto patterns."""
    matches = []
    try:
        with open(filepath, 'r', encoding='utf-8', errors='replace') as f:
            lines = f.readlines()
    except (OSError, PermissionError):
        return matches

    for line_idx, line in enumerate(lines):
        for pattern_name, pattern in CRYPTO_PATTERNS.items():
            for m in pattern.finditer(line):
                ctx_before = [
                    lines[i].rstrip()
                    for i in range(max(0, line_idx - CONTEXT_LINES), line_idx)
                ]
                ctx_after = [
                    lines[i].rstrip()
                    for i in range(line_idx + 1, min(len(lines), line_idx + CONTEXT_LINES + 1))
                ]
                matches.append(Match(
                    file=str(filepath),
                    line_num=line_idx + 1,
                    pattern_type=pattern_name,
                    matched_text=m.grou
print_match function · python · L115-L136 (22 LOC)
research/tools/repo_analysis/extract_aes_patterns.py
def print_match(match: Match, repos_dir: str):
    """Pretty-print a single match."""
    rel_path = os.path.relpath(match.file, repos_dir)
    print(f"\n  \033[1;33m[{match.pattern_type}]\033[0m {rel_path}:{match.line_num}")
    print(f"  Matched: \033[1;32m{match.matched_text}\033[0m")
    if match.context_before:
        for cl in match.context_before:
            print(f"    \033[2m{cl}\033[0m")
    # Highlight the matched line
    print(f"    \033[1m>>> {match.context_before and '' or ''}", end='')
    # Find the actual line
    try:
        with open(match.file, 'r', errors='replace') as f:
            for i, line in enumerate(f):
                if i == match.line_num - 1:
                    print(f"{line.rstrip()}\033[0m")
                    break
    except (OSError, PermissionError):
        print(f"(could not re-read line)\033[0m")
    if match.context_after:
        for cl in match.context_after:
            print(f"    \033[2m{cl}\033[0m")
main function · python · L139-L214 (76 LOC)
research/tools/repo_analysis/extract_aes_patterns.py
def main():
    repos_dir = sys.argv[1] if len(sys.argv) > 1 else REPOS_DIR

    if repos_dir in ('-h', '--help'):
        print(__doc__.strip())
        sys.exit(0)

    if not os.path.isdir(repos_dir):
        print(f"ERROR: Directory not found: {repos_dir}", file=sys.stderr)
        sys.exit(1)

    print(f"Scanning {repos_dir} for AES/crypto patterns...")
    print(f"Extensions: {', '.join(sorted(SOURCE_EXTENSIONS))}")
    print()

    all_matches = []
    files_scanned = 0

    for root, dirs, files in os.walk(repos_dir):
        # Skip hidden dirs and common non-code dirs
        dirs[:] = [d for d in dirs if not d.startswith('.') and d not in
                   ('node_modules', '__pycache__', '.git', 'build', 'target')]
        for fname in files:
            ext = os.path.splitext(fname)[1].lower()
            if ext not in SOURCE_EXTENSIONS:
                continue
            filepath = Path(root) / fname
            files_scanned += 1
            matches = scan_file(filepat
Repobility · code-quality intelligence platform · https://repobility.com
XRegistryEntry class · python · L36-L68 (33 LOC)
research/tools/repo_analysis/xregistry_tool.py
class XRegistryEntry:
    """Represents a single xRegistry entry."""
    def __init__(self, offset: int, entry_type: int, path: str,
                 data_offset: int = 0, data_size: int = 0, data: bytes = b''):
        self.offset = offset
        self.entry_type = entry_type
        self.path = path
        self.data_offset = data_offset
        self.data_size = data_size
        self.data = data

    def type_name(self) -> str:
        return {1: 'DIR', 2: 'INT', 3: 'BIN'}.get(self.entry_type, f'UNK({self.entry_type})')

    def value_str(self) -> str:
        if self.entry_type == ENTRY_TYPE_INT and len(self.data) >= 4:
            val = struct.unpack('>I', self.data[:4])[0]
            return f'{val} (0x{val:08x})'
        elif self.entry_type == ENTRY_TYPE_BIN and self.data:
            hex_str = self.data.hex()
            if len(hex_str) > 64:
                hex_str = hex_str[:64] + '...'
            # Also try ASCII
            try:
                ascii_str = self.data.decod
__init__ method · python · L38-L45 (8 LOC)
research/tools/repo_analysis/xregistry_tool.py
    def __init__(self, offset: int, entry_type: int, path: str,
                 data_offset: int = 0, data_size: int = 0, data: bytes = b''):
        self.offset = offset
        self.entry_type = entry_type
        self.path = path
        self.data_offset = data_offset
        self.data_size = data_size
        self.data = data
value_str method · python · L50-L68 (19 LOC)
research/tools/repo_analysis/xregistry_tool.py
    def value_str(self) -> str:
        if self.entry_type == ENTRY_TYPE_INT and len(self.data) >= 4:
            val = struct.unpack('>I', self.data[:4])[0]
            return f'{val} (0x{val:08x})'
        elif self.entry_type == ENTRY_TYPE_BIN and self.data:
            hex_str = self.data.hex()
            if len(hex_str) > 64:
                hex_str = hex_str[:64] + '...'
            # Also try ASCII
            try:
                ascii_str = self.data.decode('ascii').rstrip('\x00')
                if ascii_str.isprintable() and len(ascii_str) > 2:
                    return f'{hex_str} (ascii: "{ascii_str}")'
            except (UnicodeDecodeError, ValueError):
                pass
            return hex_str
        elif self.entry_type == ENTRY_TYPE_DIR:
            return '<directory>'
        return '<empty>'
XRegistryParser class · python · L71-L257 (187 LOC)
research/tools/repo_analysis/xregistry_tool.py
class XRegistryParser:
    """Parse PS3 xRegistry.sys binary format."""

    def __init__(self, filepath: str):
        self.filepath = filepath
        with open(filepath, 'rb') as f:
            self.data = bytearray(f.read())
        self.entries = []
        self._parse()

    def _parse(self):
        """Parse the xRegistry structure."""
        data = self.data

        # Verify magic
        if data[:4] != XREG_MAGIC:
            # Try scanning for the magic
            pos = data.find(XREG_MAGIC)
            if pos == -1:
                print(f"WARNING: xRegistry magic {XREG_MAGIC.hex()} not found at offset 0",
                      file=sys.stderr)
                # Fall back to string scanning
                self._parse_by_paths()
                return
            else:
                print(f"NOTE: Magic found at offset 0x{pos:x} (expected 0x0)", file=sys.stderr)

        # Parse header
        # Typical header: magic(4) + version(2) + entry_count(2) + data_offset(4) + ..
__init__ method · python · L74-L79 (6 LOC)
research/tools/repo_analysis/xregistry_tool.py
    def __init__(self, filepath: str):
        self.filepath = filepath
        with open(filepath, 'rb') as f:
            self.data = bytearray(f.read())
        self.entries = []
        self._parse()
_parse method · python · L81-L113 (33 LOC)
research/tools/repo_analysis/xregistry_tool.py
    def _parse(self):
        """Parse the xRegistry structure."""
        data = self.data

        # Verify magic
        if data[:4] != XREG_MAGIC:
            # Try scanning for the magic
            pos = data.find(XREG_MAGIC)
            if pos == -1:
                print(f"WARNING: xRegistry magic {XREG_MAGIC.hex()} not found at offset 0",
                      file=sys.stderr)
                # Fall back to string scanning
                self._parse_by_paths()
                return
            else:
                print(f"NOTE: Magic found at offset 0x{pos:x} (expected 0x0)", file=sys.stderr)

        # Parse header
        # Typical header: magic(4) + version(2) + entry_count(2) + data_offset(4) + ...
        # The exact format varies; we'll try the common layout
        if len(data) < 16:
            print("ERROR: File too small", file=sys.stderr)
            return

        # Try to read entry table
        # Format hypothesis: after header, entries are sequential with:
_parse_by_paths method · python · L115-L184 (70 LOC)
research/tools/repo_analysis/xregistry_tool.py
    def _parse_by_paths(self):
        """Parse by finding all /setting/ paths in the file."""
        data = self.data
        pos = 0

        while pos < len(data):
            # Find next path-like string
            idx = data.find(b'/setting/', pos)
            if idx == -1:
                idx = data.find(b'/setting2/', pos)
            if idx == -1:
                break

            # Read the full path (null-terminated)
            end = data.find(b'\x00', idx)
            if end == -1 or end - idx > 256:
                pos = idx + 1
                continue

            path = data[idx:end].decode('ascii', errors='replace')

            # Look at bytes before the path for entry metadata
            # Typical: a few header bytes before the path string
            entry_header_start = max(0, idx - 8)
            header_bytes = data[entry_header_start:idx]

            # Try to determine entry type from header
            entry_type = 0
            data_offset = 0
            
list_entries method · python · L186-L190 (5 LOC)
research/tools/repo_analysis/xregistry_tool.py
    def list_entries(self, filter_path: Optional[str] = None) -> list:
        """List all entries, optionally filtered by path prefix."""
        if filter_path:
            return [e for e in self.entries if filter_path in e.path]
        return self.entries
Repobility analyzer · published findings · https://repobility.com
read_entry method · python · L192-L197 (6 LOC)
research/tools/repo_analysis/xregistry_tool.py
    def read_entry(self, path: str) -> Optional[XRegistryEntry]:
        """Read a specific entry by exact path."""
        for e in self.entries:
            if e.path == path:
                return e
        return None
search_entries method · python · L199-L202 (4 LOC)
research/tools/repo_analysis/xregistry_tool.py
    def search_entries(self, term: str) -> list:
        """Search entries by path substring."""
        term_lower = term.lower()
        return [e for e in self.entries if term_lower in e.path.lower()]
inject_value method · python · L204-L239 (36 LOC)
research/tools/repo_analysis/xregistry_tool.py
    def inject_value(self, path: str, value_hex: str, output_path: str) -> bool:
        """Inject a value at a given path and write to output file."""
        value_bytes = bytes.fromhex(value_hex.replace(' ', ''))

        entry = self.read_entry(path)
        if entry is None:
            print(f"ERROR: Path not found: {path}", file=sys.stderr)
            print("Available premo paths:", file=sys.stderr)
            for e in self.search_entries('premo'):
                print(f"  {e.path}", file=sys.stderr)
            return False

        # Find where to write the data
        # The data location depends on the entry format
        # For now, we'll write at the data_offset if known,
        # or right after the null terminator of the path
        write_offset = entry.data_offset if entry.data_offset else (
            entry.offset + len(entry.path.encode('ascii')) + 1
        )

        if write_offset + len(value_bytes) > len(self.data):
            print(f"ERROR: Write would exc
‹ prevpage 7 / 8next ›