Difference between revisions of "Dynasty Warriors Online file extractor"

From SoundDB
Jump to: navigation, search
(Created page with "<pre> #!/usr/bin/python # # Dynasty Warriors Online file extractor 0.1 by hcs import io from sys import argv from struct import unpack def unpack_file(infile, offset, name): ...")
 
(No difference)

Latest revision as of 10:06, 24 May 2011

#!/usr/bin/python
#
# Dynasty Warriors Online file extractor 0.1 by hcs

import io
from sys import argv
from struct import unpack

def unpack_file(infile, offset, name):
    infile.seek(offset)

    # check the header
    if infile.read(4) != "KOVS":
        return 0

    # read file size
    file_size = unpack('<I',infile.read(4))[0]

    # skip padding
    # TODO: check that padding is all 0s?
    infile.seek(offset+0x20)

    # read the file
    oggbuf = bytearray(file_size)
    infile.readinto(oggbuf)

    # deobfuscate
    for i in range(0,0x100):
        oggbuf[i] = oggbuf[i] ^ i

    # write to the output
    outfile = open(name,'wb')
    outfile.write(oggbuf)

    print name, file_size, "bytes"

    return 1

###

if len(argv) != 2:
    print "Decrypt Ogg files from Dynasty Warriors Online"
    print "usage: dwo_xor.py input.bin"
    exit(1)

# open input
infile_name = argv[1]
infile = open(infile_name,'rb')

# try to just dump file straightaway
if unpack_file(infile, 0, '%s.ogg' % infile_name):
    print "ok"
    exit(0)

# read known parts of header
infile.seek(0xC)
header_size, subfile_count = unpack('<IxxxxI',infile.read(12))

if header_size != 0x18 + 4*subfile_count:
    print "header consistency check failed"
    exit(1)

file_offsets = unpack('<'+'I'*subfile_count,infile.read(4*subfile_count))
for offset in file_offsets:
    if not unpack_file(infile, offset, \
        '%s_%08x.ogg' % \
        (infile_name, offset)):
        print "unpack failed"
        exit(1)

print "ok!"