mirror of
https://gitea.tendokyu.moe/beerpsi/x.git
synced 2024-11-27 17:00:51 +01:00
Add title server enc key scripts
This commit is contained in:
parent
e55107fe2a
commit
d5fd61fd5e
91
chuni/calc_title_server_enc_key.py
Normal file
91
chuni/calc_title_server_enc_key.py
Normal file
@ -0,0 +1,91 @@
|
||||
from hashlib import pbkdf2_hmac
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
import re
|
||||
|
||||
from Crypto.Hash import SHA1
|
||||
import pefile
|
||||
|
||||
from Crypto.Protocol.KDF import PBKDF2
|
||||
|
||||
def rva2offset(pe: pefile.PE, rva: int):
|
||||
for section in pe.sections:
|
||||
if section.contains_rva(rva):
|
||||
return section.get_offset_from_rva(rva)
|
||||
|
||||
return -1
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print(f"Usage: python {os.path.basename(__file__)} <PATH TO EXE>")
|
||||
exit(1)
|
||||
|
||||
exe_path = sys.argv[1]
|
||||
|
||||
KEY_PASSWORD_RE = re.compile(rb"\?AVSystemInterface@projClient@@....(?P<offset>....)")
|
||||
KEY_SALT_RE = re.compile(rb"\x50\x6A\x20\x6A(?P<iterations>.)\x6A\x10\x2B\xCA\x68(?P<offset>....)\x51\x55\xE8....")
|
||||
SALT_PASSWORD_RE = re.compile(rb"\?AVDeflate@projClient@@\x00\x00\x00\x00....(?P<offset1>....)(?P<offset2>....)")
|
||||
SALT_SALT_RE = re.compile(rb"\x52\x6A\x08\x6A(?P<iterations>.)\x6A\x10\x68(?P<offset>....)\x51\x53\xE8....")
|
||||
IV_RE_1 = re.compile(rb"\xF3\x0F\x7E\x05(?P<offset>....)\x8B\x74\x24\x24\x6A\x01")
|
||||
IV_RE_2 = re.compile(rb"\xE8....\xF3\x0F\x7E\x05(?P<offset>....)\x6A\x01")
|
||||
ITER_COUNT_RE = re.compile(rb"\xC7\x86....(?P<count>....)\x0F\x8C....\x85\xED\x0F\x84....\x85\xDB\x0F\x84....")
|
||||
|
||||
with open(exe_path, "rb") as f:
|
||||
exe = f.read()
|
||||
|
||||
pe = pefile.PE(data=exe, fast_load=True)
|
||||
base_address = pe.OPTIONAL_HEADER.ImageBase
|
||||
|
||||
if (pmatch := KEY_PASSWORD_RE.search(exe)) and (smatch := KEY_SALT_RE.search(exe)):
|
||||
poffset = rva2offset(pe, struct.unpack("<I", pmatch.group("offset"))[0] - base_address)
|
||||
soffset = rva2offset(pe, struct.unpack("<I", smatch.group("offset"))[0] - base_address)
|
||||
poffset_end = poffset + exe[poffset:].index(0)
|
||||
|
||||
password = exe[poffset:poffset_end].decode("utf-8")
|
||||
salt = exe[soffset:soffset + 16]
|
||||
|
||||
key = PBKDF2(
|
||||
password,
|
||||
salt,
|
||||
dkLen=32,
|
||||
count=smatch.group("iterations")[0],
|
||||
hmac_hash_module=SHA1,
|
||||
)
|
||||
key = bytes((x % 0x5E) + 0x21 for x in key)
|
||||
|
||||
print(f"Key: {key.hex()}")
|
||||
|
||||
if (ivmatch := IV_RE_1.search(exe)):
|
||||
ivoffset = rva2offset(pe, struct.unpack("<I", ivmatch.group("offset"))[0] - base_address)
|
||||
print(f"IV: {exe[ivoffset:ivoffset + 16].hex()}")
|
||||
elif (ivmatch := IV_RE_2.search(exe)):
|
||||
ivoffset = rva2offset(pe, struct.unpack("<I", ivmatch.group("offset"))[0] - base_address)
|
||||
print(f"IV: {exe[ivoffset:ivoffset + 16].hex()}")
|
||||
|
||||
if (pmatch := SALT_PASSWORD_RE.search(exe)) and (smatch := SALT_SALT_RE.search(exe)):
|
||||
poffset = rva2offset(pe, struct.unpack("<I", pmatch.group("offset1"))[0] - base_address)
|
||||
|
||||
if poffset == -1:
|
||||
poffset = rva2offset(pe, struct.unpack("<I", pmatch.group("offset2"))[0] - base_address)
|
||||
|
||||
soffset = rva2offset(pe, struct.unpack("<I", smatch.group("offset"))[0] - base_address)
|
||||
poffset_end = poffset + exe[poffset:].index(0)
|
||||
|
||||
password = exe[poffset:poffset_end].decode("utf-8")
|
||||
salt = exe[soffset:soffset + 16]
|
||||
|
||||
key = PBKDF2(
|
||||
password,
|
||||
salt,
|
||||
dkLen=8,
|
||||
count=smatch.group("iterations")[0],
|
||||
hmac_hash_module=SHA1,
|
||||
)
|
||||
print(f"Endpoint salt: {key.hex()}")
|
||||
|
||||
if (match := ITER_COUNT_RE.search(exe)):
|
||||
iter_count = struct.unpack("<I", match.group("count"))[0]
|
||||
|
||||
print(f"Iterations: {iter_count}")
|
||||
|
||||
|
42
geki/calc_title_server_enc_key.py
Normal file
42
geki/calc_title_server_enc_key.py
Normal file
@ -0,0 +1,42 @@
|
||||
from hashlib import blake2b
|
||||
import os
|
||||
import sys
|
||||
|
||||
# MU3.Sys.System.keyIvDigestFixed
|
||||
KEY_IV_DIGEST_FIXED = bytes([
|
||||
179, 10, 98, 130, 17, 166, 184, 233, 246, 211,
|
||||
46, 229, 236, 79, 78, 83, 107, 151, 195, 172,
|
||||
57, 72, 120, 103, 17, 124, 18, 64, 15, 225,
|
||||
169, 39
|
||||
])
|
||||
|
||||
if len(sys.argv) < 4:
|
||||
print(f"Usage: python {os.path.basename(__file__)} <noise0> <noise1> <noise2>")
|
||||
exit(1)
|
||||
|
||||
with open(sys.argv[1], "rb") as f:
|
||||
key = blake2b(
|
||||
f.read(),
|
||||
digest_size=32,
|
||||
key=KEY_IV_DIGEST_FIXED,
|
||||
).hexdigest()
|
||||
|
||||
print(f"Key: {key}")
|
||||
|
||||
with open(sys.argv[2], "rb") as f:
|
||||
iv = blake2b(
|
||||
f.read(),
|
||||
digest_size=32,
|
||||
key=KEY_IV_DIGEST_FIXED,
|
||||
).hexdigest()
|
||||
|
||||
print(f"IV: {iv}")
|
||||
|
||||
with open(sys.argv[3], "rb") as f:
|
||||
salt = blake2b(
|
||||
f.read(),
|
||||
digest_size=32,
|
||||
key=KEY_IV_DIGEST_FIXED,
|
||||
).hexdigest()
|
||||
|
||||
print(f"Endpoint salt: {salt}")
|
Loading…
Reference in New Issue
Block a user