Class: Oracle

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/oracle.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

included, logger, #logger, logger=

Constructor Details

#initialize(smali_dir, driver, include_types, exclude_types, disable_plugins) ⇒ Oracle

Returns a new instance of Oracle.



8
9
10
11
12
13
14
# File 'lib/oracle.rb', line 8

def initialize(smali_dir, driver, include_types, exclude_types, disable_plugins)
  @smali_files = Oracle.parse_smali(smali_dir)
  @methods = Oracle.filter_methods(@smali_files, include_types, exclude_types)
  Plugin.init_plugins(driver, @smali_files, @methods)
  @disable_plugins = disable_plugins
  logger.info("Disabled plugins: #{@disable_plugins * ','}") unless @disable_plugins.empty?
end

Class Method Details

.filter_methods(smali_files, include_types, exclude_types) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/oracle.rb', line 40

def self.filter_methods(smali_files, include_types, exclude_types)
  methods = []
  smali_files.each do |smali_file|
    smali_file.methods.each do |method|
      if include_types
        next if method.descriptor !~ include_types
      elsif exclude_types && !(method.descriptor !~ exclude_types)
        next
      end
      methods << method
    end
  end

  methods
end

.parse_smali(smali_dir) ⇒ Object



56
57
58
59
60
# File 'lib/oracle.rb', line 56

def self.parse_smali(smali_dir)
  smali_files = []
  Dir["#{smali_dir}/**/*.smali"].each { |f| smali_files << SmaliFile.new(f) }
  smali_files
end

Instance Method Details

#divineObject



16
17
18
19
20
21
22
23
24
# File 'lib/oracle.rb', line 16

def divine
  puts "Optimizing #{@methods.size} methods over #{@smali_files.size} Smali files."
  made_changes = process_plugins
  @smali_files.each(&:update) if made_changes
  optimizations = {}
  Plugin.plugins.each { |p| optimizations.merge!(p.optimizations) }
  opt_str = optimizations.collect { |k, v| "#{k}=#{v}" } * ', '
  puts "Optimizations: #{opt_str}"
end

#process_pluginsObject



26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/oracle.rb', line 26

def process_plugins
  made_changes = false
  loop do
    sweep_changes = false
    Plugin.plugins.each do |p|
      next if @disable_plugins.include?(p.class.name.downcase)
      sweep_changes |= p.process
    end
    made_changes |= sweep_changes
    break unless sweep_changes
  end
  made_changes
end