apk_analyzer 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: []