This decrypts and decompresses the sl2 files:

   1 import os, sys, zlib
   2 from rijndael import Rijndael
   3 from struct import unpack
   4 
   5 for fname in sys.argv[1:]:
   6     key = [0x04, 0x38, 0x04, 0x31, 0x2D, 0x32, 0x0C, 0x30, 0x43, 0x2E, 0x08, 0x04, 0x16, 0x30, 0x22, 0x0C]
   7     iv  = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
   8     with open(fname, "rb") as f:
   9         with open(fname.replace(".sl2", "")+".txt", "wb") as f2:
  10             print(f"handling {fname}")
  11             rjn = Rijndael(key, block_size = 16)
  12             fdata = f.read()
  13             
  14             plaintext_len = unpack(">I", fdata[0x4C:0x50])[0]
  15             ciphertext_len = (plaintext_len//16) * 16
  16             if ciphertext_len < plaintext_len:
  17                 ciphertext_len += 16
  18             
  19             data = fdata[0x50:ciphertext_len+0x50]
  20             
  21             decrypted = []
  22             while len(data) >= 16:
  23                 ciphertext = data[:16]
  24                 plaintext = rjn.decrypt(ciphertext)
  25                 for i in range(len(plaintext)):
  26                     plaintext[i] ^= iv[i]
  27                 decrypted += plaintext
  28                 iv = ciphertext
  29                 data = data[16:]
  30             decrypted = decrypted[:plaintext_len]
  31             
  32             if True:    
  33                 decompressed = zlib.decompress(bytes(decrypted))
  34             
  35                 string_len = unpack(">I", bytes(decompressed[0x2C:0x30]))[0]
  36                 text = decompressed[0x30:0x30+string_len-1]
  37             
  38                 f2.write(text)
  39             else:
  40                 f2.write(bytes(decrypted))

This parses them:

   1 import os, sys, json, re
   2 
   3 for fname in sys.argv[1:]:
   4     with open(fname, "r", encoding="cp932") as f:
   5         lines = []
   6         
   7         parsing_if = -1
   8         data = json.load(f)
   9         i = 0
  10         while len(data[i:]) > 0:
  11             entry = data[i]
  12             if parsing_if == 1:
  13                 if entry != "true":
  14                     print(entry)
  15                     print("^-- expected \"true\" block of if statement")
  16                     exit()
  17                 else:
  18                     parsing_if = 2
  19                     i += 1
  20                     continue
  21             if parsing_if == 2:
  22                 if entry == "false":
  23                     parsing_if = 3
  24                     i += 1
  25                     continue
  26             if parsing_if == 3:
  27                 if entry == "endif":
  28                     parsing_if = -1
  29                     i += 1
  30                     continue
  31             if isinstance(entry, str):
  32                 if entry == "_if":
  33                     if parsing_if != -1:
  34                         print("error: nested if statements not supported")
  35                     parsing_if = 1
  36                     i += 2
  37                     continue
  38                 
  39                 if entry[0] in "_":
  40                     # wild guess lol
  41                     if len(data[i:]) > 1 and not isinstance(data[i+1], str):
  42                         i += 2
  43                     else:
  44                         i += 1
  45                     continue
  46                 if entry[0] in "#":
  47                     i += 1
  48                     continue
  49                 if entry in ["ending"]:
  50                     i += 1
  51                     continue
  52                 if entry in ["false", "true", "endif"]:
  53                     print("in: "+fname)
  54                     print(parsing_if)
  55                     print("")
  56                     print(data[i-6])
  57                     print(data[i-5])
  58                     print(data[i-4])
  59                     print(data[i-3])
  60                     print(data[i-2])
  61                     print(data[i-1])
  62                     print(data[i] + " <---!!")
  63                     print(data[i+1])
  64                     print(data[i+2])
  65                     print(data[i+3])
  66                     print(data[i+4])
  67                     print(data[i+5])
  68                     print(data[i+6])
  69                     exit()
  70                 if entry[0] in "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_#":
  71                     print(data[i-6])
  72                     print(data[i-5])
  73                     print(data[i-4])
  74                     print(data[i-3])
  75                     print(data[i-2])
  76                     print(data[i-1])
  77                     print(data[i] + " <---()")
  78                     print(data[i+1])
  79                     print(data[i+2])
  80                     print(data[i+3])
  81                     print(data[i+4])
  82                     print(data[i+5])
  83                     print(data[i+6])
  84                     exit()
  85                 lines += [entry]
  86                 i += 1
  87             else:
  88                 print(entry)
  89                 print("^-- unexpected list")
  90                 exit()
  91         
  92         lastline = ""
  93         for line in lines:
  94             if line[0] != '/':
  95                 if lastline.endswith(""):
  96                     lastline = re.sub(r"[^「]*(「.*」)", r"\1", lastline)
  97                 print(lastline)
  98                 lastline = line
  99             else:
 100                 lastline += line[1:]
 101             #if line.endswith("」"):
 102             #    line = 

rijndael.py is here: https://gist.github.com/wareya/e00c80c9d346312354d45516978e3376

Koichoco (last edited 2018-05-12 22:13:17 by weh)