#!/bin/bash
#
# Usage: extract-evga-rom [[update.exe] evga-nvflash.rom]
# Extracts ROM file from EVGA-style update.exe and writes it to evga-nvflash.rom
#
# EVGA NVIDIA ROM extraction script for Linux (or bash, to be exact)
# -------------------------------------------
# EVGA provides a ROM update tool on their forums (http://evga.com/forums/tm.aspx?&m=1703680&mpage=1) for their GTX 670/680 series. Unfortunately, the update comes only in the form of a Windows tool. It is incompatible with nvflash itself.
# For those without a Windows installation on the system containing their graphics card, and for some with EFI / UEFI, options are very limited; mail support for the raw ROM file, or risk voiding warranty by finding it somewhere else.
# Luckily, the update.exe file contains the ROM file in unaltered, uncompressed fashion, making it quite easy to extract.
#
# The script expects a file named update.exe to be present in the current working directory and outputs to file evga-nvflash.rom. Arguments can be provided (in the same order) to use other filenames.
#
# NOTE: There's no check to see whether evga-nvflash.rom is already present, so for Linux's sake, make sure you don't happen to have an important file named evga-nvflash.rom because it will be overwritten.
# NOTE EVEN MORE: This script has only been confirmed to work with EVGA's update.exe for the original GTX 670 2GB, VBIOS version 80.04.5C.
# NOTE THE MOST / DISCLAIMER: If you haven't been warned yet, this seems like a good spot. You could brick your card. Be extremely cautious. Save the original ROM, know how to perform a blind flash, don't do things to void your warranty unless you're willing to replace yo
ur card by financial means. Only you are accountable for what you are about to attempt. Of course this script only grabs a portion of one file and puts it in another, so there's no need to cover myself here .. in fact, aren't I anonymous? Anyway; I wish you good luck!
#
binary=${1:-update.exe}
output=${2:-evga-nvflash.rom}
minsize=50000 # 50 kb
maxsize=250000 # 250 kb
searchstart="NVGI"
searchend="END CERT"
if [ ! -r "$binary" ]; then
echo "Can't read $binary"
exit
fi
start=$( grep -boa "$searchstart" "$binary" | tail -n1 | cut -d: -f1 )
end=$( grep -boa "$searchend" "$binary" | head -n2 | tail -n1 | cut -d: -f1 )
offset=455 # $searchend is not quite the end - grab more bytes
size=$(( $end - $start + $offset ))
echo "Found a chunk of $size bytes"
if [ $size -lt $minsize -o $size -gt $maxsize ]; then
echo "The chunk is smaller than $minsize bytes or larger than $maxsize bytes. Continueing, but you should check the output file $output by hand; it is probably all wrong :(" >&2
fi
dd if=$binary skip=$start bs=1 count=$size > "$output"
cat <<< "Wrote $size bytes to $output."