bin/dex-oracle
#!/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"