def _dd(self, file_name, offset, size, extension, output_file_name=None): ''' Extracts a file embedded inside the target file. @file_name - Path to the target file. @offset - Offset inside the target file where the embedded file begins. @size - Number of bytes to extract. @extension - The file exension to assign to the extracted file on disk. @output_file_name - The requested name of the output file. Returns the extracted file name. ''' total_size = 0 # Default extracted file name is <hex offset>.<extension> default_bname = "%X" % offset if self.max_size and size > self.max_size: size = self.max_size if not output_file_name or output_file_name is None: bname = default_bname else: # Strip the output file name of invalid/dangerous characters (like file paths) bname = os.path.basename(output_file_name) fname = unique_file_name(bname, extension) try: # Open the target file and seek to the offset fdin = self.config.open_file(file_name, length=size, offset=offset) # Open the output file try: fdout = BlockFile(fname, 'w') except KeyboardInterrupt as e: raise e except Exception as e: # Fall back to the default name if the requested name fails fname = unique_file_name(default_bname, extension) fdout = BlockFile(fname, 'w') while total_size < size: (data, dlen) = fdin.read_block() if not data: break else: fdout.write(str2bytes(data[:dlen])) total_size += dlen # Cleanup fdout.close() fdin.close() except KeyboardInterrupt as e: raise e except Exception as e: raise Exception( "Extractor.dd failed to extract data from '%s' to '%s': %s" % (file_name, fname, str(e))) return fname
def _dd(self, file_name, offset, size, extension, output_file_name=None): ''' Extracts a file embedded inside the target file. @file_name - Path to the target file. @offset - Offset inside the target file where the embedded file begins. @size - Number of bytes to extract. @extension - The file exension to assign to the extracted file on disk. @output_file_name - The requested name of the output file. Returns the extracted file name. ''' total_size = 0 # Default extracted file name is <hex offset>.<extension> default_bname = "%X" % offset if self.max_size and size > self.max_size: size = self.max_size if not output_file_name or output_file_name is None: bname = default_bname else: # Strip the output file name of invalid/dangerous characters (like file paths) bname = os.path.basename(output_file_name) fname = unique_file_name(bname, extension) try: # Open the target file and seek to the offset fdin = self.config.open_file(file_name, length=size, offset=offset) # Open the output file try: fdout = BlockFile(fname, 'w') except KeyboardInterrupt as e: raise e except Exception as e: # Fall back to the default name if the requested name fails fname = unique_file_name(default_bname, extension) fdout = BlockFile(fname, 'w') while total_size < size: (data, dlen) = fdin.read_block() if not data: break else: fdout.write(str2bytes(data[:dlen])) total_size += dlen # Cleanup fdout.close() fdin.close() except KeyboardInterrupt as e: raise e except Exception as e: raise Exception("Extractor.dd failed to extract data from '%s' to '%s': %s" % (file_name, fname, str(e))) binwalk.core.common.debug("Carved data block 0x%X - 0x%X from '%s' to '%s'" % (offset, offset+size, file_name, fname)) return fname
def build_output_directory(self, path): ''' Set the output directory for extracted files. @path - The path to the file that data will be extracted from. Returns None. ''' # If we have not already created an output directory for this target file, create one now if not has_key(self.extraction_directories, path): output_directory = os.path.join(os.path.dirname(path), unique_file_name('_' + os.path.basename(path), extension='extracted')) if not os.path.exists(output_directory): os.mkdir(output_directory) self.extraction_directories[path] = output_directory # Else, just use the already created directory else: output_directory = self.extraction_directories[path] # Set the initial base extraction directory for later determining the level of recusion if not self.base_recursion_dir: self.base_recursion_dir = os.path.realpath(output_directory) + os.path.sep return output_directory
def build_output_directory(self, path): ''' Set the output directory for extracted files. @path - The path to the file that data will be extracted from. Returns None. ''' # If we have not already created an output directory for this target file, create one now if not has_key(self.extraction_directories, path): basedir = os.path.dirname(path) basename = os.path.basename(path) outdir = os.path.join(basedir, '_' + basename) output_directory = unique_file_name(outdir, extension='extracted') if not os.path.exists(output_directory): os.mkdir(output_directory) self.extraction_directories[path] = output_directory # Else, just use the already created directory else: output_directory = self.extraction_directories[path] # Set the initial base extraction directory for later determining the level of recusion # TODO: This is no longer needed since self.directory has the same information. Update code accordingly. if not self.base_recursion_dir: self.base_recursion_dir = os.path.realpath(output_directory) + os.path.sep return output_directory
def build_output_directory(self, path): ''' Set the output directory for extracted files. @path - The path to the file that data will be extracted from. Returns None. ''' # If we have not already created an output directory for this target file, create one now if not has_key(self.extraction_directories, path): output_directory = os.path.join( os.path.dirname(path), unique_file_name('_' + os.path.basename(path), extension='extracted')) if not os.path.exists(output_directory): os.mkdir(output_directory) self.extraction_directories[path] = output_directory # Else, just use the already created directory else: output_directory = self.extraction_directories[path] # Set the initial base extraction directory for later determining the level of recusion if not self.base_recursion_dir: self.base_recursion_dir = os.path.realpath( output_directory) + os.path.sep return output_directory
def extract_v1(self): for l in self.layout: if l.filename is not None: self.fd.seek(l.offset) out_filename = unique_file_name(l.filename.decode()) with open(out_filename, 'w+b') as out_fd: n, cz = 0, self.chunksize while n < l.size: n += cz if n > l.size: cz -= n - l.size out_fd.write(str2bytes(self.fd.read(cz))) if self.password_extractor is not None: if l.type == CSP_LAYOUT_PASSWORD: try: self.password = check_output( [self.password_extractor, l.filename]) except CalledProcessError as e: warning(str(e)) elif l.type == CSP_LAYOUT_APPL: if self.password is None: warning('Password wasn\'t extracted') continue app_out_filename = splitext(out_filename)[0] self.decrypt_v1(out_filename, l.size, app_out_filename) os.unlink(out_filename) self.untar(app_out_filename, splitext(app_out_filename)[0])
def extract(self): if not self.valid: return False for sec in self.sections: if sec.type in [ SECTION_TYPE_ARCHIVE_TBZ2, SECTION_TYPE_ENCRYPTED_ARCHIVE_TBZ2 ]: self.fd.seek(sec.data_offset) if sec.type == SECTION_TYPE_ENCRYPTED_ARCHIVE_TBZ2: decryptor = AES.new(self.key, AES.MODE_CBC, sec.vector) out_filename = unique_file_name('{}_off{:X}.{}.tbz2'.format( abspath(self.fd.path), sec.offset, sec.name)) with open(out_filename, 'w+b') as out_fd: n, cz = 0, self.chunksize while n < sec.data_size: n += cz if n > sec.data_size: cz -= n - sec.data_size chunk = str2bytes(self.fd.read(cz)) if sec.type == SECTION_TYPE_ENCRYPTED_ARCHIVE_TBZ2: chunk = decryptor.decrypt(chunk) out_fd.write(chunk) self.untar(out_filename, splitext(out_filename)[0]) return True
def build_output_directory(self, path): ''' Set the output directory for extracted files. @path - The path to the file that data will be extracted from. Returns None. ''' # If we have not already created an output directory for this target file, create one now if not has_key(self.extraction_directories, path): basedir = os.path.dirname(path) basename = os.path.basename(path) # Make sure we put the initial extraction directory in the CWD if self.directory is None: self.directory = os.getcwd() if basedir != self.directory: # During recursive extraction, extracted files will be in subdirectories # of the CWD. This allows us to figure out the subdirectory by simply # splitting the target file's base directory on our known CWD. # # However, the very *first* file being scanned is not necessarily in the # CWD, so this will raise an IndexError. This is easy to handle though, # since the very first file being scanned needs to have its contents # extracted to ${CWD}/_basename.extracted, so we just set the subdir # variable to a blank string when an IndexError is encountered. try: subdir = basedir.split(self.directory)[1][1:] except IndexError as e: subdir = "" else: subdir = "" if self.output_directory_override: output_directory = os.path.join(self.directory, subdir, self.output_directory_override) else: outdir = os.path.join(self.directory, subdir, '_' + basename) output_directory = unique_file_name(outdir, extension='extracted') if not os.path.exists(output_directory): os.mkdir(output_directory) self.extraction_directories[path] = output_directory self.output[path].directory = os.path.realpath( output_directory) + os.path.sep # Else, just use the already created directory else: output_directory = self.extraction_directories[path] return output_directory
def build_output_directory(self, path): ''' Set the output directory for extracted files. @path - The path to the file that data will be extracted from. Returns None. ''' # If we have not already created an output directory for this target file, create one now if not has_key(self.extraction_directories, path): basedir = os.path.dirname(path) basename = os.path.basename(path) # Make sure we put the initial extraction directory in the CWD if self.directory is None: self.directory = os.getcwd() if basedir != self.directory: # During recursive extraction, extracted files will be in subdirectories # of the CWD. This allows us to figure out the subdirectory by simply # splitting the target file's base directory on our known CWD. # # However, the very *first* file being scanned is not necessarily in the # CWD, so this will raise an IndexError. This is easy to handle though, # since the very first file being scanned needs to have its contents # extracted to ${CWD}/_basename.extracted, so we just set the subdir # variable to a blank string when an IndexError is encountered. try: subdir = basedir.split(self.directory)[1][1:] except IndexError as e: subdir = "" else: subdir = "" if self.output_directory_override: output_directory = os.path.join(self.directory, subdir, self.output_directory_override) else: outdir = os.path.join(self.directory, subdir, '_' + basename) output_directory = unique_file_name(outdir, extension='extracted') if not os.path.exists(output_directory): os.mkdir(output_directory) self.extraction_directories[path] = output_directory self.output[path].directory = os.path.realpath(output_directory) + os.path.sep # Else, just use the already created directory else: output_directory = self.extraction_directories[path] return output_directory
def build_output_directory(self, path): ''' Set the output directory for extracted files. @path - The path to the file that data will be extracted from. Returns None. ''' # If we have not already created an output directory for this target file, create one now if not has_key(self.extraction_directories, path): basedir = os.path.dirname(path) basename = os.path.basename(path) # Make sure we put the initial extracted file in the CWD if self.directory is None: if self.base_directory is None: basedir = os.getcwd() else: basedir = self.base_directory if not os.path.exists(basedir): os.mkdir(basedir) outdir = os.path.join(basedir, '_' + basename) output_directory = unique_file_name(outdir, extension='extracted') if not os.path.exists(output_directory): os.mkdir(output_directory) self.extraction_directories[path] = output_directory # Else, just use the already created directory else: output_directory = self.extraction_directories[path] # Set the initial base extraction directory for later determining the level of recusion if self.directory is None: self.directory = os.path.realpath(output_directory) + os.path.sep self.output[path].directory = self.directory return output_directory
def build_output_directory(self, path): ''' Set the output directory for extracted files. @path - The path to the file that data will be extracted from. Returns None. ''' # If we have not already created an output directory for this target file, create one now if not has_key(self.extraction_directories, path): basedir = os.path.dirname(path) basename = os.path.basename(path) # Make sure we put the initial extraction directory in the CWD if self.directory is None: self.directory = os.getcwd() if basedir != self.directory: subdir = basedir.split(self.directory)[1][1:] else: subdir = "" if self.output_directory_override: output_directory = os.path.join(self.directory, subdir, self.output_directory_override) else: outdir = os.path.join(self.directory, subdir, '_' + basename) output_directory = unique_file_name(outdir, extension='extracted') if not os.path.exists(output_directory): os.mkdir(output_directory) self.extraction_directories[path] = output_directory self.output[path].directory = os.path.realpath(output_directory) + os.path.sep # Else, just use the already created directory else: output_directory = self.extraction_directories[path] return output_directory
def _dd(self, file_name, offset, size, extension, output_file_name=None): ''' Extracts a file embedded inside the target file. @file_name - Path to the target file. @offset - Offset inside the target file where the embedded file begins. @size - Number of bytes to extract. @extension - The file exension to assign to the extracted file on disk. @output_file_name - The requested name of the output file. Returns the extracted file name. ''' total_size = 0 # Default extracted file name is <displayed hex offset>.<extension> default_bname = "%X" % (offset + self.config.base) if self.max_size and size > self.max_size: size = self.max_size if not output_file_name or output_file_name is None: bname = default_bname else: # Strip the output file name of invalid/dangerous characters (like file paths) bname = os.path.basename(output_file_name) fname = unique_file_name(bname, extension) try: # If byte swapping is enabled, we need to start reading at a swap-size # aligned offset, then index in to the read data appropriately. if self.config.swap_size: adjust = offset % self.config.swap_size else: adjust = 0 offset -= adjust # Open the target file and seek to the offset fdin = self.config.open_file(file_name) fdin.seek(offset) # Open the output file try: fdout = BlockFile(fname, 'w') except KeyboardInterrupt as e: raise e except Exception as e: # Fall back to the default name if the requested name fails fname = unique_file_name(default_bname, extension) fdout = BlockFile(fname, 'w') while total_size < size: (data, dlen) = fdin.read_block() if not data: break else: total_size += (dlen-adjust) if total_size > size: dlen -= (total_size - size) fdout.write(str2bytes(data[adjust:dlen])) adjust = 0 # Cleanup fdout.close() fdin.close() except KeyboardInterrupt as e: raise e except Exception as e: raise Exception("Extractor.dd failed to extract data from '%s' to '%s': %s" % (file_name, fname, str(e))) binwalk.core.common.debug("Carved data block 0x%X - 0x%X from '%s' to '%s'" % (offset, offset+size, file_name, fname)) return fname
def _dd(self, file_name, offset, size, extension, output_file_name=None): ''' Extracts a file embedded inside the target file. @file_name - Path to the target file. @offset - Offset inside the target file where the embedded file begins. @size - Number of bytes to extract. @extension - The file exension to assign to the extracted file on disk. @output_file_name - The requested name of the output file. Returns the extracted file name. ''' total_size = 0 # Default extracted file name is <displayed hex offset>.<extension> default_bname = "%X" % (offset + self.config.base) if self.max_size and size > self.max_size: size = self.max_size if not output_file_name or output_file_name is None: bname = default_bname else: # Strip the output file name of invalid/dangerous characters (like # file paths) bname = os.path.basename(output_file_name) fname = unique_file_name(bname, extension) try: # If byte swapping is enabled, we need to start reading at a swap-size # aligned offset, then index in to the read data appropriately. if self.config.swap_size: adjust = offset % self.config.swap_size else: adjust = 0 offset -= adjust # Open the target file and seek to the offset fdin = self.config.open_file(file_name) fdin.seek(offset) # Open the output file try: fdout = BlockFile(fname, 'w') except KeyboardInterrupt as e: raise e except Exception as e: # Fall back to the default name if the requested name fails fname = unique_file_name(default_bname, extension) fdout = BlockFile(fname, 'w') while total_size < size: (data, dlen) = fdin.read_block() if dlen < 1: break else: total_size += (dlen - adjust) if total_size > size: dlen -= (total_size - size) fdout.write(str2bytes(data[adjust:dlen])) adjust = 0 # Cleanup fdout.close() fdin.close() except KeyboardInterrupt as e: raise e except Exception as e: raise Exception("Extractor.dd failed to extract data from '%s' to '%s': %s" % (file_name, fname, str(e))) binwalk.core.common.debug("Carved data block 0x%X - 0x%X from '%s' to '%s'" % (offset, offset + size, file_name, fname)) return fname