CalebFenton/dex-oracle

View on GitHub
bin/dex-oracle

Summary

Maintainability
Test Coverage
#!/usr/bin/env ruby
require 'pathname'
require 'optparse'

require_relative '../lib/oracle'
require_relative '../lib/dex-oracle/smali_input'
require_relative '../lib/dex-oracle/driver'
require_relative '../lib/dex-oracle/utility'
require_relative '../lib/dex-oracle/logging'

include Logging

Zip.warn_invalid_date = false

options = {
  device_id: ENV['ANDROID_SERIAL'] || '',
  timeout: 60 * 2,
  include_types: nil,
  exclude_types: nil,
  disable_plugins: [],
}

optparse = OptionParser.new do |opts|
  opts.banner = "Usage: #{File.basename(__FILE__)} [opts] <APK / DEX / Smali Directory>"
  opts.on('-h', '--help', 'Display this screen') do
    puts opts
    exit
  end

  opts.on('-d', '--device ANDROID_SERIAL',
          "Device ID for driver execution, default=\"#{options[:device_id]}\"") do |id|
    options[:device_id] = id
  end

  opts.on('-t', '--timeout N', Integer,
          "ADB command execution timeout in seconds, default=\"#{options[:timeout]}\"") do |id|
    options[:timeout] = id
  end

  opts.on('-i', '--include PATTERN', Regexp,
          'Only optimize methods and classes matching the pattern, e.g. Ldune;->melange\(\)V') do |regex|
    options[:include_types] = regex
  end

  opts.on('-e', '--exclude PATTERN', Regexp,
          'Exclude these types from optimization; including overrides') do |regex|
    options[:exclude_types] = regex
  end

  opts.on('--disable-plugins STRING[,STRING]*', String,
          'Disable plugins, e.g. stringdecryptor,unreflector') do |str|
    options[:disable_plugins] = str.downcase.delete(' ').split(',')
  end

  opts.on('--list-plugins', 'List available plugins') do
    require_relative '../lib/dex-oracle/plugin'
    puts 'Available plugins:'
    Plugin.plugin_classes.each { |c| puts "  #{c}" }
    exit
  end

  opts.on('-v', '--verbose', 'Be verbose') do
    logger.level = Logger::INFO
  end

  opts.on('-V', '--vverbose', 'Be very verbose') do
    logger.level = Logger::DEBUG
  end
end
optparse.parse!

if ARGV.size < 1
  puts optparse.help
  exit(-1)
end

unless Utility.which('adb')
  logger.error 'Unable to find adb command on path. Please make sure you have adb installed and setup.'
  exit(-1)
end

unless `adb devices`.strip != 'List of devices attached'
  logger.error 'It appears you have no devices running. Please start an emulator or plug in a test device.'
  exit(-1)
end

start = Time.now
input = Pathname.new(ARGV[0]).realpath.to_s

smali_input = SmaliInput.new(input)

driver = Driver.new(options[:device_id], options[:timeout])
driver.install(smali_input.out_dex)

oracle = Oracle.new(
  smali_input.dir, driver, options[:include_types], options[:exclude_types], options[:disable_plugins]
)
oracle.divine

smali_input.finish

puts "Time elapsed #{Time.now - start} seconds"