From 41bb22f400a5e8ae5db106aa99f950e2abdd11d8 Mon Sep 17 00:00:00 2001 From: Vladimir Khodygo Date: Sat, 29 Oct 2022 14:26:21 +0100 Subject: [PATCH] MAINT, FIX: apply rubocop to code, close #40, #50 * auto-fix formatting where acceptable * adjust regexps * fix issues with uppercase names * correct upx path to output file --- _init.rb | 2 +- src/cli.rb | 32 +++++++------ src/extract-7z.rb | 33 ++++++------- src/extract-innosetup.rb | 33 ++++++------- src/extract-polyglot.rb | 21 ++++---- src/extract-uefi.rb | 35 +++++++------- src/extract-upx.rb | 33 ++++++------- src/extract-zlib.rb | 19 ++++---- src/extraction.rb | 10 ++-- src/methods.rb | 100 +++++++++++++++++++++------------------ src/utils.rb | 13 ++--- 11 files changed, 165 insertions(+), 166 deletions(-) diff --git a/_init.rb b/_init.rb index 0a17e4f..783cecf 100644 --- a/_init.rb +++ b/_init.rb @@ -1,4 +1,4 @@ -require "./src/cli" +require './src/cli' $0=ARGV.first $PROGRAM_NAME=$0 diff --git a/src/cli.rb b/src/cli.rb index 4c66795..6ad87c9 100644 --- a/src/cli.rb +++ b/src/cli.rb @@ -1,20 +1,21 @@ -require "thor" -require "fileutils" -require "logger" -require "colorize" -require "./src/methods" -require "./src/utils" - -#Terrapin::CommandLine.logger = Logger.new(STDOUT) +require 'thor' +require 'fileutils' +require 'logger' +require 'colorize' +require './src/methods' +require './src/utils' +# Terrapin::CommandLine.logger = Logger.new(STDOUT) module VBiosFinder @@wd + class CLI < Thor desc 'extract '.colorize(:blue), 'attempts to extract an embedded vbios from a bios update' - def extract file=nil + + def extract(file = nil) wd = "#{Dir.pwd}/tmp-vbiosfinder" if file.nil? - puts "no file specified".colorize(:red) + puts 'no file specified'.colorize(:red) return end if File.directory? wd @@ -23,17 +24,18 @@ def extract file=nil end FileUtils.mkdir_p wd Kernel.at_exit do - puts "Cleaning up garbage".colorize(:blue) + puts 'Cleaning up garbage'.colorize(:blue) FileUtils.remove_entry_secure wd end @@wd = wd Dir.chdir wd - puts "output will be stored in '#{wd}'".colorize(":blue") - Utils::installed?("ruby") # "bugfix" - Utils::get_new_files # "bugfix" #2 + puts "output will be stored in '#{wd}'".colorize(':blue') + Utils.installed?('ruby') # "bugfix" + Utils.get_new_files # "bugfix" #2 FileUtils.cp(file, wd) + puts 'copying BIOS file to the work directory'.colorize(':blue') puts - Main::run Utils::get_new_files.first + Main.run Utils.get_new_files.first end end end diff --git a/src/extract-7z.rb b/src/extract-7z.rb index f33a9c4..51f6fc3 100644 --- a/src/extract-7z.rb +++ b/src/extract-7z.rb @@ -1,26 +1,23 @@ -require "terrapin" +require 'terrapin' module VBiosFinder class Extract - def self.p7zip file - begin - line = Terrapin::CommandLine.new("7z", "x :file") - line.run(file: file) - rescue Terrapin::ExitStatusError => e - puts e.message - return - end + def self.p7zip(file) + line = Terrapin::CommandLine.new('7z', 'x :file') + line.run(file: file) + rescue Terrapin::ExitStatusError => e + puts e.message + nil end end + class Test - def self.p7zip file - begin - line = Terrapin::CommandLine.new("7z", "l :file | grep 'Type = 7z'") - line.run(file: file) - true - rescue Terrapin::ExitStatusError => e - false - end + def self.p7zip(file) + line = Terrapin::CommandLine.new('7z', "l :file | grep 'Type = 7z'") + line.run(file: file) + true + rescue Terrapin::ExitStatusError => e + false end end -end \ No newline at end of file +end diff --git a/src/extract-innosetup.rb b/src/extract-innosetup.rb index 0f8613b..128acf5 100644 --- a/src/extract-innosetup.rb +++ b/src/extract-innosetup.rb @@ -1,26 +1,23 @@ -require "terrapin" +require 'terrapin' module VBiosFinder class Extract - def self.innosetup file - begin - line = Terrapin::CommandLine.new("innoextract", ":file") - puts line.run(file: file) - rescue Terrapin::ExitStatusError => e - puts e.message - return - end + def self.innosetup(file) + line = Terrapin::CommandLine.new('innoextract', ':file') + puts line.run(file: file) + rescue Terrapin::ExitStatusError => e + puts e.message + nil end end + class Test - def self.innosetup file - begin - line = Terrapin::CommandLine.new("innoextract", "-t :file") - line.run(file: file) - true - rescue Terrapin::ExitStatusError => e - false - end + def self.innosetup(file) + line = Terrapin::CommandLine.new('innoextract', '-t :file') + line.run(file: file) + true + rescue Terrapin::ExitStatusError => e + false end end -end \ No newline at end of file +end diff --git a/src/extract-polyglot.rb b/src/extract-polyglot.rb index b837eff..5f27e7c 100644 --- a/src/extract-polyglot.rb +++ b/src/extract-polyglot.rb @@ -1,25 +1,26 @@ module VBiosFinder class Extract - def self.polyglot file - File.open file, "r:ASCII-8BIT" do |data| - regex = /(.{4})\xAA\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51(.{1})/n + def self.polyglot(file) + File.open file, 'r:ASCII-8BIT' do |data| + regex = /(.{4})\xAA\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51(.)/n input = data.read matches = regex.match input - payload_size = matches.captures.first.unpack('V').first + payload_size = matches.captures.first.unpack1('V') payload_offset = matches.offset(2).last data.seek payload_offset - File.open "#{file}-polyglot", "w:ASCII-8BIT" do |outdata| + File.open "#{file}-polyglot", 'w:ASCII-8BIT' do |outdata| outdata.write data.read end end end end + class Test - def self.polyglot file - File.open file, "r:ASCII-8BIT" do |data| - regex = /(.{4})\xAA\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.{1}/n - return !(regex.match(data.read).nil?) + def self.polyglot(file) + File.open file, 'r:ASCII-8BIT' do |data| + regex = /(.{4})\xAA\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51./n + return !regex.match(data.read).nil? end end end -end \ No newline at end of file +end diff --git a/src/extract-uefi.rb b/src/extract-uefi.rb index 04e68cd..6fff14c 100644 --- a/src/extract-uefi.rb +++ b/src/extract-uefi.rb @@ -1,27 +1,24 @@ -require "terrapin" +require 'terrapin' module VBiosFinder class Extract - def self.uefi file - begin - line = Terrapin::CommandLine.new("UEFIExtract", ":file all") - line.run(file: file) - rescue Terrapin::ExitStatusError => e - # TODO: fix Test::uefi before uncommenting this - puts e.message - return - end + def self.uefi(file) + line = Terrapin::CommandLine.new('uefiextract', ':file all') + line.run(file: file) + rescue Terrapin::ExitStatusError => e + # TODO: fix Test::uefi before uncommenting this + puts e.message + nil end end + class Test - def self.uefi file - begin - line = Terrapin::CommandLine.new("UEFIExtract", ":file report") - line.run(file: file) - true - rescue Terrapin::ExitStatusError => e - false - end + def self.uefi(file) + line = Terrapin::CommandLine.new('uefiextract', ':file report') + line.run(file: file) + true + rescue Terrapin::ExitStatusError => e + false end end -end \ No newline at end of file +end diff --git a/src/extract-upx.rb b/src/extract-upx.rb index 6e53f9c..58d5269 100644 --- a/src/extract-upx.rb +++ b/src/extract-upx.rb @@ -1,26 +1,23 @@ -require "terrapin" +require 'terrapin' module VBiosFinder class Extract - def self.upx file - begin - line = Terrapin::CommandLine.new("upx", "-d :file -o :outfile") - line.run(file: file, outfile: "upx-#{file}") - rescue Terrapin::ExitStatusError => e - puts e.message - return - end + def self.upx(file) + line = Terrapin::CommandLine.new('upx', '-d :file -o :outfile') + line.run(file: file, outfile: "upx-#{File.basename(file)}") + rescue Terrapin::ExitStatusError => e + puts e.message + nil end end + class Test - def self.upx file - begin - line = Terrapin::CommandLine.new("upx", "-t :file") - line.run(file: file) - true - rescue Terrapin::ExitStatusError => e - false - end + def self.upx(file) + line = Terrapin::CommandLine.new('upx', '-t :file') + line.run(file: file) + true + rescue Terrapin::ExitStatusError => e + false end end -end \ No newline at end of file +end diff --git a/src/extract-zlib.rb b/src/extract-zlib.rb index 53ae9d1..19be56b 100644 --- a/src/extract-zlib.rb +++ b/src/extract-zlib.rb @@ -1,27 +1,28 @@ -require "zlib" +require 'zlib' module VBiosFinder class Extract - def self.zlib file + def self.zlib(file) target = "#{file}-zlib" begin - File.open file, "r:ASCII-8BIT" do |data| - File.open target, "w:ASCII-8BIT" do |outdata| + File.open file, 'r:ASCII-8BIT' do |data| + File.open target, 'w:ASCII-8BIT' do |outdata| outdata.write Zlib::Inflate.inflate(data.read) end end rescue Zlib::DataError - puts "wrong guess :(".colorize(:red) + puts 'wrong guess :('.colorize(:red) FileUtils.rm target end end end + class Test - def self.zlib file - File.open file, "r:ASCII-8BIT" do |data| + def self.zlib(file) + File.open file, 'r:ASCII-8BIT' do |data| regex = /^\x78\x9C/n - return !(regex.match(data.read).nil?) + return !regex.match(data.read).nil? end end end -end \ No newline at end of file +end diff --git a/src/extraction.rb b/src/extraction.rb index 5dcb5a8..27cf71c 100644 --- a/src/extraction.rb +++ b/src/extraction.rb @@ -1,10 +1,10 @@ -require "colorize" -require "./src/utils" -require "./src/methods" +require 'colorize' +require './src/utils' +require './src/methods' module VBiosFinder class Extraction - def self.attempt method_s, requires, reason, file + def self.attempt(method_s, requires, reason, file) if Test.method(method_s).call(file) puts "found #{requires} archive".colorize(:green) Extract.method(method_s).call(file) @@ -13,4 +13,4 @@ def self.attempt method_s, requires, reason, file end end end -end \ No newline at end of file +end diff --git a/src/methods.rb b/src/methods.rb index a53e6b4..e6808c1 100644 --- a/src/methods.rb +++ b/src/methods.rb @@ -1,72 +1,76 @@ -require "terrapin" -require "find" -require "colorize" -require "./src/extraction" -require "./src/extract-innosetup" -require "./src/extract-upx" -require "./src/extract-uefi" -require "./src/extract-7z" -require "./src/extract-polyglot" -require "./src/extract-zlib" +require 'terrapin' +require 'find' +require 'colorize' +require './src/extraction' +require './src/extract-innosetup' +require './src/extract-upx' +require './src/extract-uefi' +require './src/extract-7z' +require './src/extract-polyglot' +require './src/extract-zlib' require 'digest/md5' -hashm = Hash.new +hashm = {} module VBiosFinder class Main @extractions = [] - @extractions << [:polyglot, "polyglot", "builtin module for polyglot files"] - @extractions << [:zlib, "zlib", "builtin module for zlib data"] - @extractions << [:innosetup, "innoextract", "required for Inno Installers"] - @extractions << [:upx, "upx", "required for UPX executables"] - @extractions << [:p7zip, "7z", "required for 7z (self-extracting) archives"] + @extractions << [:polyglot, 'polyglot', 'builtin module for polyglot files'] + @extractions << [:zlib, 'zlib', 'builtin module for zlib data'] + @extractions << [:innosetup, 'innoextract', 'required for Inno Installers'] + @extractions << [:upx, 'upx', 'required for UPX executables'] + @extractions << [:p7zip, '7z', 'required for 7z (self-extracting) archives'] - def self.extract file + def self.extract(file) puts "trying to extract #{file}" # Attempt all known extraction methods - @extractions.each{|e| Extraction::attempt(*e, file)} + @extractions.each { |e| Extraction.attempt(*e, file) } end - def self.run file - @extractions.select! do |sym, requires, reason, arg| - reason.start_with?("builtin") || Utils::installed?(requires, reason) + def self.run(file) + @extractions.select! do |_sym, requires, reason, _arg| + reason.start_with?('builtin') || Utils.installed?(requires, reason) end - files = Utils::get_new_files + files = Utils.get_new_files files << file while files.size > 0 files.each do |e| extract e end - files = Utils::get_new_files + files = Utils.get_new_files end - puts "extracting uefi data".colorize(:blue) - Find.find(".").reject{|e| File.directory? e}.each do |e| + puts 'extracting uefi data'.colorize(:blue) + Find.find('.').reject { |e| File.directory? e }.each do |e| puts "trying to extract #{e}" - Extraction::attempt(:uefi, "UEFIExtract", "required for UEFI images", e) + Extraction.attempt(:uefi, 'uefiextract', 'required for UEFI images', e) end outpath = "#{Dir.pwd}/../output" FileUtils.mkdir_p outpath FileUtils.cp file, "#{outpath}/bios_#{File.basename file}" - puts "filtering for modules...".colorize(:blue) - uefibins = Find.find(".").reject{|e| File.directory? e}.select{|e| e.end_with? ".bin"} + puts 'filtering for modules...'.colorize(:blue) + uefibins = Find.find('.').reject { |e| File.directory? e }.select { |e| e.end_with? '.bin' } puts "got #{uefibins.length} modules".colorize(:blue) - puts "finding vbios".colorize(:blue) - line = Terrapin::CommandLine.new("file", "-b :file") - modules = uefibins.select{|e| line.run(file: e).include? "Video"} + puts 'finding vbios'.colorize(:blue) + line = Terrapin::CommandLine.new('file', '-b :file') + modules = uefibins.select { |e| line.run(file: e).include? 'Video' } if modules.length > 0 puts "#{modules.length} possible candidates".colorize(:green) - if Utils::installed?("rom-parser", "required for proper rom naming & higher accuracy") + if Utils.installed?('rom-parser', 'required for proper rom naming & higher accuracy') modules.each do |mod| - rom_parser = Terrapin::CommandLine.new("rom-parser", ":file") + rom_parser = Terrapin::CommandLine.new('rom-parser', ':file') begin romdata = rom_parser.run(file: mod) - romdata = romdata.split("\n")[1].split(", ").map{|e| e.split(": ")}.to_h rescue nil + romdata = begin + romdata.split("\n")[1].split(', ').map { |e| e.split(': ') }.to_h + rescue StandardError + nil + end unless romdata.nil? || romdata['vendor'].nil? || romdata['device'].nil? puts "Found VBIOS for device #{romdata['vendor']}:#{romdata['device']}!".colorize(:green) new_filename = "vbios_#{romdata['vendor']}_#{romdata['device']}.rom" - new_filename =check_cpy(new_filename,romdata) + new_filename = check_cpy(new_filename, romdata) FileUtils.cp(mod, "#{outpath}/#{new_filename}") end rescue Terrapin::ExitStatusError => e @@ -81,31 +85,33 @@ def self.run file end puts "Job done. Extracted files can be found in #{outpath}".colorize(:green) else - puts "no candidates found :(".colorize(:red) + puts 'no candidates found :('.colorize(:red) if uefibins.length > 0 - puts "input contains uefi data but no vbios could be found".colorize(:yellow) - puts "the vbios might not be baked into the input!".colorize(:yellow) + puts 'input contains uefi data but no vbios could be found'.colorize(:yellow) + puts 'the vbios might not be baked into the input!'.colorize(:yellow) end end end end end - - -define_method (:check_cpy) do |new_filename,romdata| +define_method(:check_cpy) do |new_filename, romdata| count = 0 - Dir.glob('**/*',File::FNM_DOTMATCH).each do |f| - if File.directory?(f) - next - end + Dir.glob('**/*', File::FNM_DOTMATCH).each do |f| + next if File.directory?(f) + key = Digest::MD5.hexdigest(IO.read(f)).to_sym - if hashm.has_key?(key) then hashm[key].push(f) else hashm[key] = [f] end + if hashm.has_key?(key) + hashm[key].push(f) + else + hashm[key] = [f] + end end hashm.each_value do |a| next if a.length == 1 - count+= 1 + + count += 1 new_filename = "vbios_#{romdata['vendor']}_#{romdata['device']}_#{count}.rom" return new_filename diff --git a/src/utils.rb b/src/utils.rb index f361697..88ce5e3 100644 --- a/src/utils.rb +++ b/src/utils.rb @@ -1,17 +1,18 @@ -require "terrapin" -require "mkmf" -require "find" +require 'terrapin' +require 'mkmf' +require 'find' module VBiosFinder class Utils @@current_files = [] def self.get_new_files - current_files = Find.find(".").reject{|e| File.directory? e} + current_files = Find.find('.').reject { |e| File.directory? e } result = current_files - @@current_files @@current_files = current_files - return result + result end - def self.installed? program, reason="optional" + + def self.installed?(program, reason = 'optional') if find_executable(program).nil? puts "Install '#{program}' on your system (#{reason})".colorize(:red) false