mirror of https://github.com/UMSKT/DB.git
96 lines
3.7 KiB
Python
96 lines
3.7 KiB
Python
import hashlib
|
|
import parser.pidgen.bink as bink
|
|
import pefile
|
|
|
|
|
|
def bink_out(resource_data):
|
|
# Process the resource data
|
|
# bink_id = "%02x" % int.from_bytes(resource_data[0x00:0x04], 'little')
|
|
sha1_hash = hashlib.sha1(resource_data).hexdigest()
|
|
data = bink.parse(resource_data)
|
|
data["sha1_hash"] = sha1_hash
|
|
|
|
return data
|
|
|
|
|
|
def parse(file_data):
|
|
output = {}
|
|
|
|
found_bink = 0
|
|
# attempt extracting via the PE directory
|
|
try:
|
|
# Load the DLL using pefile
|
|
pe = pefile.PE(data=file_data)
|
|
|
|
# Loop over the resources in the DLL
|
|
for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
|
|
if resource_type.name is not None and resource_type.name.string.decode() == 'BINK':
|
|
found_bink = 1
|
|
# Extract resources from the "BINK" resource type
|
|
for resource_id_entry in resource_type.directory.entries:
|
|
for resource_entry in resource_id_entry.directory.entries:
|
|
resource_offset = resource_entry.data.struct.OffsetToData
|
|
resource_size = resource_entry.data.struct.Size
|
|
|
|
# Access the resource data
|
|
resource_data = pe.get_memory_mapped_image()[resource_offset: resource_offset + resource_size]
|
|
|
|
bink_id = "%08x" % int.from_bytes(resource_data[0x00:0x04], 'little')
|
|
output[bink_id] = bink_out(resource_data)
|
|
|
|
# Close the PE file
|
|
pe.close()
|
|
except pefile.PEFormatError as e:
|
|
found_bink = 0
|
|
except AttributeError as e:
|
|
found_bink = 0
|
|
|
|
# attempt a string search
|
|
if found_bink == 0:
|
|
|
|
string_1998 = b'\xAE\xDF\x30\x01'
|
|
string_2002 = b'\xC4\x7C\x31\x01'
|
|
entries = {}
|
|
for i in range(len(file_data) - 3):
|
|
if ((file_data[i:i + 4] == string_1998 and i + 0x170 < len(file_data) and (
|
|
file_data[i + 0x170:i + 0x170 + 4] == string_1998)) or (
|
|
file_data[i:i + 4] == string_1998 and i - 0x170 > 0 and (
|
|
file_data[i - 0x170:i - 0x170 + 4] == string_1998))):
|
|
start = i - 16
|
|
end = start + int.from_bytes(file_data[start + 4:start + 8], 'little') + 4
|
|
entries[start] = {
|
|
"Type": "BINK1998",
|
|
"StartAddress": start,
|
|
"EndAddress": end
|
|
}
|
|
|
|
if ((file_data[i:i + 4] == string_1998 and i + 0x180 < len(file_data) and (
|
|
file_data[i + 0x180:i + 0x180 + 4] == string_1998)) or (
|
|
file_data[i:i + 4] == string_1998 and i - 0x180 > 0 and (
|
|
file_data[i - 0x180:i - 0x180 + 4] == string_1998))):
|
|
start = i - 16
|
|
end = start + int.from_bytes(file_data[start + 4:start + 8], 'little') + 4
|
|
entries[start] = {
|
|
"Type": "BINK1998",
|
|
"StartAddress": start,
|
|
"EndAddress": end
|
|
}
|
|
|
|
elif file_data[i:i + 4] == string_2002 and i + 0x1E8 < len(file_data) and (
|
|
file_data[i + 0x1E8:i + 0x1E8 + 4] == string_2002):
|
|
start = i - 16
|
|
end = start + int.from_bytes(file_data[start + 4:start + 8], 'little') + 4
|
|
entries[start] = {
|
|
"Type": "BINK2002",
|
|
"StartAddress": start,
|
|
"EndAddress": end
|
|
}
|
|
|
|
if len(entries) != 0:
|
|
for key, value in entries.items():
|
|
bink_data = file_data[key:value['EndAddress']]
|
|
bink_id = "%08x" % int.from_bytes(bink_data[0x00:0x04], 'little')
|
|
output[bink_id] = bink_out(bink_data)
|
|
|
|
return output
|