#!/usr/bin/env ruby # frozen_string_literal: true require 'pwn' require 'optparse' require 'json' opts = {} OptionParser.new do |options| options.banner = "USAGE: #{File.basename($PROGRAM_NAME)} [opts] " options.on('-dDEV', '--block-dev=DEV', '') do |d| opts[:block_dev] = d end options.on('-bBAUD', '--baud=BAUD', '') do |b| opts[:baud] = b end options.on('-DDATABITS', '--data-bits=DATABITS', '') do |d| opts[:data_bits] = d end options.on('-sSTOPBITS', '--stop-bits=STOPBITS', '') do |s| opts[:stop_bits] = s end options.on('-pPARITY', '--parity=PARITY', '') do |p| opts[:parity] = p end options.on('-fFLOWCTRL', '--flow-control=FLOWCTRL', '') do |f| opts[:flow_control] = f end end.parse! if opts.empty? puts `#{File.basename($PROGRAM_NAME)} --help` exit 1 end begin block_dev = opts[:block_dev] if File.exist?(opts[:block_dev]) baud = opts[:baud] data_bits = opts[:data_bits] stop_bits = opts[:stop_bits] parity = opts[:parity] flow_control = opts[:flow_control] msr206_obj = PWN::Plugins::MSR206.connect( block_dev: block_dev, baud: baud, data_bits: data_bits, stop_bits: stop_bits, parity: parity, flow_control: flow_control ) puts "- Welcome to #{File.basename($PROGRAM_NAME)} -" puts "Connected via: #{block_dev} @ #{msr206_obj[:serial_conn].modem_params}" puts "Flow Control: #{msr206_obj[:serial_conn].flow_control}" puts "Signals: #{msr206_obj[:serial_conn].signals}" exec_resp = PWN::Plugins::MSR206.exec( msr206_obj: msr206_obj, cmd: :simulate_power_cycle_warm_reset ) # Unsure if this switches the protocol from USI0 to USI1 # exec_resp = PWN::Plugins::MSR206.exec( # msr206_obj: msr206_obj, # cmd: :proto_usi1 # ) # puts exec_resp.inspect config_hash = PWN::Plugins::MSR206.get_config( msr206_obj: msr206_obj ) puts "Configuration: #{config_hash.inspect}" exec_resp = PWN::Plugins::MSR206.exec( msr206_obj: msr206_obj, cmd: :version_report ) puts "Firmware Version: #{exec_resp[:decoded]}" # Main Menu menu_msg = '' loop do unless menu_msg.include?('ERROR') exec_resp = PWN::Plugins::MSR206.exec( msr206_obj: msr206_obj, cmd: :green_flash ) end puts "\n>> MAIN MENU OPTIONS:" puts '[(R)ead Card]' puts '[(B)ackup Card]' puts '[(C)opy Card]' puts '[(L)oad Card from File]' puts '[(W)arm Reset]' puts '[(Q)uit]' puts menu_msg print 'MAIN MENU OPTION >>> ' menu_msg = '' option = gets.scrub.chomp.strip.upcase.to_sym case option when :R menu_msg = 'READ CARD' track_data = PWN::Plugins::MSR206.read_card( msr206_obj: msr206_obj ) when :B menu_msg = 'BACKUP CARD TO FILE' track_data = PWN::Plugins::MSR206.backup_card( msr206_obj: msr206_obj ) when :C menu_msg = 'COPY CARD' track_data = PWN::Plugins::MSR206.copy_card( msr206_obj: msr206_obj ) when :L menu_msg = 'LOAD FROM FILE' track_data = PWN::Plugins::MSR206.load_card_from_file( msr206_obj: msr206_obj ) when :W menu_msg = 'WARM RESET' exec_resp = PWN::Plugins::MSR206.exec( msr206_obj: msr206_obj, cmd: :simulate_power_cycle_warm_reset ) when :Q exit else menu_msg = '****** ERROR: Invalid Menu Option Selected ******' exec_resp = PWN::Plugins::MSR206.exec( msr206_obj: msr206_obj, cmd: :green_off ) exec_resp = PWN::Plugins::MSR206.exec( msr206_obj: msr206_obj, cmd: :yellow_flash ) end end rescue StandardError => e raise e rescue SystemExit, Interrupt puts "\nGoodbye." ensure # Lights Off exec_resp = PWN::Plugins::MSR206.exec( msr206_obj: msr206_obj, cmd: :green_off ) exec_resp = PWN::Plugins::MSR206.exec( msr206_obj: msr206_obj, cmd: :yellow_off ) exec_resp = PWN::Plugins::MSR206.exec( msr206_obj: msr206_obj, cmd: :red_off ) msr206_obj = PWN::Plugins::MSR206.disconnect(msr206_obj: msr206_obj) if msr206_obj end