Insyde iFlash/iFdPacker Extractor v2.0_a9

Support for hardcoded Insyde 7-Zip SFX password

Fixed 7-Zip hang on password protected files
This commit is contained in:
platomav 2022-07-07 01:31:29 +03:00
parent 69784889cb
commit df47293d01
4 changed files with 49 additions and 21 deletions

View file

@ -7,7 +7,7 @@ Insyde iFlash/iFdPacker Extractor
Copyright (C) 2022 Plato Mavropoulos
"""
TITLE = 'Insyde iFlash/iFdPacker Extractor v2.0_a8'
TITLE = 'Insyde iFlash/iFdPacker Extractor v2.0_a9'
import os
import sys
@ -33,6 +33,9 @@ class IflashHeader(ctypes.LittleEndianStructure):
# 0x18
]
def _get_padd_len(self):
return self.TotalSize - self.ImageSize
def get_image_tag(self):
return self.ImageTag.decode('utf-8','ignore').strip('_')
@ -41,6 +44,7 @@ class IflashHeader(ctypes.LittleEndianStructure):
printer(['Image Name:', self.get_image_tag()], p, False)
printer(['Image Size:', f'0x{self.ImageSize:X}'], p, False)
printer(['Total Size:', f'0x{self.TotalSize:X}'], p, False)
printer(['Padd Size :', f'0x{self._get_padd_len():X}'], p, False)
# Check if input is Insyde iFlash/iFdPacker Update image
def is_insyde_ifd(input_file):
@ -73,15 +77,16 @@ def insyde_iflash_detect(input_buffer):
for iflash_match in PAT_INSYDE_IFL.finditer(input_buffer):
ifl_bgn = iflash_match.start()
if len(input_buffer[ifl_bgn:]) <= IFL_HDR_LEN:
if len(input_buffer[ifl_bgn:]) <= INS_IFL_LEN:
continue
ifl_hdr = get_struct(input_buffer, ifl_bgn, IflashHeader)
if ifl_hdr.TotalSize in iflash_match_nan \
or ifl_hdr.ImageSize in iflash_match_nan \
or ifl_hdr.TotalSize <= ifl_hdr.ImageSize:
or ifl_hdr.TotalSize < ifl_hdr.ImageSize \
or ifl_bgn + INS_IFL_LEN + ifl_hdr.TotalSize > len(input_buffer):
continue
iflash_match_all.append([ifl_bgn, ifl_hdr])
@ -93,21 +98,28 @@ def insyde_iflash_extract(input_buffer, extract_path, padding=0):
insyde_iflash_all = insyde_iflash_detect(input_buffer)
if not insyde_iflash_all:
return 1
return 127
printer('Detected Insyde iFlash Update image!', padding)
make_dirs(extract_path, delete=True)
exit_codes = []
for insyde_iflash in insyde_iflash_all:
exit_code = 0
ifl_bgn,ifl_hdr = insyde_iflash
img_bgn = ifl_bgn + IFL_HDR_LEN
img_bgn = ifl_bgn + INS_IFL_LEN
img_end = img_bgn + ifl_hdr.ImageSize
img_bin = input_buffer[img_bgn:img_end]
if len(img_bin) != ifl_hdr.ImageSize:
exit_code = 1
img_val = [ifl_hdr.get_image_tag(), 'bin']
img_tag,img_ext = IFL_IMG_NAMES.get(img_val[0], img_val)
img_tag,img_ext = INS_IFL_IMG.get(img_val[0], img_val)
img_name = f'{img_tag} [0x{img_bgn:08X}-0x{img_end:08X}]'
@ -126,8 +138,10 @@ def insyde_iflash_extract(input_buffer, extract_path, padding=0):
out_image.write(img_bin)
printer(f'Succesfull Insyde iFlash > {img_tag} extraction!', padding + 12)
exit_codes.append(exit_code)
return 0
return sum(exit_codes)
# Extract Insyde iFdPacker 7-Zip SFX 7z Update image
def insyde_packer_extract(input_buffer, extract_path, padding=0):
@ -143,22 +157,27 @@ def insyde_packer_extract(input_buffer, extract_path, padding=0):
sfx_buffer = bytearray(input_buffer[match_sfx.end() - 0x5:])
if sfx_buffer[:0x5] == b'\x6E\xF4\x79\x5F\x4E':
printer('Detected Insyde iFdPacker > 7-Zip SFX obfuscation!', padding + 4)
printer('Detected Insyde iFdPacker > 7-Zip SFX > Obfuscation!', padding + 4)
for index,byte in enumerate(sfx_buffer):
sfx_buffer[index] = byte // 2 + (128 if byte % 2 else 0)
printer('Removed Insyde iFdPacker > 7-Zip SFX obfuscation!', padding + 8)
printer('Removed Insyde iFdPacker > 7-Zip SFX > Obfuscation!', padding + 8)
printer('Extracting Insyde iFdPacker > 7-Zip SFX archive...', padding + 4)
if bytes(INS_SFX_PWD, 'utf-16le') in input_buffer[:match_sfx.start()]:
printer('Detected Insyde iFdPacker > 7-Zip SFX > Password!', padding + 8)
printer(INS_SFX_PWD, padding + 12)
sfx_path = os.path.join(extract_path, 'Insyde_iFdPacker_SFX.7z')
with open(sfx_path, 'wb') as sfx_file:
sfx_file.write(sfx_buffer)
if is_szip_supported(sfx_path, padding + 8, check=True):
if szip_decompress(sfx_path, extract_path, 'Insyde iFdPacker > 7-Zip SFX', padding + 8, check=True) == 0:
if is_szip_supported(sfx_path, padding + 8, password=INS_SFX_PWD, check=True):
if szip_decompress(sfx_path, extract_path, 'Insyde iFdPacker > 7-Zip SFX',
padding + 8, password=INS_SFX_PWD, check=True) == 0:
os.remove(sfx_path)
else:
return 125
@ -170,13 +189,18 @@ def insyde_packer_extract(input_buffer, extract_path, padding=0):
for sfx_file in get_path_files(extract_path):
if is_insyde_ifd(sfx_file):
printer(f'{os.path.basename(sfx_file)}', padding + 12)
ifd_code = insyde_ifd_extract(sfx_file, sfx_file, padding + 16)
exit_codes.append(ifd_code)
return sum(exit_codes)
# Insyde iFlash Image Names
IFL_IMG_NAMES = {
# Insyde iFdPacker known 7-Zip SFX Password
INS_SFX_PWD = 'Y`t~i!L@i#t$U%h^s7A*l(f)E-d=y+S_n?i'
# Insyde iFlash known Image Names
INS_IFL_IMG = {
'BIOSCER' : ['Certificate', 'bin'],
'BIOSCR2' : ['Certificate 2nd', 'bin'],
'BIOSIMG' : ['BIOS-UEFI', 'bin'],
@ -188,7 +212,7 @@ IFL_IMG_NAMES = {
}
# Get common ctypes Structure Sizes
IFL_HDR_LEN = ctypes.sizeof(IflashHeader)
INS_IFL_LEN = ctypes.sizeof(IflashHeader)
if __name__ == '__main__':
# Set argparse Arguments