Skip to content

Instantly share code, notes, and snippets.

@SutandoTsukai181
Created May 20, 2021 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SutandoTsukai181/b0edfb32687ea76cb7b21db65dc03bd0 to your computer and use it in GitHub Desktop.
Save SutandoTsukai181/b0edfb32687ea76cb7b21db65dc03bd0 to your computer and use it in GitHub Desktop.
Decrypts entries in chunks of 32 bytes with the XOR key for JoJo ASB/EoH sound *_ev.xfbin files.
#!/usr/bin/env python
__author__ = 'SutandoTsukai181'
__license__ = "MIT"
__version__ = '1.0'
import os
from itertools import cycle
from sys import argv
KEY = b'\x8C\x91\x9B\x9A\x89\xD1\x87\x99\x9D\x96\x91'
ENTRY_LEN = 32
BLOCK_LEN = 4
HELP = f"""{argv[0]} v{__version__}
By {__author__}
Decrypts entries in chunks of {ENTRY_LEN} bytes with the XOR key for JoJo ASB/EoH sound '_ev.xfbin' files.
Usage: {argv[0]} IN_PATH OUT_PATH
IN_PATH: path to input file with encrypted bytes
IN_PATH: path to output decrypted file
"""
def decrypt(path: str, out_path: str = None):
result = bytearray()
if not out_path:
out_path = path + ('.decrypted')
if not os.path.isfile(path):
raise Exception(f'File does not exist: {path}')
print('Decrypting...')
with open(path, 'rb') as f:
file = bytearray(f.read())
# align to entry size
if len(file) % ENTRY_LEN:
file.extend([0] * (ENTRY_LEN - (len(file) % ENTRY_LEN)))
for i in range(len(file) // ENTRY_LEN):
entry = file[i*ENTRY_LEN: (i+1)*ENTRY_LEN]
cur_key = cycle(KEY)
for j in range(ENTRY_LEN // BLOCK_LEN):
block = entry[j*BLOCK_LEN: (j+1)*BLOCK_LEN]
result.extend(list(map(lambda x: x ^ next(cur_key), block))[::-1])
with open(out_path, 'wb') as f:
f.write(result)
print(f'Result was written to {out_path}')
def main():
if len(argv) == 2:
decrypt(argv[1])
elif len(argv) == 3:
decrypt(argv[1], argv[2])
else:
print(HELP)
os.system('pause')
if __name__ == '__main__':
main()
@SutandoTsukai181
Copy link
Author

SutandoTsukai181 commented May 20, 2021

Link to encryption script: encrypt_ev.py

Encryption and decryption are 2 separate scripts (despite the code mostly being the same) for the convenience of being able to drag and drop files into each script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment