KeyFC欢迎致辞,点击播放
资源、介绍、历史、Q群等新人必读
KeyFC 社区总索引
如果你找到这个笔记本,请把它邮寄给我们的回忆
KeyFC 漂流瓶传递活动 Since 2011
 

th09(东方花映塚)文件提取器 试作型 (充当生日礼物的东西)

[ 10723 查看 / 5 回复 ]

回复:th09(东方花映塚)文件提取器 试作型 (充当生日礼物的东西)

=.=

TH09的提取以及合并程序早在半年前就做出来了……

其实TH09的加密算法和TH08的一模一样……就是加密参数不同而已。

在做TH08汉化的时候就已经写好的TH09的解码程序……

可惜现在渔场汉化组集体偷懒中……不知道啥时候才做th09的汉化……
分享 转发
http://sadan9.3322.org/temp/remi1.jpg
TOP

回复:th09(东方花映塚)文件提取器 试作型 (充当生日礼物的东西)

def deobfuscate(src, xorval, xoradd, blocksize, changesize):
    src = array('B', src)
    dest = array('B', src)
    size = len(src)
   
    restsize = size % blocksize
    if restsize >= blocksize / 4: restsize = 0
    restsize += (size & 1)

    size -= restsize

    src_idx = 0
    dest_idx_block = 0

    while changesize > 0 and size > 0:
        if size < blocksize:
            blocksize = size

        dest_idx_block += blocksize

        dest_idx = dest_idx_block - 1
        for nothing in range((blocksize + 1) >> 1):
            dest[dest_idx] = src[src_idx] ^ xorval
            xorval = (xorval + xoradd) % 256
            dest_idx -= 2
            src_idx += 1

        dest_idx = dest_idx_block - 2
        for nothing in range(blocksize >> 1):
            dest[dest_idx] = src[src_idx] ^ xorval
            xorval = (xorval + xoradd) % 256
            dest_idx -= 2
            src_idx += 1

        size -= blocksize
        changesize -= blocksize

    size += restsize
    assert dest_idx_block == src_idx
    assert size == len(src) - src_idx
    return dest

class reader(object):
    def __init__(self, infile):
        self.infile = infile

    def read_entries(self):
        (magic, blob) = struct.unpack('<4s12s', self.infile.read(16))

        check.equal('Magic number', magic, 'PBGZ')

        blob = deobfuscate(blob, 0x1B, 0x37, 12, 1024)

        (num_entries, index_offset, index_size_unpacked
        ) = struct.unpack('<LLL', blob)

        num_entries -= 123456
        index_offset -= 345678
        index_size_unpacked -= 567891

        print '%s files' % num_entries

        self.infile.seek(0, 2)
        filesize = self.infile.tell()

        self.infile.seek(index_offset)
        index_size_packed = filesize - index_offset
        packed_index = array('B')
        packed_index.fromfile(self.infile, index_size_packed)

        packed_index = deobfuscate(packed_index, 0x3E, 0x9B, 128, 1024)

        index = array('B', 'x' * index_size_unpacked)
        lzss.decompress(packed_index, index)

        entries = self.parse_index(index, num_entries)

        end_entry = dat.entry()
        end_entry.offs = index_offset
        for e, next_e in util.iterate_pairs(itertools.chain(entries, [end_entry])):
            e.packed_size = next_e.offs - e.offs
            print '%s: offs %s, packed size %s, unpacked size %s, flags %s'                  % (e.name, e.offs, e.packed_size, e.size, e.flags)
            yield e

    def parse_index(self, index, num_entries):
        entry_pos = 0
        for nothing in range(num_entries):
            name_len = 0
            while index[entry_pos + name_len]:
                name_len += 1

            e = dat.entry(self)
            e.name = index[entry_pos : entry_pos + name_len].tostring()
            (e.offs, e.size, e.flags) = struct.unpack('<LLL',index[entry_pos+name_len+1:entry_pos + name_len + 13])
            entry_pos += name_len + 13
            yield e

    def read_compressed(self, entry):
        self.infile.seek(entry.offs)
        entry.packed = array('B')
        entry.packed.fromfile(self.infile, entry.packed_size)

    def decompress(self, entry):
        entry.data = array('B', 'x' * entry.size)
        lzss.decompress(entry.packed, entry.data)
        if entry.data[:3].tostring() == 'edz':
            print chr(entry.data[3])
            entry.data = deobfuscate(entry.data[4:],*obfuscations[chr(entry.data[3])])


关键的解码就这些了……
http://sadan9.3322.org/temp/remi1.jpg
TOP