class SmaliInput

Constants

DEX_MAGIC
PK_ZIP_MAGIC

Attributes

dir[R]
out_apk[R]
out_dex[R]
temp_dex[R]
temp_dir[R]

Public Class Methods

compile(dir, out_dex = nil) click to toggle source
# File lib/dex-oracle/smali_input.rb, line 24
def self.compile(dir, out_dex = nil)
  raise 'Smali could not be found on the path.' if Utility.which('smali').nil?
  out_dex = Tempfile.new(%w(oracle .dex)) if out_dex.nil?
  logger.info("Compiling DEX #{out_dex.path} ...")
  exit_code = SmaliInput.exec("smali #{dir} -o #{out_dex.path}")
  # Remember kids, if you make a CLI, exit with non-zero status for failures
  raise 'Crap, smali compilation failed.' if $CHILD_STATUS.exitstatus != 0
  out_dex
end
exec(cmd) click to toggle source
# File lib/dex-oracle/smali_input.rb, line 43
def self.exec(cmd)
  `#{cmd}`
end
extract_dex(apk, out_dex) click to toggle source
# File lib/dex-oracle/smali_input.rb, line 39
def self.extract_dex(apk, out_dex)
  Utility.extract_file(apk, 'classes.dex', out_dex)
end
new(input) click to toggle source
# File lib/dex-oracle/smali_input.rb, line 13
def initialize(input)
  prepare(input)
end
update_apk(dir, out_apk) click to toggle source
# File lib/dex-oracle/smali_input.rb, line 34
def self.update_apk(dir, out_apk)
  out_dex = compile(dir)
  Utility.update_zip(out_apk, 'classes.dex', out_dex)
end

Public Instance Methods

finish() click to toggle source
# File lib/dex-oracle/smali_input.rb, line 17
def finish
  SmaliInput.update_apk(dir, @out_apk) if @out_apk
  SmaliInput.compile(dir, @out_dex) if @out_dex && !@out_apk
  FileUtils.rm_rf(@dir) if @temp_dir
  FileUtils.rm_rf(@out_dex) if @temp_dex
end

Private Instance Methods

baksmali(input) click to toggle source
# File lib/dex-oracle/smali_input.rb, line 49
def baksmali(input)
  logger.debug("Disassembling #{input} ...")
  raise 'Baksmali could not be found on the path.' if Utility.which('baksmali').nil?
  @dir = Dir.mktmpdir
  cmd = "baksmali #{input} -o #{@dir}"
  SmaliInput.exec(cmd)
end
prepare(input) click to toggle source
# File lib/dex-oracle/smali_input.rb, line 57
def prepare(input)
  if File.directory?(input)
    @temp_dir = false
    @temp_dex = true
    @dir = input
    @out_dex = SmaliInput.compile(dir)
    return
  end

  magic = File.open(input) { |f| f.read(3) }.bytes.to_a
  case magic
  when PK_ZIP_MAGIC
    @temp_dex = true
    @temp_dir = true
    @out_apk = "#{File.basename(input, '.*')}_oracle#{File.extname(input)}"
    @out_dex = Tempfile.new(%w(oracle .dex))
    FileUtils.cp(input, @out_apk)
    SmaliInput.extract_dex(@out_apk, @out_dex)
    baksmali(input)
  when DEX_MAGIC
    @temp_dex = false
    @temp_dir = true
    @out_dex = "#{File.basename(input, '.*')}_oracle#{File.extname(input)}"
    FileUtils.cp(input, @out_dex)
    @out_dex = File.new(@out_dex)
    baksmali(input)
  else
    raise "Unrecognized file type for: #{input}, magic=#{magic.inspect}"
  end
end