From ae2e8d60f24d41d116c6403ea81eb339543c2831 Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Sun, 24 Dec 2017 18:02:13 +0100
Subject: [PATCH 01/17] Improve status messages

---
 src/extraction.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/extraction.rb b/src/extraction.rb
index a727674..716158c 100644
--- a/src/extraction.rb
+++ b/src/extraction.rb
@@ -9,7 +9,7 @@ def self.attempt method_s, requires, reason, file
         puts "found #{requires} archive".colorize(:green)
         Extract.method(method_s).call(file)
       else
-        puts "not packed with #{requires}".colorize(:red)
+        puts "not extractable with #{requires}".colorize(:red)
       end
     end
   end

From 4e9838d788ad4442c02266f242ade78d5ab8ad9c Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Sun, 24 Dec 2017 18:05:54 +0100
Subject: [PATCH 02/17] Fix crash on subsequent runs with dirty work directory

---
 src/cli.rb | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/cli.rb b/src/cli.rb
index 4a71d6e..c896490 100644
--- a/src/cli.rb
+++ b/src/cli.rb
@@ -17,6 +17,10 @@ def extract file=nil, wd="#{Dir.pwd}/tmp-vbiosfinder"
         return
       end
       FileUtils.mkdir_p wd
+      Kernel.at_exit do
+        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")

From 0be085fc8fa01a88355b9f2298652fde8f680552 Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Sun, 24 Dec 2017 18:07:53 +0100
Subject: [PATCH 03/17] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 0f45ede..502380c 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ Some dependencies might not offer a package for your linux distribution **(like
 
 ## TODO
 - Add option to extract the bios of the running system **(can we?)**
-- Clean up temporary working dir after finishing up **(should we?) (default-on CLI switch?)**
+- ~~Clean up temporary working dir after finishing up~~ done
 - Test with more BIOS updates
 
 ## Licensing

From c49504435cdeefacaa459e8cf0114ceeea42e1d4 Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Sun, 24 Dec 2017 18:08:44 +0100
Subject: [PATCH 04/17] Remove debug message

---
 src/extract-innosetup.rb | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/extract-innosetup.rb b/src/extract-innosetup.rb
index 8288809..27dac69 100644
--- a/src/extract-innosetup.rb
+++ b/src/extract-innosetup.rb
@@ -3,7 +3,6 @@
 module VBiosFinder
   class Extract
     def self.innosetup file
-      puts file
       begin
         line = Cocaine::CommandLine.new("innoextract", ":file")
         puts line.run(file: file)

From 4d78b2683f84303a8aa433727beafaaacb08b9f9 Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Sun, 24 Dec 2017 18:14:12 +0100
Subject: [PATCH 05/17] Disable custom working dirs

---
 src/cli.rb | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/cli.rb b/src/cli.rb
index c896490..c8f179b 100644
--- a/src/cli.rb
+++ b/src/cli.rb
@@ -11,7 +11,8 @@ module VBiosFinder
   @@wd
   class CLI < Thor
     desc 'extract <bios update file>'.colorize(:blue), 'attempts to extract an embedded vbios from a bios update'
-    def extract file=nil, wd="#{Dir.pwd}/tmp-vbiosfinder"
+    def extract file=nil
+      wd = "#{Dir.pwd}/tmp-vbiosfinder"
       if file.nil?
         puts "no file specified".colorize(:red)
         return

From d5344e0f015ec90413c9fa604375c4c613c30780 Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Tue, 26 Dec 2017 11:28:25 +0100
Subject: [PATCH 06/17] Add: Also save extracted bios

---
 src/methods.rb | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/methods.rb b/src/methods.rb
index d2d4593..185d971 100644
--- a/src/methods.rb
+++ b/src/methods.rb
@@ -22,7 +22,10 @@ def self.run file
       # Try to find an UEFI bios image now
       if Utils::installed?("UEFIDump", "required for UEFI images") && Test::uefi(file)
         puts "found UEFI image".colorize(:green)
-        Extract::uefi(file)
+        outpath = "#{Dir.pwd}/../output"
+        FileUtils.mkdir_p outpath
+        FileUtils.cp file, "#{outpath}/bios_#{File.basename file}"
+        Extract::uefi file
         puts "extracted. filtering modules...".colorize(:blue)
         modules = Find.find("#{file}.dump").reject{|e| File.directory? e}.select{|e| e.end_with? ".bin"}
         puts "got #{modules.length} modules".colorize(:blue)
@@ -31,8 +34,6 @@ def self.run file
         modules = modules.select{|e| line.run(file: e).include? "Video"}
         if modules.length > 0
           puts "#{modules.length} possible candidates".colorize(:green)
-          outpath = "#{Dir.pwd}/../output"
-          FileUtils.mkdir_p outpath
           if Utils::installed?("rom-parser", "required for proper rom naming & higher accuracy")
             modules.each do |mod|
               rom_parser = Cocaine::CommandLine.new("rom-parser", ":file")

From c6db08e680398440b71d9f139158a5504f176466 Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Tue, 26 Dec 2017 14:05:39 +0100
Subject: [PATCH 07/17] Add .gitignore

---
 .gitignore | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 .gitignore

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5523c88
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.bundle
+output
+tmp-vbiosfinder
+vendor
+3rdparty/*

From 3edc877f294583fd0324332a152fee66aa705e1c Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Mon, 12 Feb 2018 15:01:35 +0100
Subject: [PATCH 08/17] Add Lenovo S5 2nd Gen (20JAA009HH) to list of
 compatible devices (#1)

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 502380c..1ff6acb 100644
--- a/README.md
+++ b/README.md
@@ -23,6 +23,7 @@ Some dependencies might not offer a package for your linux distribution **(like
 
 ## Compatibility
 - Lenovo y50-70 **(bios update)**
+- [Lenovo S5 2nd Gen (20JAA009HH) **(bios update)**](https://github.com/coderobe/VBiosFinder/issues/1)
 - **note: if your device isn't listed here, feel free to try this tool and report your results!**
 
 ## Troubleshooting

From ea89d34da221eace3b3aecbbb12709ac62c6e16c Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Sun, 8 Jul 2018 02:59:11 +0200
Subject: [PATCH 09/17] Add updater-polyglot extraction & zlib inflation;
 Switch from UEFIDump to UEFIExtract; Decrease verbosity;

---
 README.md               |   2 +-
 src/cli.rb              |   4 ++
 src/extract-polyglot.rb |  25 +++++++++
 src/extract-uefi.rb     |  10 ++--
 src/extract-zlib.rb     |  21 ++++++++
 src/extraction.rb       |   4 +-
 src/methods.rb          | 113 +++++++++++++++++++++++-----------------
 src/utils.rb            |   2 +-
 8 files changed, 124 insertions(+), 57 deletions(-)
 create mode 100644 src/extract-polyglot.rb
 create mode 100644 src/extract-zlib.rb

diff --git a/README.md b/README.md
index 1ff6acb..bc93cc0 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ Laptops with NVIDIA Optimus graphics often have the dGPU VBIOS integrated in the
 ## Dependencies
 - Ruby
 - bundler **(a ruby gem)**
-- [UEFIDump](https://github.com/LongSoft/UEFITool) **(note: UEFIDump can be found in the branch `new_engine`)**
+- [UEFIExtract](https://github.com/LongSoft/UEFITool) **(note: UEFIExtract can be found in the branch `new_engine`)**
 - [rom-parser](https://github.com/awilliam/rom-parser)
 - p7zip **(optional)**
 - [innoextract](https://github.com/dscharrer/innoextract) **(optional)**
diff --git a/src/cli.rb b/src/cli.rb
index c8f179b..aafa3d4 100644
--- a/src/cli.rb
+++ b/src/cli.rb
@@ -17,6 +17,10 @@ def extract file=nil
         puts "no file specified".colorize(:red)
         return
       end
+      if File.directory? wd
+        puts "dirty work directory! remove #{wd}".colorize(:red)
+        exit 1
+      end
       FileUtils.mkdir_p wd
       Kernel.at_exit do
         puts "Cleaning up garbage".colorize(:blue)
diff --git a/src/extract-polyglot.rb b/src/extract-polyglot.rb
new file mode 100644
index 0000000..b837eff
--- /dev/null
+++ b/src/extract-polyglot.rb
@@ -0,0 +1,25 @@
+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
+        input = data.read
+        matches = regex.match input
+        payload_size = matches.captures.first.unpack('V').first
+        payload_offset = matches.offset(2).last
+        data.seek payload_offset
+        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?)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/src/extract-uefi.rb b/src/extract-uefi.rb
index bf30b4d..d52ad21 100644
--- a/src/extract-uefi.rb
+++ b/src/extract-uefi.rb
@@ -4,11 +4,11 @@ module VBiosFinder
   class Extract
     def self.uefi file
       begin
-        line = Cocaine::CommandLine.new("UEFIDump", ":file")
-        puts line.run(file: file)
+        line = Cocaine::CommandLine.new("UEFIExtract", ":file all")
+        line.run(file: file)
       rescue Cocaine::ExitStatusError => e
         # TODO: fix Test::uefi before uncommenting this
-        # puts e.message
+        puts e.message
         return
       end
     end
@@ -16,8 +16,8 @@ def self.uefi file
   class Test
     def self.uefi file
       begin
-        line = Cocaine::CommandLine.new("UEFIDump", ":file")
-        puts line.run(file: file)
+        line = Cocaine::CommandLine.new("UEFIExtract", ":file report")
+        line.run(file: file)
         true
       rescue Cocaine::ExitStatusError => e
         false
diff --git a/src/extract-zlib.rb b/src/extract-zlib.rb
new file mode 100644
index 0000000..f226123
--- /dev/null
+++ b/src/extract-zlib.rb
@@ -0,0 +1,21 @@
+require "zlib"
+
+module VBiosFinder
+  class Extract
+    def self.zlib file
+      File.open file, "r:ASCII-8BIT" do |data|
+        File.open "#{file}-zlib", "w:ASCII-8BIT" do |outdata|
+          outdata.write Zlib::Inflate.inflate(data.read)
+        end
+      end
+    end
+  end
+  class Test
+    def self.zlib file
+      File.open file, "r:ASCII-8BIT" do |data|
+        regex = /^\x78\x9C/n
+        return !(regex.match(data.read).nil?)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/src/extraction.rb b/src/extraction.rb
index 716158c..5dcb5a8 100644
--- a/src/extraction.rb
+++ b/src/extraction.rb
@@ -5,11 +5,11 @@
 module VBiosFinder
   class Extraction
     def self.attempt method_s, requires, reason, file
-      if Utils::installed?(requires, reason) && Test.method(method_s).call(file)
+      if Test.method(method_s).call(file)
         puts "found #{requires} archive".colorize(:green)
         Extract.method(method_s).call(file)
       else
-        puts "not extractable with #{requires}".colorize(:red)
+        #puts "not extractable with #{requires}".colorize(:red)
       end
     end
   end
diff --git a/src/methods.rb b/src/methods.rb
index 185d971..27c2811 100644
--- a/src/methods.rb
+++ b/src/methods.rb
@@ -6,66 +6,83 @@
 require "./src/extract-upx"
 require "./src/extract-uefi"
 require "./src/extract-7z"
+require "./src/extract-polyglot"
+require "./src/extract-zlib"
 
 module VBiosFinder
   class Main
-    def self.run file
-      puts "trying to extract #{file}"
+    @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"]
 
+    def self.extract file
+      puts "trying to extract #{file}"
       # Attempt all known extraction methods
-      extractions = []
-      extractions << [:innosetup, "innoextract", "required for Inno Installers", file]
-      extractions << [:upx, "upx", "required for UPX executables", file]
-      extractions << [:p7zip, "7z", "required for 7z (self-extracting) archives", file]
-      extractions.each{|e| Extraction::attempt(*e)}
+      @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)
+      end
+
+      files = Utils::get_new_files
+      files << file
+
+      while files.size > 0
+        files.each do |e|
+          extract e
+        end
+        files = Utils::get_new_files
+      end
 
-      # Try to find an UEFI bios image now
-      if Utils::installed?("UEFIDump", "required for UEFI images") && Test::uefi(file)
-        puts "found UEFI image".colorize(:green)
-        outpath = "#{Dir.pwd}/../output"
-        FileUtils.mkdir_p outpath
-        FileUtils.cp file, "#{outpath}/bios_#{File.basename file}"
-        Extract::uefi file
-        puts "extracted. filtering modules...".colorize(:blue)
-        modules = Find.find("#{file}.dump").reject{|e| File.directory? e}.select{|e| e.end_with? ".bin"}
-        puts "got #{modules.length} modules".colorize(:blue)
-        puts "finding vbios".colorize(:blue)
-        line = Cocaine::CommandLine.new("file", "-b :file")
-        modules = modules.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")
-            modules.each do |mod|
-              rom_parser = Cocaine::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
-                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"
-                  FileUtils.cp(mod, "#{outpath}/#{new_filename}")
-                end
-              rescue Cocaine::ExitStatusError => e
-                puts "can't determine vbios type"
+      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)
+      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 "got #{uefibins.length} modules".colorize(:blue)
+      puts "finding vbios".colorize(:blue)
+      line = Cocaine::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")
+          modules.each do |mod|
+            rom_parser = Cocaine::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
+              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"
+                FileUtils.cp(mod, "#{outpath}/#{new_filename}")
               end
-            end
-          else
-            modules.each do |mod|
-              FileUtils.cp(mod, outpath)
+            rescue Cocaine::ExitStatusError => e
+              puts "can't determine vbios type"
             end
           end
-          puts "Job done. Extracted files can be found in #{outpath}".colorize(:green)
         else
-          puts "no candidates found :(".colorize(:red)
+          modules.each do |mod|
+            FileUtils.cp(mod, outpath)
+          end
         end
-        exit 0
+        puts "Job done. Extracted files can be found in #{outpath}".colorize(:green)
       else
-        puts "not an uefi image"
-      end
-
-      Utils::get_new_files.each do |e|
-        puts
-        run e
+        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)
+        end
       end
     end
   end
diff --git a/src/utils.rb b/src/utils.rb
index 052c86c..52e7146 100644
--- a/src/utils.rb
+++ b/src/utils.rb
@@ -13,7 +13,7 @@ def self.get_new_files
     end
     def self.installed? program, reason="optional"
       if find_executable(program).nil?
-        puts "Install '#{program}' on your system (#{reason})"
+        puts "Install '#{program}' on your system (#{reason})".colorize(:red)
         false
       else
         true

From 8b8111332bd7b862f93c8652b10b5157ace83743 Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Tue, 28 Aug 2018 02:24:24 +0200
Subject: [PATCH 10/17] Fix: catch zlib errors

---
 src/extract-zlib.rb | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/extract-zlib.rb b/src/extract-zlib.rb
index f226123..53ae9d1 100644
--- a/src/extract-zlib.rb
+++ b/src/extract-zlib.rb
@@ -3,10 +3,16 @@
 module VBiosFinder
   class Extract
     def self.zlib file
-      File.open file, "r:ASCII-8BIT" do |data|
-        File.open "#{file}-zlib", "w:ASCII-8BIT" do |outdata|
-          outdata.write Zlib::Inflate.inflate(data.read)
+      target = "#{file}-zlib"
+      begin
+        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)
+        FileUtils.rm target
       end
     end
   end

From 5b2758c358b84fbe36202bb27ff805d7f001ed07 Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Thu, 20 Dec 2018 22:34:27 +0100
Subject: [PATCH 11/17] Add TravelMate P645-SG to list of compatible devices
 (#9)

---
 README.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index bc93cc0..5f81b59 100644
--- a/README.md
+++ b/README.md
@@ -21,9 +21,10 @@ Some dependencies might not offer a package for your linux distribution **(like
 - A temporary working dir is created at `./tmp-vbiosfinder` which can be removed inbetween runs
 - Extracted VBIOS roms will be placed in `./output`
 
-## Compatibility
+## Compatibility (non-exhaustive)
 - Lenovo y50-70 **(bios update)**
 - [Lenovo S5 2nd Gen (20JAA009HH) **(bios update)**](https://github.com/coderobe/VBiosFinder/issues/1)
+- [TravelMate P645-SG](https://github.com/coderobe/VBiosFinder/issues/9)
 - **note: if your device isn't listed here, feel free to try this tool and report your results!**
 
 ## Troubleshooting

From 5aa46de7bf89af129e1b3101e5ad51fa5f91261c Mon Sep 17 00:00:00 2001
From: Robin Broda <robin@broda.me>
Date: Fri, 19 Jul 2019 17:03:45 +0200
Subject: [PATCH 12/17] Save VBIOS even when rom-parser cannot identify it

---
 src/methods.rb | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/methods.rb b/src/methods.rb
index 27c2811..4138b58 100644
--- a/src/methods.rb
+++ b/src/methods.rb
@@ -68,7 +68,8 @@ def self.run file
                 FileUtils.cp(mod, "#{outpath}/#{new_filename}")
               end
             rescue Cocaine::ExitStatusError => e
-              puts "can't determine vbios type"
+              puts "can't determine vbios type of #{File.basename(mod)}, saving as 'vbios_unknown_#{File.basename(mod)}'"
+              FileUtils.cp(mod, "#{outpath}/vbios_unknown_#{File.basename(mod)}")
             end
           end
         else

From 884c9815e8fbabd1551b0ff35ab92ad1b0f4deaa Mon Sep 17 00:00:00 2001
From: Robin B <robin@broda.me>
Date: Mon, 5 Aug 2019 14:13:55 +0200
Subject: [PATCH 13/17] Add the ThinkPad T430 to the list of supported devices
 (#18)

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 5f81b59..d31d23f 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,7 @@ Some dependencies might not offer a package for your linux distribution **(like
 - Lenovo y50-70 **(bios update)**
 - [Lenovo S5 2nd Gen (20JAA009HH) **(bios update)**](https://github.com/coderobe/VBiosFinder/issues/1)
 - [TravelMate P645-SG](https://github.com/coderobe/VBiosFinder/issues/9)
+- [ThinkPad T430](https://github.com/coderobe/VBiosFinder/issues/18)
 - **note: if your device isn't listed here, feel free to try this tool and report your results!**
 
 ## Troubleshooting

From 880eb022e1d7671a75e0c5344bbad3c5ab2f071b Mon Sep 17 00:00:00 2001
From: "Dominik M. Kwiatek" <mltnhm@users.noreply.github.com>
Date: Sat, 12 Oct 2019 22:56:39 +0100
Subject: [PATCH 14/17] Upgrade Cocaine to Terrapin (#19)

sad, liked the name
---
 Gemfile                  |  2 +-
 Gemfile.lock             |  8 ++++----
 src/cli.rb               |  2 +-
 src/extract-7z.rb        | 10 +++++-----
 src/extract-innosetup.rb | 10 +++++-----
 src/extract-uefi.rb      | 10 +++++-----
 src/extract-upx.rb       | 10 +++++-----
 src/methods.rb           |  8 ++++----
 src/utils.rb             |  2 +-
 9 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/Gemfile b/Gemfile
index 3cce557..439ac47 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,7 +4,7 @@ source "https://rubygems.org"
 
 git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
 
-gem "cocaine"
+gem "terrapin"
 
 
 # Added at 2017-12-24 10:16:46 +0100 by coderobe:
diff --git a/Gemfile.lock b/Gemfile.lock
index 526edbe..2d0cc2e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -2,8 +2,6 @@ GEM
   remote: https://rubygems.org/
   specs:
     climate_control (0.2.0)
-    cocaine (0.5.8)
-      climate_control (>= 0.0.3, < 1.0)
     coderay (1.1.2)
     colorize (0.8.1)
     method_source (0.9.0)
@@ -11,17 +9,19 @@ GEM
     pry (0.11.3)
       coderay (~> 1.1.0)
       method_source (~> 0.9.0)
+    terrapin (0.6.0)
+      climate_control (>= 0.0.3, < 1.0)
     thor (0.20.0)
 
 PLATFORMS
   ruby
 
 DEPENDENCIES
-  cocaine
   colorize (~> 0.8.1)
   posix-spawn (~> 0.3.13)
   pry (~> 0.11.3)
+  terrapin
   thor (~> 0.20.0)
 
 BUNDLED WITH
-   1.16.1
+   1.17.3
diff --git a/src/cli.rb b/src/cli.rb
index aafa3d4..4c66795 100644
--- a/src/cli.rb
+++ b/src/cli.rb
@@ -5,7 +5,7 @@
 require "./src/methods"
 require "./src/utils"
 
-#Cocaine::CommandLine.logger = Logger.new(STDOUT)
+#Terrapin::CommandLine.logger = Logger.new(STDOUT)
 
 module VBiosFinder
   @@wd
diff --git a/src/extract-7z.rb b/src/extract-7z.rb
index cc49e8c..f33a9c4 100644
--- a/src/extract-7z.rb
+++ b/src/extract-7z.rb
@@ -1,12 +1,12 @@
-require "cocaine"
+require "terrapin"
 
 module VBiosFinder
   class Extract
     def self.p7zip file
       begin
-        line = Cocaine::CommandLine.new("7z", "x :file")
+        line = Terrapin::CommandLine.new("7z", "x :file")
         line.run(file: file)
-      rescue Cocaine::ExitStatusError => e
+      rescue Terrapin::ExitStatusError => e
         puts e.message
         return
       end
@@ -15,10 +15,10 @@ def self.p7zip file
   class Test
     def self.p7zip file
       begin
-        line = Cocaine::CommandLine.new("7z", "l :file | grep 'Type = 7z'")
+        line = Terrapin::CommandLine.new("7z", "l :file | grep 'Type = 7z'")
         line.run(file: file)
         true
-      rescue Cocaine::ExitStatusError => e
+      rescue Terrapin::ExitStatusError => e
         false
       end
     end
diff --git a/src/extract-innosetup.rb b/src/extract-innosetup.rb
index 27dac69..0f8613b 100644
--- a/src/extract-innosetup.rb
+++ b/src/extract-innosetup.rb
@@ -1,12 +1,12 @@
-require "cocaine"
+require "terrapin"
 
 module VBiosFinder
   class Extract
     def self.innosetup file
       begin
-        line = Cocaine::CommandLine.new("innoextract", ":file")
+        line = Terrapin::CommandLine.new("innoextract", ":file")
         puts line.run(file: file)
-      rescue Cocaine::ExitStatusError => e
+      rescue Terrapin::ExitStatusError => e
         puts e.message
         return
       end
@@ -15,10 +15,10 @@ def self.innosetup file
   class Test
     def self.innosetup file
       begin
-        line = Cocaine::CommandLine.new("innoextract", "-t :file")
+        line = Terrapin::CommandLine.new("innoextract", "-t :file")
         line.run(file: file)
         true
-      rescue Cocaine::ExitStatusError => e
+      rescue Terrapin::ExitStatusError => e
         false
       end
     end
diff --git a/src/extract-uefi.rb b/src/extract-uefi.rb
index d52ad21..04e68cd 100644
--- a/src/extract-uefi.rb
+++ b/src/extract-uefi.rb
@@ -1,12 +1,12 @@
-require "cocaine"
+require "terrapin"
 
 module VBiosFinder
   class Extract
     def self.uefi file
       begin
-        line = Cocaine::CommandLine.new("UEFIExtract", ":file all")
+        line = Terrapin::CommandLine.new("UEFIExtract", ":file all")
         line.run(file: file)
-      rescue Cocaine::ExitStatusError => e
+      rescue Terrapin::ExitStatusError => e
         # TODO: fix Test::uefi before uncommenting this
         puts e.message
         return
@@ -16,10 +16,10 @@ def self.uefi file
   class Test
     def self.uefi file
       begin
-        line = Cocaine::CommandLine.new("UEFIExtract", ":file report")
+        line = Terrapin::CommandLine.new("UEFIExtract", ":file report")
         line.run(file: file)
         true
-      rescue Cocaine::ExitStatusError => e
+      rescue Terrapin::ExitStatusError => e
         false
       end
     end
diff --git a/src/extract-upx.rb b/src/extract-upx.rb
index 64d24d2..6e53f9c 100644
--- a/src/extract-upx.rb
+++ b/src/extract-upx.rb
@@ -1,12 +1,12 @@
-require "cocaine"
+require "terrapin"
 
 module VBiosFinder
   class Extract
     def self.upx file
       begin
-        line = Cocaine::CommandLine.new("upx", "-d :file -o :outfile")
+        line = Terrapin::CommandLine.new("upx", "-d :file -o :outfile")
         line.run(file: file, outfile: "upx-#{file}")
-      rescue Cocaine::ExitStatusError => e
+      rescue Terrapin::ExitStatusError => e
         puts e.message
         return
       end
@@ -15,10 +15,10 @@ def self.upx file
   class Test
     def self.upx file
       begin
-        line = Cocaine::CommandLine.new("upx", "-t :file")
+        line = Terrapin::CommandLine.new("upx", "-t :file")
         line.run(file: file)
         true
-      rescue Cocaine::ExitStatusError => e
+      rescue Terrapin::ExitStatusError => e
         false
       end
     end
diff --git a/src/methods.rb b/src/methods.rb
index 4138b58..b3245f7 100644
--- a/src/methods.rb
+++ b/src/methods.rb
@@ -1,4 +1,4 @@
-require "cocaine"
+require "terrapin"
 require "find"
 require "colorize"
 require "./src/extraction"
@@ -52,13 +52,13 @@ def self.run file
       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 = Cocaine::CommandLine.new("file", "-b :file")
+      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")
           modules.each do |mod|
-            rom_parser = Cocaine::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
@@ -67,7 +67,7 @@ def self.run file
                 new_filename = "vbios_#{romdata['vendor']}_#{romdata['device']}.rom"
                 FileUtils.cp(mod, "#{outpath}/#{new_filename}")
               end
-            rescue Cocaine::ExitStatusError => e
+            rescue Terrapin::ExitStatusError => e
               puts "can't determine vbios type of #{File.basename(mod)}, saving as 'vbios_unknown_#{File.basename(mod)}'"
               FileUtils.cp(mod, "#{outpath}/vbios_unknown_#{File.basename(mod)}")
             end
diff --git a/src/utils.rb b/src/utils.rb
index 52e7146..f361697 100644
--- a/src/utils.rb
+++ b/src/utils.rb
@@ -1,4 +1,4 @@
-require "cocaine"
+require "terrapin"
 require "mkmf"
 require "find"
 

From b48da3e4384fb76aca772db154762a3b037cc4d2 Mon Sep 17 00:00:00 2001
From: Pey-crypto <53893419+Pey-crypto@users.noreply.github.com>
Date: Sat, 17 Oct 2020 20:38:40 +0530
Subject: [PATCH 15/17] This fixes the Copy and file overwritting problems

Checks the MD5 values of the files present in the directory
---
 src/methods.rb | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/methods.rb b/src/methods.rb
index b3245f7..7951d42 100644
--- a/src/methods.rb
+++ b/src/methods.rb
@@ -8,7 +8,8 @@
 require "./src/extract-7z"
 require "./src/extract-polyglot"
 require "./src/extract-zlib"
-
+require 'digest/md5'
+hash = {}
 module VBiosFinder
   class Main
     @extractions = []
@@ -65,6 +66,7 @@ def self.run file
               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)                
                 FileUtils.cp(mod, "#{outpath}/#{new_filename}")
               end
             rescue Terrapin::ExitStatusError => e
@@ -88,3 +90,21 @@ def self.run file
     end
   end
 end
+
+
+
+def check_cpy(new_filename,romdata)
+  count = 0
+  Dir.glob('**/*',File::FNM_DOTMATCH).each do |f|
+    key = Digest::MD5.hexdigest(IO.read(f)).to_sym
+    if hash.has_key?(key) then hash[key].push(f) else hash[key] = [f] end
+  end
+
+  hash.each_value do |a|
+    next if a.length == 1
+    count+= 1
+    new_filename = "vbios_#{romdata['vendor']}_#{romdata['device']}_#{count}.rom"
+
+    return new_filename
+  end
+end

From 88aea3ae66ad676ef3f97af62c952424c47bd15a Mon Sep 17 00:00:00 2001
From: Tobias Kronthaler <kronthto@gmail.com>
Date: Sat, 26 Dec 2020 12:31:39 +0100
Subject: [PATCH 16/17] Fix some issues in check_cpy

---
 src/methods.rb | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/methods.rb b/src/methods.rb
index 7951d42..a53e6b4 100644
--- a/src/methods.rb
+++ b/src/methods.rb
@@ -9,7 +9,7 @@
 require "./src/extract-polyglot"
 require "./src/extract-zlib"
 require 'digest/md5'
-hash = {}
+hashm = Hash.new
 module VBiosFinder
   class Main
     @extractions = []
@@ -93,14 +93,17 @@ def self.run file
 
 
 
-def check_cpy(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
     key = Digest::MD5.hexdigest(IO.read(f)).to_sym
-    if hash.has_key?(key) then hash[key].push(f) else hash[key] = [f] end
+    if hashm.has_key?(key) then hashm[key].push(f) else hashm[key] = [f] end
   end
 
-  hash.each_value do |a|
+  hashm.each_value do |a|
     next if a.length == 1
     count+= 1
     new_filename = "vbios_#{romdata['vendor']}_#{romdata['device']}_#{count}.rom"

From c2d764975115de466fdb4963d7773b5bc8468a06 Mon Sep 17 00:00:00 2001
From: "Robin M. B" <robin@broda.me>
Date: Sun, 14 Feb 2021 22:52:08 +0100
Subject: [PATCH 17/17] Update compatibility list

https://github.com/coderobe/VBiosFinder/issues/13
https://github.com/coderobe/VBiosFinder/issues/15
https://github.com/coderobe/VBiosFinder/issues/21
https://github.com/coderobe/VBiosFinder/issues/24
https://github.com/coderobe/VBiosFinder/issues/34
---
 README.md | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index d31d23f..bd380d1 100644
--- a/README.md
+++ b/README.md
@@ -22,10 +22,16 @@ Some dependencies might not offer a package for your linux distribution **(like
 - Extracted VBIOS roms will be placed in `./output`
 
 ## Compatibility (non-exhaustive)
-- Lenovo y50-70 **(bios update)**
-- [Lenovo S5 2nd Gen (20JAA009HH) **(bios update)**](https://github.com/coderobe/VBiosFinder/issues/1)
-- [TravelMate P645-SG](https://github.com/coderobe/VBiosFinder/issues/9)
+- [ASUS N580GD](https://github.com/coderobe/VBiosFinder/issues/15)
+- Lenovo y50-70
+- [Lenovo S5 2nd Gen (20JAA009HH)](https://github.com/coderobe/VBiosFinder/issues/1)
+- [ThinkPad P52](https://github.com/coderobe/VBiosFinder/issues/24)
+- [ThinkPad P72](https://github.com/coderobe/VBiosFinder/issues/13)
 - [ThinkPad T430](https://github.com/coderobe/VBiosFinder/issues/18)
+- [ThinkPad T440p](https://github.com/coderobe/VBiosFinder/issues/21)
+- [ThinkPad T530](https://github.com/coderobe/VBiosFinder/issues/34)
+- [TravelMate P645-SG](https://github.com/coderobe/VBiosFinder/issues/9)
+
 - **note: if your device isn't listed here, feel free to try this tool and report your results!**
 
 ## Troubleshooting
