class Headdesk::Apk

Representation of an APK file unpacked by apktool

:reek: TooManyInstanceVariables

Attributes

android_manifest[R]
resources[R]
sdk_info[R]
yaml[R]

Public Class Methods

new(path, manifest_contents = nil, yaml_contents = nil) click to toggle source

:reek: TooManyStatements

# File lib/headdesk/apk.rb, line 20
def initialize(path, manifest_contents = nil, yaml_contents = nil)
  @path = path

  android_manifest_xml = File.join(@path, 'AndroidManifest.xml').freeze
  apktool_yml = File.join(@path, 'apktool.yml').freeze

  throw CliError.new('Path did not contain AndroidManifest.xml') unless File.exist?(android_manifest_xml) || manifest_contents
  throw CliError.new('Path did not contain apktool.yml') unless File.exist?(apktool_yml) || yaml_contents

  @yaml = yaml_contents || YAML.load_file(apktool_yml)
  @sdk_info = @yaml['sdkInfo']
  @resources = Resources.new(@path)

  manifest = Nokogiri::XML(manifest_contents) if manifest_contents
  manifest ||= File.open(android_manifest_xml) do |file|
    Nokogiri::XML(file)
  end

  @android_manifest = manifest.xpath('manifest')
  throw CliError.new('Invalid Android manifest') if @android_manifest.empty?
  @android_manifest = @android_manifest.first
end

Public Instance Methods

analyze() click to toggle source
# File lib/headdesk/apk.rb, line 43
def analyze
  report = Headdesk::APKReport.new(self)

  Headdesk::Check.for_apk.each do |check_type|
    check = check_type.new(self)
    report << check.process
  end

  # TODO: Associated domains
  report
end
class?(decl) click to toggle source

:reek: NilCheck

# File lib/headdesk/apk.rb, line 89
def class?(decl)
  !find_class(decl).nil?
end
find_class(decl) click to toggle source
# File lib/headdesk/apk.rb, line 93
def find_class(decl)
  file_name = Dir["#{@path}/smali*/**/#{Class.path_for(decl)}.smali"].first
  return nil unless file_name && File.exist?(file_name)

  Class.new(file_name)
end
min_sdk(gt_eq) click to toggle source
# File lib/headdesk/apk.rb, line 84
def min_sdk(gt_eq)
  min_sdk_version >= gt_eq
end
min_sdk_version() click to toggle source
# File lib/headdesk/apk.rb, line 76
def min_sdk_version
  sdk_info['minSdkVersion'].to_i
end
target_sdk_version() click to toggle source
# File lib/headdesk/apk.rb, line 72
def target_sdk_version
  sdk_info['targetSdkVersion'].to_i
end
targets_sdk(gt_eq) click to toggle source
# File lib/headdesk/apk.rb, line 80
def targets_sdk(gt_eq)
  target_sdk_version >= gt_eq
end
unity_version() click to toggle source
# File lib/headdesk/apk.rb, line 55
def unity_version
  unity_assets = File.join(@path, 'assets', 'bin', 'Data').freeze
  return nil unless Dir.exist?(unity_assets)

  asset_file = Dir[File.join(unity_assets, '/*')].first
  return nil unless asset_file

  version_bytes = []
  File.open(asset_file, 'rb') do |file|
    file.read(16) # Throw the first 16 bytes away
    file.read(16).each_byte do |byte|
      version_bytes << byte if byte > 0
    end
    return version_bytes.pack('c*')
  end
end