|
@ -38,14 +38,14 @@ def dump(input_path, output_path = None): |
|
|
key_data = unpad(cryptor.decrypt(key_data))[17:] |
|
|
key_data = unpad(cryptor.decrypt(key_data))[17:] |
|
|
key_length = len(key_data) |
|
|
key_length = len(key_data) |
|
|
|
|
|
|
|
|
# key box |
|
|
# key box (standard RC4 Key-scheduling algorithm) |
|
|
key_data = bytearray(key_data) |
|
|
key = bytearray(key_data) |
|
|
key_box = bytearray(range(256)) |
|
|
S = bytearray(range(256)) |
|
|
j = 0 |
|
|
j = 0 |
|
|
|
|
|
|
|
|
for i in range(256): |
|
|
for i in range(256): |
|
|
j = (key_box[i] + j + key_data[i % key_length]) & 0xff |
|
|
j = (j + S[i] + key[i % key_length]) % 256 |
|
|
key_box[i], key_box[j] = key_box[j], key_box[i] |
|
|
S[i], S[j] = S[j], S[i] |
|
|
|
|
|
|
|
|
# meta data |
|
|
# meta data |
|
|
meta_length = f.read(4) |
|
|
meta_length = f.read(4) |
|
@ -72,19 +72,18 @@ def dump(input_path, output_path = None): |
|
|
# media data |
|
|
# media data |
|
|
output_path = output_path(input_path, meta_data) |
|
|
output_path = output_path(input_path, meta_data) |
|
|
m = open(output_path,'wb') |
|
|
m = open(output_path,'wb') |
|
|
|
|
|
data = bytearray(f.read()) |
|
|
|
|
|
|
|
|
while True: |
|
|
# stream cipher (modified RC4 Pseudo-random generation algorithm) |
|
|
chunk = bytearray(f.read(0x8000)) |
|
|
i = 0 |
|
|
chunk_length = len(chunk) |
|
|
j = 0 |
|
|
if not chunk: |
|
|
for k, _ in enumerate(data): |
|
|
break |
|
|
i = (i + 1) % 256 |
|
|
|
|
|
j = (i + S[i]) % 256 # in RC4, is j = (j + S[i]) % 256 |
|
|
for i in range(chunk_length): |
|
|
# S[i], S[j] = S[j], S[i] # skip swapping |
|
|
j = (i + 1) & 0xff |
|
|
data[k] ^= S[(S[i] + S[j]) % 256] |
|
|
chunk[i] ^= key_box[(key_box[j] + key_box[(key_box[j] + j) & 0xff]) & 0xff] |
|
|
|
|
|
|
|
|
|
|
|
m.write(chunk) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m.write(data) |
|
|
m.close() |
|
|
m.close() |
|
|
f.close() |
|
|
f.close() |
|
|
|
|
|
|
|
|