Information in binascii.hexlify() Doesn't Slice Correctly?

13 Views Asked by At

I'm attempting to take a binary data file exported from a program I'm using, hexlify it using the binascii module, and retrieve the data that I need so I can eventually output that data in a Qt GUI. So far this is what I've got:

import binascii, functools, struct
from pathlib import Path

def read_value(dataset, start, length, encoding):
    unhex = binascii.unhexlify(dataset[start * 2:(start + length) * 2])
    unpack = struct.unpack(encoding, unhex)
    data = functools.reduce(lambda result, decrypted: result * 10 + decrypted, unpack)

    return data

class Inventory:
    def __init__(self, dataset, category):
        self.dataset = dataset
        self.category = category

    def get_data(self):
        if self.category == 'collectibles':
            data = self.dataset[0x55060:0x56448]

        return data

class Item:
    def __init__(self, data, offset):
        self.item_id = read_value(data, offset + 0x0, 0x2, '<H')
        self.index = read_value(data, offset + 0x2, 0x2, '<H')
        self.category = read_value(data, offset + 0x4, 0x1, '<B')
        self.amount = read_value(data, offset + 0xC, 0x2, '<H')
        self.status = read_value(data, offset + 0xE, 0x2, '<H')

the_file = Path('../file.sav').read_bytes()
the_dataset = binascii.hexlify(the_file)
the_collectibles = Inventory(the_dataset, 'collectibles').get_data()
the_items = [Item(the_collectibles, 0x0), Item(the_collectibles, 0x10)]

print(the_items[0].__dict__)
print(the_items[1].__dict__)

However, I'm getting data that I know shouldn't be there...

Using the above code, I expect the output data at the specified offsets between 0x55060 to 0x56448 to be:

{'item_id': 2002, 'index': 0, 'category': 3, 'amount': 99, 'status': 1}
{'item_id': 2059, 'index': 1, 'category': 3, 'amount': 45, 'status': 1}

However, I get the following numbers that definitely shouldn't exist at those positions:

{'item_id': 65535, 'index': 45928, 'category': 10, 'amount': 65150, 'status': 4614}
{'item_id': 65535, 'index': 0, 'category': 181, 'amount': 20489, 'status': 8093}

If I actually do the following, bypassing the classes and slice, and providing absolute values, I get the numbers that I expect:

item_id = read_value(the_dataset, 0x55060, 0x2, '<H')
index = read_value(the_dataset, 0x55062, 0x2, '<H')
category = read_value(the_dataset, 0x55064, 0x1, '<B')
amount = read_value(the_dataset, 0x5506C, 0x2, '<H')
status = read_value(the_dataset, 0x5506E, 0x2, '<H')

It just seems really like that data = self.dataset[0x55060:0x56448] in the Inventory class isn't slicing the data correctly? I'm not sure if I'm doing something wrong, or if there's another module I should be using to slice the data. Or should I be slicing the data at all?

Any advice would be greatly appreciated!

0

There are 0 best solutions below