def find_magic_file(self, fname, system_only=False, user_only=False): ''' Finds the specified magic file name in the system / user magic file directories. @fname - The name of the magic file. @system_only - If True, only the system magic file directory will be searched. @user_only - If True, only the user magic file directory will be searched. If system_only and user_only are not set, the user directory is always searched first. Returns the path to the file on success; returns None on failure. ''' loc = None if not system_only: fpath = self._user_path(self.BINWALK_MAGIC_DIR, fname) if os.path.exists(fpath) and common.file_size(fpath) > 0: loc = fpath if loc is None and not user_only: fpath = self._system_path(self.BINWALK_MAGIC_DIR, fname) if os.path.exists(fpath) and common.file_size(fpath) > 0: loc = fpath return fpath
def extract(self, offset, description, file_name, size, name=None): ''' Extract an embedded file from the target file, if it matches an extract rule. Called automatically by Binwalk.scan(). @offset - Offset inside the target file to begin the extraction. @description - Description of the embedded file to extract, as returned by libmagic. @file_name - Path to the target file. @size - Number of bytes to extract. @name - Name to save the file as. Returns the name of the extracted file (blank string if nothing was extracted). ''' fname = '' cleanup_extracted_fname = True original_dir = os.getcwd() rules = self._match(description) file_path = os.path.realpath(file_name) # No extraction rules for this file if not rules: return (None, None) output_directory = self.build_output_directory(file_name) # Extract to end of file if no size was specified if not size: size = file_size(file_path) - offset if os.path.isfile(file_path): os.chdir(output_directory) # Loop through each extraction rule until one succeeds for i in range(0, len(rules)): rule = rules[i] # Copy out the data to disk, if we haven't already fname = self._dd(file_path, offset, size, rule['extension'], output_file_name=name) # If there was a command specified for this rule, try to execute it. # If execution fails, the next rule will be attempted. if rule['cmd']: # Many extraction utilities will extract the file to a new file, just without # the file extension (i.e., myfile.7z -> myfile). If the presumed resulting # file name already exists before executing the extract command, do not attempt # to clean it up even if its resulting file size is 0. if self.remove_after_execute: extracted_fname = os.path.splitext(fname)[0] if os.path.exists(extracted_fname): cleanup_extracted_fname = False # Execute the specified command against the extracted file if self.run_extractors: extract_ok = self.execute(rule['cmd'], fname) else: extract_ok = True # Only clean up files if remove_after_execute was specified if extract_ok == True and self.remove_after_execute: # Remove the original file that we extracted try: os.unlink(fname) except KeyboardInterrupt as e: raise e except Exception as e: pass # If the command worked, assume it removed the file extension from the extracted file # If the extracted file name file exists and is empty, remove it if cleanup_extracted_fname and os.path.exists(extracted_fname) and file_size(extracted_fname) == 0: try: os.unlink(extracted_fname) except KeyboardInterrupt as e: raise e except Exception as e: pass # If the command executed OK, don't try any more rules if extract_ok == True: break # Else, remove the extracted file if this isn't the last rule in the list. # If it is the last rule, leave the file on disk for the user to examine. elif i != (len(rules)-1): try: os.unlink(fname) except KeyboardInterrupt as e: raise e except Exception as e: pass # If there was no command to execute, just use the first rule else: break os.chdir(original_dir) return (output_directory, fname)
def extract(self, offset, description, file_name, size, name=None): ''' Extract an embedded file from the target file, if it matches an extract rule. Called automatically by Binwalk.scan(). @offset - Offset inside the target file to begin the extraction. @description - Description of the embedded file to extract, as returned by libmagic. @file_name - Path to the target file. @size - Number of bytes to extract. @name - Name to save the file as. Returns the name of the extracted file (blank string if nothing was extracted). ''' fname = '' recurse = False original_dir = os.getcwd() rules = self.match(description) file_path = os.path.realpath(file_name) # No extraction rules for this file if not rules: return (None, None, False) else: binwalk.core.common.debug("Found %d matching extraction rules" % len(rules)) # Generate the output directory name where extracted files will be stored output_directory = self.build_output_directory(file_name) # Extract to end of file if no size was specified if not size: size = file_size(file_path) - offset if os.path.isfile(file_path): os.chdir(output_directory) # Loop through each extraction rule until one succeeds for i in range(0, len(rules)): rule = rules[i] # Make sure we don't recurse into any extracted directories if instructed not to if rule['recurse'] in [True, False]: recurse = rule['recurse'] else: recurse = True # Copy out the data to disk, if we haven't already fname = self._dd(file_path, offset, size, rule['extension'], output_file_name=name) # If there was a command specified for this rule, try to execute it. # If execution fails, the next rule will be attempted. if rule['cmd']: # Note the hash of the original file; if --rm is specified and the # extraction utility modifies the original file rather than creating # a new one (AFAIK none currently do, but could happen in the future), # we don't want to remove this file. if self.remove_after_execute: fname_md5 = file_md5(fname) # Execute the specified command against the extracted file if self.run_extractors: extract_ok = self.execute(rule['cmd'], fname, rule['codes']) else: extract_ok = True # Only clean up files if remove_after_execute was specified if extract_ok == True and self.remove_after_execute: # Remove the original file that we extracted, # if it has not been modified by the extractor. try: if file_md5(fname) == fname_md5: os.unlink(fname) except KeyboardInterrupt as e: raise e except Exception as e: pass # If the command executed OK, don't try any more rules if extract_ok == True: break # Else, remove the extracted file if this isn't the last rule in the list. # If it is the last rule, leave the file on disk for the user to examine. elif i != (len(rules)-1): try: os.unlink(fname) except KeyboardInterrupt as e: raise e except Exception as e: pass # If there was no command to execute, just use the first rule else: break os.chdir(original_dir) return (output_directory, fname, recurse)
def extract(self, offset, description, file_name, size, name=None): ''' Extract an embedded file from the target file, if it matches an extract rule. Called automatically by Binwalk.scan(). @offset - Offset inside the target file to begin the extraction. @description - Description of the embedded file to extract, as returned by libmagic. @file_name - Path to the target file. @size - Number of bytes to extract. @name - Name to save the file as. Returns the name of the extracted file (blank string if nothing was extracted). ''' fname = '' cleanup_extracted_fname = True original_dir = os.getcwd() rules = self.match(description) file_path = os.path.realpath(file_name) # No extraction rules for this file if not rules: return (None, None) else: binwalk.core.common.debug("Found %d matching extraction rules" % len(rules)) output_directory = self.build_output_directory(file_name) # Update self.directory with the first output_directory path if self.directory is None: self.directory = output_directory # Extract to end of file if no size was specified if not size: size = file_size(file_path) - offset if os.path.isfile(file_path): os.chdir(output_directory) # Loop through each extraction rule until one succeeds for i in range(0, len(rules)): rule = rules[i] # Copy out the data to disk, if we haven't already fname = self._dd(file_path, offset, size, rule['extension'], output_file_name=name) # If there was a command specified for this rule, try to execute it. # If execution fails, the next rule will be attempted. if rule['cmd']: # Many extraction utilities will extract the file to a new file, just without # the file extension (i.e., myfile.7z -> myfile). If the presumed resulting # file name already exists before executing the extract command, do not attempt # to clean it up even if its resulting file size is 0. if self.remove_after_execute: extracted_fname = os.path.splitext(fname)[0] if os.path.exists(extracted_fname): cleanup_extracted_fname = False # Execute the specified command against the extracted file if self.run_extractors: extract_ok = self.execute(rule['cmd'], fname, rule['codes']) else: extract_ok = True # Only clean up files if remove_after_execute was specified if extract_ok == True and self.remove_after_execute: # Remove the original file that we extracted try: os.unlink(fname) except KeyboardInterrupt as e: raise e except Exception as e: pass # If the command worked, assume it removed the file extension from the extracted file # If the extracted file name file exists and is empty, remove it if cleanup_extracted_fname and os.path.exists(extracted_fname) and file_size(extracted_fname) == 0: try: os.unlink(extracted_fname) except KeyboardInterrupt as e: raise e except Exception as e: pass # If the command executed OK, don't try any more rules if extract_ok == True: break # Else, remove the extracted file if this isn't the last rule in the list. # If it is the last rule, leave the file on disk for the user to examine. elif i != (len(rules)-1): try: os.unlink(fname) except KeyboardInterrupt as e: raise e except Exception as e: pass # If there was no command to execute, just use the first rule else: break os.chdir(original_dir) return (output_directory, fname)