Phoenix TDK Packer Extractor v2.0_a6

Dramatically increase TDK Packer base offset detection speed

Applied regex pattern improvements
This commit is contained in:
platomav 2022-05-24 14:36:46 +03:00
parent 8b561640db
commit aea54aeaad
3 changed files with 29 additions and 15 deletions

View file

@ -7,7 +7,7 @@ Phoenix TDK Packer Extractor
Copyright (C) 2021-2022 Plato Mavropoulos
"""
TITLE = 'Phoenix TDK Packer Extractor v2.0_a5'
TITLE = 'Phoenix TDK Packer Extractor v2.0_a6'
import os
import sys
@ -92,29 +92,36 @@ def get_tdk_base(in_buffer, pack_off):
for mz in mz_ord:
mz_off = mz.start()
# MZ (DOS) > PE (NT) image offset is found at offset 0x3C-0x40 relative to MZ base
# MZ (DOS) > PE (NT) image Offset is found at offset 0x3C-0x40 relative to MZ base
pe_off = mz_off + int.from_bytes(in_buffer[mz_off + 0x3C:mz_off + 0x40], 'little')
# Skip MZ (DOS) with bad PE (NT) image Offset
if pe_off == mz_off or pe_off >= pack_off:
continue
# Check if potential MZ > PE image magic value is valid
if PAT_MICROSOFT_PE.search(in_buffer[pe_off:pe_off + 0x4]):
try:
# Analyze detected MZ > PE image buffer
pe_file = pefile.PE(data=in_buffer[mz_off:])
# Analyze detected MZ > PE image buffer quickly (fast_load)
pe_file = pefile.PE(data=in_buffer[mz_off:], fast_load=True)
# Since fast_load is used, IMAGE_DIRECTORY_ENTRY_RESOURCE must be parsed for FileInfo > StringTable
pe_file.parse_data_directories(directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_RESOURCE']])
# Attempt to retrieve the PE > "Product Name" version string value
pe_name = pe_file.FileInfo[0][0].StringTable[0].entries[b'ProductName']
pe_name = pe_file.FileInfo[0][0].StringTable[0].entries[b'ProductName'].upper()
except:
# Any error means no PE > "Product Name" retrieved
pe_name = b''
# Check for valid Phoenix TDK Packer PE > "Product Name"
# Expected value is "TDK Packer (Extractor for Windows)"
if pe_name.upper().startswith(b'TDK PACKER'):
if pe_name.startswith(b'TDK PACKER'):
# Set TDK Base Offset to valid TDK Packer MZ offset
tdk_base_off = mz_off
# Stop parsing detected MZ once TDK Base Offset is found
if tdk_base_off:
if tdk_base_off is not None:
break
else:
# No TDK Base Offset could be found, assume 0x0

View file

@ -7,7 +7,7 @@ Portwell EFI Update Extractor
Copyright (C) 2021-2022 Plato Mavropoulos
"""
TITLE = 'Portwell EFI Update Extractor v2.0_a6'
TITLE = 'Portwell EFI Update Extractor v2.0_a7'
import os
import sys
@ -37,8 +37,8 @@ def is_portwell_efi(in_file):
try: pe_buffer = get_portwell_pe(in_buffer)[1]
except: pe_buffer = b''
is_mz = in_buffer.startswith(PAT_MICROSOFT_MZ.pattern) # EFI images start with PE Header MZ
is_uu = pe_buffer.startswith(PAT_PORTWELL_EFI.pattern) # Portwell EFI files start with <UU>
is_mz = PAT_MICROSOFT_MZ.search(in_buffer[:0x2]) # EFI images start with PE Header MZ
is_uu = PAT_PORTWELL_EFI.search(pe_buffer[:0x4]) # Portwell EFI files start with <UU>
return is_mz and is_uu
@ -52,6 +52,8 @@ def get_portwell_pe(in_buffer):
# Parse & Extract Portwell UEFI Unpacker
def portwell_efi_extract(input_buffer, output_path, padding=0):
efi_files = [] # Initialize EFI Payload file chunks
extract_path = os.path.join(f'{output_path}_extracted')
make_dirs(extract_path, delete=True)
@ -62,9 +64,14 @@ def portwell_efi_extract(input_buffer, output_path, padding=0):
printer(efi_title, padding)
efi_files = pe_data.split(PAT_PORTWELL_EFI.pattern) # Split EFI Payload into <UU> file chunks
# Split EFI Payload into <UU> file chunks
efi_list = list(PAT_PORTWELL_EFI.finditer(pe_data))
for i,_ in enumerate(efi_list):
efi_bgn = efi_list[i].end()
efi_end = len(pe_data) if i == len(efi_list) - 1 else efi_list[i + 1].start()
efi_files.append(pe_data[efi_bgn:efi_end])
parse_efi_files(extract_path, efi_files[1:], padding)
parse_efi_files(extract_path, efi_files, padding)
# Get Portwell UEFI Unpacker tag
def get_unpacker_tag(input_buffer, pe_file):

View file

@ -7,13 +7,13 @@ Copyright (C) 2022 Plato Mavropoulos
import re
PAT_AMI_PFAT = re.compile(b'_AMIPFAT.AMI_BIOS_GUARD_FLASH_CONFIGURATIONS', re.DOTALL)
PAT_AMI_PFAT = re.compile(br'_AMIPFAT.AMI_BIOS_GUARD_FLASH_CONFIGURATIONS', re.DOTALL)
PAT_AMI_UCP = re.compile(br'@(UAF|HPU).{12}@', re.DOTALL)
PAT_DELL_FTR = re.compile(br'\xEE\xAA\xEE\x8F\x49\x1B\xE8\xAE\x14\x37\x90')
PAT_DELL_HDR = re.compile(br'\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.\x78\x9C', re.DOTALL)
PAT_DELL_PKG = re.compile(br'\x72\x13\x55\x00.{45}7zXZ', re.DOTALL)
PAT_INTEL_ENG = re.compile(br'\x04\x00{3}[\xA1\xE1]\x00{3}.{8}\x86\x80.{9}\x00\$((MN2)|(MAN))', re.DOTALL)
PAT_MICROSOFT_MZ = re.compile(br'MZ')
PAT_MICROSOFT_PE = re.compile(br'PE\x00\x00')
PAT_MICROSOFT_PE = re.compile(br'PE\x00{2}')
PAT_PHOENIX_TDK = re.compile(br'\$PACK\x00{3}..\x00{2}.\x00{3}', re.DOTALL)
PAT_PORTWELL_EFI = re.compile(br'<UU>')
PAT_PORTWELL_EFI = re.compile(br'<U{2}>')