apk_analyzer 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5ddc1fe39420ebac13a7e80d242af9710c5845c2
4
+ data.tar.gz: cb880c94b6862b0447639a25b6567555f9f12e13
5
+ SHA512:
6
+ metadata.gz: 692da36487298267e24587880f3a0c86984b5edaa9afb51d6188d13f77964f85ef536f1531006847e16e96ada2770b503a7d7755295edaade4d8911503f85fbe
7
+ data.tar.gz: 0f7f5419ae86cf83e75cf36b269dc4bbd09050e79d42af96f8df04b03508d4974bac2487adb47eb259c9420417d59831c57ba43829312fd134d06acce1a65236
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
11
+
12
+ \.idea/
13
+
14
+ *.log
15
+
16
+ test_binaries\.sh
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.2.5
5
+ before_install: gem install bundler -v 1.14.4
6
+ script: rake build
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in apk_analyzer.gemspec
4
+ gemspec
5
+
6
+ # Added when debugging apktools RubyZip issue locally
7
+ # Waiting for PR on apktools to be accepted (2017/04/03)
8
+ #gem 'apktools', '~>0.7.2', path: '../apktools/apktools'
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Backelite
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,155 @@
1
+ [![Build Status](https://travis-ci.org/Backelite/apk_analyzer.svg?branch=master)](https://travis-ci.org/Backelite/apk_analyzer)
2
+
3
+ # Apk Analyzer
4
+
5
+ The aim of this gem is to extract some data from android apk files. Analysis results are printed in json. It can be used with CLI
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'apk_analyzer'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```shell
18
+ $ bundle
19
+ ```
20
+
21
+ Or install it yourself as:
22
+
23
+ ```shell
24
+ $ gem install apk_analyzer
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ 1. **CLI Usage**
30
+
31
+ In a terminal use Apk analyzer like this:
32
+
33
+ ```shell
34
+ $ apk_analyzer --manifest --cert-info --file /path/to/apk
35
+ ```
36
+
37
+ Script above will collect and print:
38
+ * Android manifest informations
39
+ * Apk certificate informations if it have been signed
40
+
41
+ **Result**
42
+ ```json
43
+ {
44
+ "manifest_info": {
45
+ "path_in_apk": "AndroidManifest.xml",
46
+ "content": {
47
+ "application_info": {
48
+ "theme": "13",
49
+ "label": "E.app.label",
50
+ "icon": "@drawable/ic_launcher",
51
+ "name": "com.package.xxxx.xxxx",
52
+ "debuggable": true,
53
+ "allowBackup": true,
54
+ "hardwareAccelerated": true,
55
+ "application_id": "com.xxxxxxx.xxxx.xxx"
56
+ },
57
+ "intents": [
58
+ {
59
+ "actions": [
60
+ "android.intent.action.MAIN"
61
+ ],
62
+ "category": "android.intent.category.LAUNCHER"
63
+ },
64
+ {
65
+ "actions": [
66
+ "com.android.vending.INSTALL_REFERRER"
67
+ ]
68
+ },
69
+ {
70
+ "actions": [
71
+ "com.google.android.c2dm.intent.RECEIVE",
72
+ "com.google.android.c2dm.intent.REGISTRATION"
73
+ ],
74
+ "category": "com.xxxxxx.xxx.rec"
75
+ },
76
+ {
77
+ "actions": [
78
+ "com.google.firebase.INSTANCE_ID_EVENT"
79
+ ]
80
+ }
81
+ ],
82
+ "uses_sdk": {
83
+ "minimum_sdk_version": 14,
84
+ "target_sdk_version": 23
85
+ },
86
+ "uses_permissions": [
87
+ "android.permission.INTERNET",
88
+ "android.permission.CAMERA",
89
+ "android.permission.WRITE_EXTERNAL_STORAGE",
90
+ "android.permission.READ_EXTERNAL_STORAGE",
91
+ "android.permission.VIBRATE",
92
+ "com.google.android.c2dm.permission.RECEIVE",
93
+ "android.permission.ACCESS_NETWORK_STATE",
94
+ "android.permission.WAKE_LOCK",
95
+ "com.modulotech.xxxxxxx.xxxx.permission.C2D_MESSAGE"
96
+ ],
97
+ "uses_features": [
98
+ {
99
+ "name": "android.hardware.camera",
100
+ "required": true
101
+ }
102
+ ],
103
+ "supports_screens": [
104
+ "anyDensity",
105
+ "normalScreens",
106
+ "largeScreens",
107
+ "xlargeScreens"
108
+ ]
109
+ }
110
+ },
111
+ "cert_info": {
112
+ "issuer_raw": "subject= C=US, O=Android, CN=Android Debug",
113
+ "cn": "Android Debug",
114
+ "ou": null,
115
+ "o": "Android",
116
+ "st": null,
117
+ "l": null,
118
+ "c": "US",
119
+ "creation_date": "Sep 15 07:06:03 2011 GMT",
120
+ "expiration_date": "Sep 7 07:06:03 2041 GMT"
121
+ }
122
+ }
123
+ ```
124
+
125
+ 2. **Inside Ruby code**
126
+
127
+ ```ruby
128
+ require 'apk_analyzer'
129
+
130
+ # Instantiate analyzer
131
+ apk_analyzer = ApkAnalyzer::Analyzer.new(File.expand_path('path/to/apk'))
132
+
133
+ # Then collect data
134
+ manifest_info = apk_analyzer.collect_manifest_info
135
+ certificate_info = apk_analyzer.collect_cert_info
136
+ ```
137
+
138
+ ## Contributing
139
+
140
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Backelite/apk_analyzer.
141
+
142
+ ## Requirements
143
+
144
+ * Java keytool: Java and its keytool utility must be installed and set in the PATH on your OS
145
+ * OpenSSL: version 1.0.2g (1 Mar 2016) or greater
146
+
147
+ ## Known issues
148
+
149
+ To avoid rubyzip 'Invalid date/time in zip entry' message logged by rubzip dependency on [apktools](https://github.com/devunwired/apktools) gem we updated it in our gem and set
150
+ warn_invalid_date to false.
151
+ A [pull request](https://github.com/devunwired/apktools/pull/20) is pending to correct this on apkxml gem too.
152
+
153
+ ## License
154
+
155
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'apk_analyzer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'apk_analyzer'
8
+ spec.version = ApkAnalyzer::VERSION
9
+ spec.authors = 'BACKELITE'
10
+ spec.email = 'opensource@backelite.com'
11
+
12
+ spec.summary = %q{Android apk files analyzer}
13
+ spec.description = %q{The aim of this gem is to extract some data from android apk files. Analysis results
14
+ are printed in json. It can be used with CLI}
15
+ spec.homepage = 'https://github.com/Backelite/apk_analyzer'
16
+ spec.license = 'MIT'
17
+
18
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
19
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
20
+ if spec.respond_to?(:metadata)
21
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
22
+ else
23
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
24
+ 'public gem pushes.'
25
+ end
26
+
27
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
28
+ f.match(%r{^(test|spec|features)/})
29
+ end
30
+ spec.bindir = 'bin'
31
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
32
+ spec.require_paths = ["lib"]
33
+
34
+ spec.add_runtime_dependency 'apktools', '~>0.7'
35
+ spec.add_runtime_dependency 'nokogiri', '~>1.5'
36
+ spec.add_runtime_dependency 'rubyzip', '~>1.2'
37
+
38
+ spec.add_development_dependency "bundler", "~> 1.14"
39
+ spec.add_development_dependency "rake", "~> 10.0"
40
+ spec.add_development_dependency "minitest", "~> 5.0"
41
+ end
data/bin/apk_analyzer ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.push File.expand_path('../../lib', __FILE__)
4
+ require 'apk_analyzer'
5
+ require 'optparse'
6
+ require 'json'
7
+
8
+ options = {
9
+ apk_path: nil,
10
+ manifest: false,
11
+ cert_info: false,
12
+ all: false
13
+ }
14
+
15
+ apk_data = {
16
+ manifest_info: nil,
17
+ cert_info: nil
18
+ }
19
+
20
+ opts_parser = OptionParser.new do |opts|
21
+ opts.on('-f', '--file=FILE_PATH', 'Apk file path') do |file_path|
22
+ options[:apk_path] = file_path
23
+ end
24
+
25
+ opts.on('-m', '--manifest', 'Prints Manifest.xml information') do
26
+ options[:manifest] = true
27
+ end
28
+
29
+ opts.on('-c', '--cert-info', 'Prints Certificate issuer and related dates') do
30
+ options[:cert_info] = true
31
+ end
32
+
33
+ opts.on('-a', '--all', 'Prints available data on APK') do
34
+ options[:all] = true
35
+ end
36
+
37
+ opts.on('-h', '--help', 'Prints help message') do
38
+ puts opts_parser
39
+ puts "\t ex: bin/apk_analyzer -m -c -f [FILE_PATH]"
40
+ exit 0
41
+ end
42
+ end
43
+
44
+ exit_code = 0
45
+
46
+ opts_parser.parse!
47
+
48
+ raise 'File not specified' if options[:apk_path].nil?
49
+ apk_analyzer = ApkAnalyzer::Analyzer.new(File.expand_path(options[:apk_path]))
50
+ apk_data = {}
51
+ begin
52
+ apk_data[:manifest_info] = apk_analyzer.collect_manifest_info if options[:manifest] || options[:all]
53
+ apk_data[:cert_info] = apk_analyzer.collect_cert_info if options[:cert_info] || options[:all]
54
+ puts JSON.pretty_generate(apk_data)
55
+ rescue => e
56
+ puts e.message
57
+ puts e.backtrace
58
+ exit_code = 1
59
+ end
60
+
61
+ exit exit_code
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "apk_analyzer"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
9
+ chmod +x bin/apk_analyzer
@@ -0,0 +1,282 @@
1
+ require 'apktools/apkxml'
2
+ require 'nokogiri'
3
+ require 'shellwords'
4
+
5
+ module ApkAnalyzer
6
+ class Analyzer
7
+ HEX_FALSE = '0x0'.freeze
8
+ HEX_TRUE = '0xffffffff'.freeze
9
+ REQUIRED = 'required'.freeze
10
+ GL_ES_VERSION = 'glEsVersion'
11
+ NAME = 'name'
12
+ ACTION = 'action'
13
+ CATEGORY = 'category'
14
+ ANDROID_MANIFEST_FILE = 'AndroidManifest.xml'
15
+
16
+
17
+ def initialize(apk_path)
18
+ # Deactivating invalid date warnings in zip for apktools gem and apk analyzer code
19
+ Zip.warn_invalid_date = false
20
+ @apk_path = apk_path
21
+ raise 'File is not a valid apk file' unless valid_zip?(apk_path)
22
+ @apk_xml = ApkXml.new(apk_path)
23
+ end
24
+
25
+ def collect_manifest_info
26
+ manifest_file_path = find_file_in_apk(ANDROID_MANIFEST_FILE)
27
+ raise 'Failed to find Manifest file in apk' if manifest_file_path.nil?
28
+ begin
29
+ manifest_xml = Nokogiri::XML(@apk_xml.parse_xml('AndroidManifest.xml', true, true))
30
+ rescue => e
31
+ puts "Failed to parse #{ANDROID_MANIFEST_FILE}"
32
+ log_expection e
33
+ end
34
+
35
+ manifest_info = {}
36
+ begin
37
+ manifest_info[:path_in_apk] = manifest_file_path
38
+ content = {}
39
+ # application content
40
+ content[:application_info] = collect_application_info(manifest_xml)
41
+
42
+ # intents
43
+ content[:intents] = collect_intent_info(manifest_xml)
44
+
45
+ # sdk infos
46
+ sdk_infos = collect_sdk_info(manifest_xml)
47
+ content[:uses_sdk] = { minimum_sdk_version: sdk_infos[0], target_sdk_version: sdk_infos[1] }
48
+
49
+ # uses permission
50
+ uses_permissions = collect_uses_permission_info(manifest_xml)
51
+ content[:uses_permissions] = uses_permissions
52
+
53
+ # uses features
54
+ feature_list = collect_uses_feature_info(manifest_xml)
55
+ content[:uses_features] = feature_list
56
+
57
+ # screen compatibility
58
+ supported_screens = collect_supported_screens(manifest_xml)
59
+ content[:supports_screens] = supported_screens
60
+
61
+ manifest_info[:content] = content
62
+ rescue => e
63
+ log_expection e
64
+ raise "Invalid xml found"
65
+ end
66
+ manifest_info
67
+ end
68
+
69
+ # Certificate info. Issuer and dates
70
+ def collect_cert_info
71
+ raise 'keytool dependency not satisfied. Make sure that JAVA keytool utility is installed' if `which keytool` == ''
72
+ cert_info = {}
73
+ certificate_raw = `keytool -printcert -rfc -jarfile #{@apk_path.shellescape}`
74
+ certificate_content_regexp = /(-----BEGIN CERTIFICATE-----.*-----END CERTIFICATE-----)/m
75
+ matched_data = certificate_content_regexp.match(certificate_raw)
76
+ if matched_data
77
+ certificate_content = matched_data.captures[0]
78
+ cert_info = {
79
+ issuer_raw: nil,
80
+ cn: nil,
81
+ ou: nil,
82
+ o: nil,
83
+ st: nil,
84
+ l: nil,
85
+ c: nil,
86
+ creation_date: nil,
87
+ expiration_date: nil
88
+ }
89
+ cert_extract_dates(certificate_content, cert_info)
90
+ cert_extract_issuer(certificate_content, cert_info)
91
+ else
92
+ puts 'Failed to find CERT.RSA file in APK'
93
+ end
94
+ cert_info
95
+ end
96
+
97
+ private
98
+
99
+ def collect_supported_screens(manifest_xml)
100
+ supported_screens = []
101
+ screen_types = manifest_xml.xpath('//supports-screens').first
102
+ unless screen_types.nil?
103
+ screen_types.attributes.each do |screen_type, required_param|
104
+ supported_screens.push screen_type if required_param.value == HEX_TRUE
105
+ end
106
+ end
107
+ supported_screens
108
+ end
109
+
110
+ def collect_uses_feature_info(manifest_xml)
111
+ features = manifest_xml.xpath('//uses-feature')
112
+ feature_list = []
113
+ features.each do |feature|
114
+ feature_element = {}
115
+ feature.attributes.each_value do |attr|
116
+ feature_attr_key = attr.name
117
+ feature_attr_value = attr.value
118
+
119
+ if attr.name == REQUIRED
120
+ feature_attr_value = bool_conv(feature_attr_value)
121
+ elsif attr.name == GL_ES_VERSION
122
+ feature_attr_key = NAME
123
+ feature_attr_value = opengl_version_conv(attr.value)
124
+ end
125
+
126
+ feature_element[feature_attr_key.to_sym] = feature_attr_value
127
+ end
128
+ feature_list.push feature_element
129
+ end
130
+ feature_list
131
+ end
132
+
133
+ def collect_uses_permission_info(manifest_xml)
134
+ uses_permissions = []
135
+ manifest_xml.xpath('//uses-permission/@android:name').each { |permission| uses_permissions.push permission.value }
136
+ uses_permissions
137
+ end
138
+
139
+ def collect_application_info(manifest_xml)
140
+ application_content = {}
141
+ application_tag = manifest_xml.xpath('//application')
142
+
143
+ # Collect all attributes within application tag
144
+ unless application_tag.empty?
145
+ application_attributes = application_tag.first.attributes
146
+ application_attributes.each_value do |attr_key|
147
+ value = attr_key.value
148
+ value = bool_conv(value) if is_hex_bool?(value)
149
+ application_content[attr_key.name.to_sym] = value
150
+ end
151
+ end
152
+
153
+ # Add application id to previous informations
154
+ application_id = manifest_xml.xpath('//manifest/@package')
155
+ application_content[:application_id] = application_id[0].value unless application_id.empty?
156
+
157
+ application_content
158
+ end
159
+
160
+ def collect_intent_info(manifest_xml)
161
+ intent_filters = manifest_xml.xpath('//intent-filter')
162
+ intents = []
163
+ intent_filters.each do |intent|
164
+ intent_attributes = {}
165
+ actions = []
166
+ category = nil
167
+ intent.children.each do |child|
168
+ next unless child.is_a?(Nokogiri::XML::Element)
169
+ if child.name == ACTION
170
+ actions.push child.attributes[NAME].value
171
+ elsif child.name == CATEGORY
172
+ category = child.attributes[NAME].value
173
+ end
174
+ end
175
+ intent_attributes[:actions] = actions unless actions.empty?
176
+ intent_attributes[:category] = category unless category.nil?
177
+ intents.push intent_attributes unless intent_attributes.empty?
178
+ end
179
+ intents
180
+ end
181
+
182
+ def collect_sdk_info(manifest_xml)
183
+ sdk_infos = []
184
+ minimum_sdk_version = manifest_xml.xpath('//uses-sdk/@android:minSdkVersion')
185
+ target_sdk_version = manifest_xml.xpath('//uses-sdk/@android:targetSdkVersion')
186
+ sdk_infos = [minimum_sdk_version, target_sdk_version].map { |elt| sanitize_hex(elt.first.value) unless elt.empty? }
187
+ sdk_infos
188
+ end
189
+
190
+ def cert_extract_issuer(certificate_content, result)
191
+ subject = `echo "#{certificate_content}" | openssl x509 -noout -in /dev/stdin -subject -nameopt -esc_msb,utf8`
192
+ result[:issuer_raw] = subject.gsub(/\n/,'')
193
+ result[:cn] = cert_extract_issuer_parameterized(subject, 'CN').gsub(/\n/,'')
194
+ result[:ou] = cert_extract_issuer_parameterized(subject, 'OU')
195
+ result[:o] = cert_extract_issuer_parameterized(subject, 'O')
196
+ result[:st] = cert_extract_issuer_parameterized(subject, 'ST')
197
+ result[:l] = cert_extract_issuer_parameterized(subject, 'L')
198
+ result[:c] = cert_extract_issuer_parameterized(subject, 'C')
199
+ end
200
+
201
+ def cert_extract_issuer_parameterized(subject, param)
202
+ # The following regex was previously used to match fields when not
203
+ # using '-nameopt -esc_msb,utf8'' switch with openssl
204
+ # match = %r{\/#{Regexp.quote(param)}=([^\/]*)}.match(subject)
205
+
206
+ match = /#{Regexp.quote(param)}=([^=]*)(, [A-Z]+=|$)/.match(subject)
207
+ return nil if match.nil?
208
+ match.captures[0]
209
+ end
210
+
211
+ def cert_extract_dates(certificate_content, result)
212
+ #collect dates
213
+ start_date = `echo "#{certificate_content}" | openssl x509 -noout -in /dev/stdin -startdate -nameopt -esc_msb,utf8`
214
+ end_date = `echo "#{certificate_content}" | openssl x509 -noout -in /dev/stdin -enddate -nameopt -esc_msb,utf8`
215
+ result[:creation_date] = cert_extract_date(start_date)
216
+ result[:expiration_date] = cert_extract_date(end_date)
217
+ end
218
+
219
+ def cert_extract_date(date_str)
220
+ match = /=(.*)$/.match(date_str)
221
+ match.captures[0]
222
+ end
223
+
224
+ def sanitize_hex(hex)
225
+ hex.to_i(16)
226
+ end
227
+
228
+ # hex strings come come from apktools/apkxml.
229
+ # It converts true to 0xffffffff and false to 0x0
230
+ def bool_conv(value)
231
+ value == HEX_FALSE ? false : true
232
+ end
233
+
234
+ def is_hex_bool?(hex_string)
235
+ hex_string == HEX_TRUE || hex_string == HEX_FALSE
236
+ end
237
+
238
+ def opengl_version_conv(value)
239
+ value_copy = value.dup
240
+ value_copy = value_copy.gsub(/\D|0/, '')
241
+ value_copy.chars.join('.')
242
+ value_copy += '.0' if value.chars.last == '0'
243
+ "Open GL #{value_copy}"
244
+ end
245
+
246
+ def valid_zip?(file)
247
+ zip = Zip::File.open(file)
248
+ true
249
+ rescue StandardError
250
+ false
251
+ ensure
252
+ zip.close if zip
253
+ end
254
+
255
+ def find_file_in_apk(file_name)
256
+ begin
257
+ file_path_in_apk = nil
258
+ apk_zipfile = Zip::File.open(@apk_path)
259
+
260
+ # Search at the root
261
+ file_path_in_apk = apk_zipfile.find_entry(file_name)
262
+ return file_path_in_apk.name unless file_path_in_apk.nil?
263
+
264
+ # Search deeply
265
+ apk_zipfile.each do |entry|
266
+ file_path_in_apk = entry.name if entry.name.match(file_name)
267
+ break unless file_path_in_apk.nil?
268
+ end
269
+ file_path_in_apk.nil? ? nil : file_path_in_apk
270
+ rescue => e
271
+ log_expection e
272
+ ensure
273
+ apk_zipfile.close
274
+ end
275
+ end
276
+
277
+ def log_expection e
278
+ puts e.message
279
+ puts e.backtrace
280
+ end
281
+ end
282
+ end
@@ -0,0 +1,3 @@
1
+ module ApkAnalyzer
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,2 @@
1
+ require 'apk_analyzer/version'
2
+ require 'apk_analyzer/analyzer'
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: apk_analyzer
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - BACKELITE
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: apktools
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubyzip
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.14'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.14'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '5.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '5.0'
97
+ description: |-
98
+ The aim of this gem is to extract some data from android apk files. Analysis results
99
+ are printed in json. It can be used with CLI
100
+ email: opensource@backelite.com
101
+ executables:
102
+ - apk_analyzer
103
+ - console
104
+ - setup
105
+ extensions: []
106
+ extra_rdoc_files: []
107
+ files:
108
+ - ".gitignore"
109
+ - ".travis.yml"
110
+ - Gemfile
111
+ - LICENSE.txt
112
+ - README.md
113
+ - Rakefile
114
+ - apk_analyzer.gemspec
115
+ - bin/apk_analyzer
116
+ - bin/console
117
+ - bin/setup
118
+ - lib/apk_analyzer.rb
119
+ - lib/apk_analyzer/analyzer.rb
120
+ - lib/apk_analyzer/version.rb
121
+ homepage: https://github.com/Backelite/apk_analyzer
122
+ licenses:
123
+ - MIT
124
+ metadata:
125
+ allowed_push_host: https://rubygems.org
126
+ post_install_message:
127
+ rdoc_options: []
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ requirements: []
141
+ rubyforge_project:
142
+ rubygems_version: 2.4.5.1
143
+ signing_key:
144
+ specification_version: 4
145
+ summary: Android apk files analyzer
146
+ test_files: []