Class: Android::Apk
- Inherits:
-
Object
- Object
- Android::Apk
- Defined in:
- lib/android/apk.rb
Overview
apk object class
Constant Summary collapse
- MANIFEST =
AndroidManifest file name
'AndroidManifest.xml'
- DEX =
dex file name
'classes.dex'
- RESOURCE =
resource file name
'resources.arsc'
Instance Attribute Summary collapse
-
#bindata ⇒ String
readonly
Binary data of apk.
- #dex ⇒ Android::Dex? readonly
- #manifest ⇒ Android::Manifest? readonly
-
#path ⇒ String
readonly
Apk file path.
- #resource ⇒ Resource? readonly
Instance Method Summary collapse
-
#archs ⇒ Array<String>
(also: #architectures)
Return all architectures (all most for universal apk).
-
#certificates ⇒ Hash{String => OpenSSL::X509::Certificate }
v1 certificate info which is used for signing.
-
#digest(type = :sha1) ⇒ String
return hex digest string of apk file.
- #each_entry {|entry| ... } ⇒ Object
- #each_file {|name, data| ... } ⇒ Object
-
#entry(name) ⇒ Zip::Entry
find and return zip entry with name.
-
#file(name) ⇒ String
find and return binary data with name.
-
#find {|name, data| ... } ⇒ Array
find files which is matched with block condition.
-
#icon ⇒ Hash{ String => String }
extract application icon data from AndroidManifest and resource.
-
#icon_by_id(icon_id) ⇒ Hash{ String => String }
extract icon data from AndroidManifest and resource by a given icon id.
-
#initialize(filepath) ⇒ Apk
constructor
create new apk object.
-
#kotlin? ⇒ Boolean
detect if use kotlin language (may be third-party sdk or not).
-
#label(lang = nil) ⇒ String?
deprecated
Deprecated.
move to Manifest#label
-
#layouts ⇒ Hash{ String => Android::Layout }
get screen layout xml datas.
-
#signs ⇒ Hash{ String => OpenSSL::PKCS7 }
(also: #signatures)
apk’s v1 signature information.
-
#size ⇒ Integer
return apk file size.
-
#time ⇒ Time
returns date of AndroidManifest.xml as Apk date.
-
#universal? ⇒ Boolean
detect if contains multi-platforms (native machine code).
Constructor Details
#initialize(filepath) ⇒ Apk
create new apk object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/android/apk.rb', line 40 def initialize(filepath) Zip.warn_invalid_date = false @path = filepath raise NotFoundError, "'#{filepath}'" unless File.exist? @path @bindata = File.open(@path, 'rb') {|f| f.read } @bindata.force_encoding(Encoding::ASCII_8BIT) raise NotApkFileError, 'manifest file is not found.' if zip.find_entry(MANIFEST).nil? begin @resource = Android::Resource.new(self.file(RESOURCE)) rescue => e logger.error "failed to parse resource: #{e} with backtrace" logger.error e.backtrace end begin @manifest = Android::Manifest.new(self.file(MANIFEST), @resource) rescue => e logger.error "failed to parse manifest:#{e} with backtrace" logger.error e.backtrace end begin @dex = Android::Dex.new(self.file(DEX)) rescue => e logger.error "failed to parse dex:#{e} with backtrace" logger.error e.backtrace end end |
Instance Attribute Details
#bindata ⇒ String (readonly)
Returns binary data of apk.
24 25 26 |
# File 'lib/android/apk.rb', line 24 def bindata @bindata end |
#manifest ⇒ Android::Manifest? (readonly)
19 20 21 |
# File 'lib/android/apk.rb', line 19 def manifest @manifest end |
#path ⇒ String (readonly)
Returns apk file path.
16 17 18 |
# File 'lib/android/apk.rb', line 16 def path @path end |
#resource ⇒ Resource? (readonly)
27 28 29 |
# File 'lib/android/apk.rb', line 27 def resource @resource end |
Instance Method Details
#archs ⇒ Array<String> Also known as: architectures
Return all architectures (all most for universal apk)
227 228 229 230 231 232 |
# File 'lib/android/apk.rb', line 227 def archs @archs ||= zip.glob('lib/**/*').each_with_object([]) do |entry, obj| arch = entry.name.split('/')[1] obj << arch unless obj.include?(arch) end end |
#certificates ⇒ Hash{String => OpenSSL::X509::Certificate }
v1 certificate info which is used for signing
220 221 222 |
# File 'lib/android/apk.rb', line 220 def certificates @certificates ||= Hash[self.signs.map{|path, sign| [path, sign.certificates.first] }] end |
#digest(type = :sha1) ⇒ String
return hex digest string of apk file
82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/android/apk.rb', line 82 def digest(type = :sha1) case type when :sha1 Digest::SHA1.hexdigest(@bindata) when :sha256 Digest::SHA256.hexdigest(@bindata) when :md5 Digest::MD5.hexdigest(@bindata) else raise ArgumentError end end |
#each_entry {|entry| ... } ⇒ Object
121 122 123 124 125 126 |
# File 'lib/android/apk.rb', line 121 def each_entry zip.each do |entry| next unless entry.file? yield entry end end |
#each_file {|name, data| ... } ⇒ Object
104 105 106 107 108 109 |
# File 'lib/android/apk.rb', line 104 def each_file zip.each do |entry| next unless entry.file? yield entry.name, zip.read(entry) end end |
#entry(name) ⇒ Zip::Entry
find and return zip entry with name
132 133 134 135 136 |
# File 'lib/android/apk.rb', line 132 def entry(name) entry = zip.find_entry(name) raise NotFoundError, "'#{name}'" if entry.nil? return entry end |
#file(name) ⇒ String
find and return binary data with name
115 116 117 |
# File 'lib/android/apk.rb', line 115 def file(name) # get data by entry name(path) zip.read(entry(name)) end |
#find {|name, data| ... } ⇒ Array
find files which is matched with block condition
147 148 149 150 151 152 153 154 |
# File 'lib/android/apk.rb', line 147 def find(&block) found = [] self.each_file do |name, data| ret = block.call(name, data) found << name if ret end found end |
#icon ⇒ Hash{ String => String }
extract application icon data from AndroidManifest and resource.
160 161 162 163 |
# File 'lib/android/apk.rb', line 160 def icon icon_id = @manifest.doc.elements['/manifest/application'].attributes['icon'] icon_by_id(icon_id) end |
#icon_by_id(icon_id) ⇒ Hash{ String => String }
extract icon data from AndroidManifest and resource by a given icon id.
170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/android/apk.rb', line 170 def icon_by_id(icon_id) if /^@(\w+\/\w+)|(0x[0-9a-fA-F]{8})$/ =~ icon_id drawables = @resource.find(icon_id) Hash[drawables.map {|name| [name, file(name)] }] else begin { icon_id => file(icon_id) } # ugh!: not tested!! rescue NotFoundError {} end end end |
#kotlin? ⇒ Boolean
detect if use kotlin language (may be third-party sdk or not)
245 246 247 |
# File 'lib/android/apk.rb', line 245 def kotlin? @kotlin ||= kotlin_file? || kotlin_classes? end |
#label(lang = nil) ⇒ String?
move to Manifest#label
get application label from AndroidManifest and resources.
189 190 191 |
# File 'lib/android/apk.rb', line 189 def label(lang = nil) @manifest.label end |
#layouts ⇒ Hash{ String => Android::Layout }
get screen layout xml datas
196 197 198 |
# File 'lib/android/apk.rb', line 196 def layouts @layouts ||= Layout.collect_layouts(self) # lazy parse end |
#signs ⇒ Hash{ String => OpenSSL::PKCS7 } Also known as: signatures
apk’s v1 signature information
203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/android/apk.rb', line 203 def signs @signs ||= lambda { signs = {} self.each_file do |path, data| # find META-INF/xxx.{RSA|DSA|EC} next unless path =~ /^META-INF\// && data.unpack("CC") == [0x30, 0x82] signs[path] = OpenSSL::PKCS7.new(data) end signs }.call end |
#size ⇒ Integer
return apk file size
74 75 76 |
# File 'lib/android/apk.rb', line 74 def size @bindata.size end |
#time ⇒ Time
returns date of AndroidManifest.xml as Apk date
97 98 99 |
# File 'lib/android/apk.rb', line 97 def time entry(MANIFEST).time end |
#universal? ⇒ Boolean
detect if contains multi-platforms (native machine code)
238 239 240 |
# File 'lib/android/apk.rb', line 238 def universal? archs.size > 1 end |