android_parser 2.4.1 → 2.5.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 +4 -4
- data/.github/dependabot.yml +9 -0
- data/.github/workflows/ci.yml +26 -0
- data/.gitignore +2 -1
- data/.rspec +3 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +9 -17
- data/README.md +93 -75
- data/Rakefile +5 -39
- data/android_parser.gemspec +29 -58
- data/lib/android/apk.rb +7 -3
- data/lib/android/axml_parser.rb +5 -2
- data/lib/android/axml_writer.rb +2 -0
- data/lib/android/dex/access_flag.rb +2 -1
- data/lib/android/dex/dex_object.rb +6 -5
- data/lib/android/dex/info.rb +3 -1
- data/lib/android/dex/utils.rb +5 -3
- data/lib/android/dex.rb +3 -1
- data/lib/android/layout.rb +5 -4
- data/lib/android/manifest.rb +213 -47
- data/lib/android/resource.rb +1 -0
- data/lib/android/utils.rb +1 -0
- data/lib/android_parser.rb +10 -0
- data/lib/ruby_apk.rb +4 -8
- metadata +28 -62
- data/.travis.yml +0 -5
- data/Gemfile.lock +0 -92
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc3206bde4ce793fb477360fd78062daa372bf5dba443d3521d86b8ffaf0a91f
|
4
|
+
data.tar.gz: 15c49cc70cb8ac8c561bdb2f5d6e108c9ff6d095bf82b56996ee1c012c874b37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 470a1645dc911bc2f41405ac41beb93d570a4885ab2413f61c7f413ce38477a7bc0c3da7162de40cd48b97799dcfd4eab12f1335a9c48a40e2555720f60a39b4
|
7
|
+
data.tar.gz: 55b1870a03b25be087e20e75c2d32a92c15a5a2a1a7d6290970a1ce0af78b44399fe5e9957fb8f111c53d9c2c59e98648b594cf7aad8d16666ff77775a3cfb10
|
@@ -0,0 +1,26 @@
|
|
1
|
+
name: CI
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
branches:
|
5
|
+
- master
|
6
|
+
pull_request:
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
test:
|
10
|
+
strategy:
|
11
|
+
fail-fast: false
|
12
|
+
matrix:
|
13
|
+
ruby: [ ruby-2.5, ruby-2.6, ruby-2.7, ruby-3.0 ]
|
14
|
+
os: [ ubuntu-latest, macos-latest ]
|
15
|
+
runs-on: ${{ matrix.os }}
|
16
|
+
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
|
20
|
+
- uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
bundler-cache: true
|
24
|
+
|
25
|
+
- name: bundle exec rspec
|
26
|
+
run: bundle exec rspec --format progress --force-colour
|
data/.gitignore
CHANGED
@@ -10,6 +10,7 @@ doc
|
|
10
10
|
|
11
11
|
# bundler
|
12
12
|
.bundle
|
13
|
+
Gemfile.lock
|
13
14
|
|
14
15
|
# rvm
|
15
16
|
.ruby-version
|
@@ -17,7 +18,7 @@ doc
|
|
17
18
|
# jeweler generated
|
18
19
|
#pkg # upload gem file to server
|
19
20
|
|
20
|
-
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
21
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
21
22
|
#
|
22
23
|
# * Create a file at ~/.gitignore
|
23
24
|
# * Include files you want ignored
|
data/.rspec
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,45 +1,60 @@
|
|
1
1
|
# ChangeLog
|
2
|
+
|
3
|
+
## 2.5.0
|
4
|
+
|
5
|
+
> New begins!
|
2
6
|
## 0.7.0
|
7
|
+
|
3
8
|
* implement Apk#signs, Apk#certificates and Manifest#version_name (#14, #15)
|
4
9
|
* bugfix
|
5
10
|
|
6
11
|
## 0.6.0
|
12
|
+
|
7
13
|
* implement Android::Apk#layouts(#10), Android::Apk#icon(#11), Android::Apk#label(#12),
|
8
14
|
* fix bug (#13)
|
9
15
|
|
10
16
|
## 0.5.1
|
17
|
+
|
11
18
|
* [#8] add Android::Manifest#label
|
12
19
|
* [#7] fix wrong boolean value in manifest parser
|
13
20
|
* [#6] add accessor Android::Manifest#doc
|
14
21
|
|
15
22
|
## 0.5.0
|
23
|
+
|
16
24
|
* [issue #1] implement Android::Resource#find, #res_readable_id, #res_hex_id methods
|
17
25
|
|
18
26
|
## 0.4.2
|
27
|
+
|
19
28
|
* fix bugs(#2, #3)
|
20
29
|
* divide change log from readme
|
21
30
|
|
22
31
|
## 0.4.1
|
32
|
+
|
23
33
|
* fix typo
|
24
34
|
* add document
|
25
35
|
|
26
36
|
## 0.4.0
|
37
|
+
|
27
38
|
* add resource parser
|
28
39
|
* enhance dex parser
|
29
40
|
|
30
41
|
## 0.3.0
|
42
|
+
|
31
43
|
* add and change name space
|
32
44
|
* add Android::Utils module and some util methods
|
33
45
|
* add Apk#entry, Apk#each_entry, and Apk#time methods,
|
34
46
|
|
35
47
|
## 0.2.0
|
48
|
+
|
36
49
|
* update documents
|
37
50
|
* add Apk::Dex#each_strings, Apk::Dex#each_class_names
|
38
51
|
|
39
52
|
## 0.1.2
|
53
|
+
|
40
54
|
* fix bug(improve android binary xml parser)
|
41
55
|
|
42
56
|
## 0.1.1
|
57
|
+
|
43
58
|
* fix bug(failed to initialize Apk::Manifest::Meta class)
|
44
59
|
* replace iconv to String#encode(for ruby1.9)
|
45
60
|
|
data/Gemfile
CHANGED
@@ -1,18 +1,10 @@
|
|
1
|
-
source
|
2
|
-
# Add dependencies required to use your gem here.
|
3
|
-
# Example:
|
4
|
-
# gem "activesupport", ">= 2.3.5"
|
5
|
-
gem "rubyzip", ">=1.0.0"
|
1
|
+
source 'http://rubygems.org'
|
6
2
|
|
7
|
-
#
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
gem "yard", require: false
|
16
|
-
gem "redcarpet"
|
17
|
-
gem "simplecov", require: false
|
18
|
-
end
|
3
|
+
# Specify your gem's dependencies in android_parser.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
# group :development do
|
7
|
+
# gem 'awesome_print'
|
8
|
+
# gem 'debase'
|
9
|
+
# gem 'ruby-debug-ide'
|
10
|
+
# end
|
data/README.md
CHANGED
@@ -1,25 +1,30 @@
|
|
1
|
-
#
|
2
|
-
Android Apk static analysis library for Ruby.
|
1
|
+
# android_parser
|
3
2
|
|
4
|
-
[
|
5
|
-
[](https://travis-ci.org/playtestcloud/ruby_apk)
|
6
|
-
[](https://gemnasium.com/github.com/playtestcloud/ruby_apk)
|
3
|
+
Android Apk static analysis parser library for Ruby, forked from [playtestcloud/ruby_apk](https://github.com/playtestcloud/ruby_apk).
|
7
4
|
|
8
5
|
## Requirements
|
9
|
-
|
6
|
+
|
7
|
+
- ruby (>= 2.5)
|
10
8
|
|
11
9
|
## Install
|
12
|
-
|
10
|
+
|
11
|
+
```bash
|
12
|
+
gem install android_parser
|
13
|
+
```
|
13
14
|
|
14
15
|
## Usage
|
16
|
+
|
15
17
|
### Initialize
|
18
|
+
|
16
19
|
```ruby
|
17
|
-
|
18
|
-
|
20
|
+
require 'android_parser'
|
21
|
+
|
22
|
+
apk = Android::Apk.new('sample.apk') # set apk file path
|
19
23
|
```
|
20
24
|
|
21
25
|
### Apk
|
22
26
|
#### Listing files in Apk
|
27
|
+
|
23
28
|
```ruby
|
24
29
|
# listing files in apk
|
25
30
|
apk = Android::Apk.new('sample.apk')
|
@@ -29,126 +34,139 @@ end
|
|
29
34
|
```
|
30
35
|
|
31
36
|
#### Find files in Apk
|
37
|
+
|
32
38
|
```ruby
|
33
|
-
|
34
|
-
|
39
|
+
apk = Android::Apk.new('sample.apk')
|
40
|
+
elf_files = apk.find{|name, data| data[0..3] == [0x7f, 0x45, 0x4c, 0x46] } # ELF magic number
|
35
41
|
```
|
36
42
|
|
37
43
|
#### Extract icon data in Apk (since 0.6.0)
|
44
|
+
|
38
45
|
```ruby
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
apk = Android::Apk.new('sample.apk')
|
47
|
+
icons = apk.icon # { "res/drawable-hdpi/ic_launcher.png" => "\x89PNG\x0D\x0A...", ... }
|
48
|
+
icons.each do |name, data|
|
49
|
+
File.open(File.basename(name), 'wb') {|f| f.write data } # save to file.
|
50
|
+
end
|
44
51
|
```
|
45
52
|
|
46
53
|
#### Extract signature and certificate information from Apk (since v0.7.0)
|
54
|
+
|
47
55
|
```ruby
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
56
|
+
apk = Android::Apk.new('sample.apk')
|
57
|
+
signs = apk.signs # retrun Hash(key: signature file path, value: OpenSSL::PKCS7)
|
58
|
+
signs.each do |path, sign|
|
59
|
+
puts path # => "MATA-INF/CERT.RSA" or ...
|
60
|
+
puts sign # => "-----BEGIN PKCS7-----\n..." PKCS7 object
|
61
|
+
end
|
54
62
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
63
|
+
certs = apk.certificates # retrun Hash(key: signature file path, value: OpenSSL::X509::Certificate)
|
64
|
+
certs.each do |path, cert|
|
65
|
+
puts path # => "MATA-INF/CERT.RSA" or ...
|
66
|
+
puts cert # => "-----BEGIN CERTIFICATE-----\n..." # X509::Certificate object
|
67
|
+
end
|
60
68
|
```
|
61
69
|
Note: Most apks have only one signature and cerficate.
|
62
70
|
|
63
71
|
### Manifest
|
72
|
+
|
64
73
|
#### Get readable xml
|
74
|
+
|
65
75
|
```ruby
|
66
|
-
|
67
|
-
|
68
|
-
|
76
|
+
apk = Android::Apk.new('sample.apk')
|
77
|
+
manifest = apk.manifest
|
78
|
+
puts manifest.to_xml
|
69
79
|
```
|
70
80
|
|
71
81
|
#### Listing components and permissions
|
82
|
+
|
72
83
|
```ruby
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
84
|
+
apk = Android::Apk.new('sample.apk')
|
85
|
+
manifest = apk.manifest
|
86
|
+
# listing components
|
87
|
+
manifest.components.each do |c| # 'c' is Android::Manifest::Component object
|
88
|
+
puts "#{c.type}: #{c.name}"
|
89
|
+
c.intent_filters.each do |filter|
|
90
|
+
puts "\t#{filter.type}"
|
81
91
|
end
|
92
|
+
end
|
82
93
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
94
|
+
# listing use-permission tag
|
95
|
+
manifest.use_permissions.each do |permission|
|
96
|
+
puts permission
|
97
|
+
end
|
87
98
|
```
|
88
99
|
|
89
100
|
#### Extract application label string
|
101
|
+
|
90
102
|
```ruby
|
91
|
-
|
92
|
-
|
103
|
+
apk = Android::Apk.new('sample.apk')
|
104
|
+
puts apk.manifest.label
|
93
105
|
```
|
94
106
|
|
95
107
|
### Resource
|
108
|
+
|
96
109
|
#### Extract resource strings from apk
|
110
|
+
|
97
111
|
```ruby
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
112
|
+
apk = Android::Apk.new('sample.apk')
|
113
|
+
rsc = apk.resource
|
114
|
+
rsc.strings.each do |str|
|
115
|
+
puts str
|
116
|
+
end
|
103
117
|
```
|
104
118
|
|
105
119
|
#### Parse resource file directly
|
120
|
+
|
106
121
|
```ruby
|
107
|
-
|
108
|
-
|
122
|
+
rsc_data = File.open('resources.arsc', 'rb').read{|f| f.read }
|
123
|
+
rsc = Android::Resource.new(rsc_data)
|
109
124
|
```
|
110
125
|
|
111
126
|
### Resolve resource id
|
127
|
+
|
112
128
|
This feature supports only srting resources for now.
|
113
129
|
|
114
130
|
```ruby
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
# assigns readable resource id
|
119
|
-
puts rsc.find('@string/app_name') # => 'application name'
|
131
|
+
apk = Android::Apk.new('sample.apk')
|
132
|
+
rsc = apk.resource
|
120
133
|
|
121
|
-
|
122
|
-
|
134
|
+
# assigns readable resource id
|
135
|
+
puts rsc.find('@string/app_name') # => 'application name'
|
123
136
|
|
124
|
-
|
125
|
-
|
126
|
-
```
|
137
|
+
# assigns hex resource id
|
138
|
+
puts rsc.find('@0x7f040000') # => 'application name'
|
127
139
|
|
140
|
+
# you can set lang attribute.
|
141
|
+
puts rsc.find('@0x7f040000', :lang => 'ja')
|
142
|
+
```
|
128
143
|
|
129
144
|
### Dex
|
145
|
+
|
130
146
|
#### Extract dex information
|
147
|
+
|
131
148
|
```ruby
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
149
|
+
apk = Android::Apk.new('sample.apk')
|
150
|
+
dex = apk.dex
|
151
|
+
# listing string table in dex
|
152
|
+
dex.strings.each do |str|
|
153
|
+
puts str
|
154
|
+
end
|
138
155
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
end
|
156
|
+
# listing all class names
|
157
|
+
dex.classes.each do |cls| # cls is Android::Dex::ClassInfo
|
158
|
+
puts "class: #{cls.name}"
|
159
|
+
cls.virtual_methods.each do |m| # Android::Dex::MethodInfo
|
160
|
+
puts "\t#{m.definition}" # puts method definition
|
145
161
|
end
|
162
|
+
end
|
146
163
|
```
|
147
164
|
|
148
165
|
#### Parse dex file directly
|
166
|
+
|
149
167
|
```ruby
|
150
|
-
|
151
|
-
|
168
|
+
dex_data = File.open('classes.dex','rb').read{|f| f.read }
|
169
|
+
dex = Android::Dex.new(dex_data)
|
152
170
|
```
|
153
171
|
|
154
172
|
|
data/Rakefile
CHANGED
@@ -1,44 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require '
|
5
|
-
begin
|
6
|
-
Bundler.setup(:default, :development)
|
7
|
-
rescue Bundler::BundlerError => e
|
8
|
-
$stderr.puts e.message
|
9
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
-
exit e.status_code
|
11
|
-
end
|
12
|
-
require 'rake'
|
3
|
+
$LOAD_PATH.unshift File.expand_path('lib', __dir__)
|
4
|
+
require 'android_parser'
|
13
5
|
require 'bundler/gem_tasks'
|
14
|
-
|
15
|
-
# require 'jeweler'
|
16
|
-
# Jeweler::Tasks.new do |gem|
|
17
|
-
# # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
18
|
-
# gem.name = "android_parser"
|
19
|
-
# gem.homepage = "https://github.com/icyleaf/ruby_apk"
|
20
|
-
# gem.license = "MIT"
|
21
|
-
# gem.summary = %Q{static analysis tool for android apk}
|
22
|
-
# gem.description = %Q{static analysis tool for android apk}
|
23
|
-
# gem.email = "info@securebrain.co.jp"
|
24
|
-
# gem.authors = ["SecureBrain"]
|
25
|
-
# # dependencies defined in Gemfile
|
26
|
-
# end
|
27
|
-
# Jeweler::RubygemsDotOrgTasks.new
|
28
|
-
|
29
|
-
require 'rspec/core'
|
30
6
|
require 'rspec/core/rake_task'
|
31
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
-
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
-
end
|
34
|
-
|
35
7
|
|
36
|
-
|
8
|
+
RSpec::Core::RakeTask.new(:spec)
|
37
9
|
|
38
|
-
|
39
|
-
# require 'yard/rake/yardoc_task'
|
40
|
-
# YARD::Rake::YardocTask.new do |t|
|
41
|
-
# t.files = ['lib/**/*.rb']
|
42
|
-
# t.options = []
|
43
|
-
# t.options << '--debug' << '--verbose' if $trace
|
44
|
-
# end
|
10
|
+
task default: :spec
|
data/android_parser.gemspec
CHANGED
@@ -1,64 +1,35 @@
|
|
1
|
-
#
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: ruby_apk 2.3.0 ruby lib
|
1
|
+
# frozen_string_literal: true
|
6
2
|
|
7
|
-
|
8
|
-
s.name = "android_parser".freeze
|
9
|
-
s.version = "2.4.1"
|
3
|
+
# frozen_string_literal: true
|
10
4
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
s.date = "2021-08-04"
|
15
|
-
s.description = "static analysis tool for android apk".freeze
|
16
|
-
s.email = "info@securebrain.co.jp".freeze
|
17
|
-
s.extra_rdoc_files = [
|
18
|
-
"CHANGELOG.md",
|
19
|
-
"LICENSE.txt",
|
20
|
-
"README.md"
|
21
|
-
]
|
22
|
-
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
23
|
-
s.homepage = "https://github.com/icyleaf/ruby_apk".freeze
|
24
|
-
s.licenses = ["MIT".freeze]
|
25
|
-
s.rubygems_version = "3.0.3".freeze
|
26
|
-
s.summary = "static analysis tool for android apk".freeze
|
5
|
+
lib = File.expand_path('../lib', __FILE__)
|
6
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
7
|
+
# require 'android_parser/version'
|
27
8
|
|
28
|
-
|
29
|
-
|
9
|
+
Gem::Specification.new do |spec|
|
10
|
+
spec.name = 'android_parser'
|
11
|
+
spec.version = '2.5.0'
|
12
|
+
spec.authors = ['SecureBrain', 'icyleaf']
|
13
|
+
spec.email = ['info@securebrain.co.jp', 'icyleaf.cn@gmail.com']
|
14
|
+
spec.platform = Gem::Platform::RUBY
|
15
|
+
spec.summary = 'Static analysis tool for android apk since 2021'
|
16
|
+
spec.description = 'Static analysis tool for android apk since 2021'
|
17
|
+
spec.homepage = 'https://github.com/icyleaf/android_parser'
|
18
|
+
spec.license = 'MIT'
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
spec.required_ruby_version = '>= 2.5'
|
30
22
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
s.add_development_dependency(%q<rspec-mocks>.freeze, [">= 3.6.0"])
|
36
|
-
s.add_development_dependency(%q<bundler>.freeze, [">= 1.1.5"])
|
37
|
-
s.add_development_dependency(%q<jeweler>.freeze, [">= 0"])
|
38
|
-
s.add_development_dependency(%q<yard>.freeze, [">= 0"])
|
39
|
-
s.add_development_dependency(%q<redcarpet>.freeze, [">= 0"])
|
40
|
-
s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
|
41
|
-
else
|
42
|
-
s.add_dependency(%q<rubyzip>.freeze, [">= 1.0.0"])
|
43
|
-
s.add_dependency(%q<rspec-its>.freeze, [">= 1.2.0"])
|
44
|
-
s.add_dependency(%q<rspec-collection_matchers>.freeze, [">= 1.1.0"])
|
45
|
-
s.add_dependency(%q<rspec-mocks>.freeze, [">= 3.6.0"])
|
46
|
-
s.add_dependency(%q<bundler>.freeze, [">= 1.1.5"])
|
47
|
-
s.add_dependency(%q<jeweler>.freeze, [">= 0"])
|
48
|
-
s.add_dependency(%q<yard>.freeze, [">= 0"])
|
49
|
-
s.add_dependency(%q<redcarpet>.freeze, [">= 0"])
|
50
|
-
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
51
|
-
end
|
52
|
-
else
|
53
|
-
s.add_dependency(%q<rubyzip>.freeze, [">= 1.0.0"])
|
54
|
-
s.add_dependency(%q<rspec-its>.freeze, [">= 1.2.0"])
|
55
|
-
s.add_dependency(%q<rspec-collection_matchers>.freeze, [">= 1.1.0"])
|
56
|
-
s.add_dependency(%q<rspec-mocks>.freeze, [">= 3.6.0"])
|
57
|
-
s.add_dependency(%q<bundler>.freeze, [">= 1.1.5"])
|
58
|
-
s.add_dependency(%q<jeweler>.freeze, [">= 0"])
|
59
|
-
s.add_dependency(%q<yard>.freeze, [">= 0"])
|
60
|
-
s.add_dependency(%q<redcarpet>.freeze, [">= 0"])
|
61
|
-
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
23
|
+
spec.add_dependency 'rubyzip', '>= 1.0', '< 3.0'
|
24
|
+
|
25
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0') then
|
26
|
+
spec.add_dependency 'rexml', '> 3.0'
|
62
27
|
end
|
63
|
-
end
|
64
28
|
|
29
|
+
spec.add_development_dependency 'rspec-its', '>= 1.2.0'
|
30
|
+
spec.add_development_dependency 'rspec-collection_matchers', '>= 1.1.0'
|
31
|
+
spec.add_development_dependency 'rspec-mocks', '>= 3.6.0'
|
32
|
+
spec.add_development_dependency 'bundler', '>= 1.12'
|
33
|
+
spec.add_development_dependency 'rake', '>= 10.0'
|
34
|
+
# spec.add_development_dependency 'rspec', '~> 3.0'
|
35
|
+
end
|
data/lib/android/apk.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'digest/md5'
|
3
4
|
require 'digest/sha1'
|
4
5
|
require 'digest/sha2'
|
5
6
|
require 'openssl'
|
7
|
+
require 'zip'
|
6
8
|
|
7
9
|
module Android
|
8
10
|
class NotApkFileError < StandardError; end
|
@@ -37,12 +39,14 @@ module Android
|
|
37
39
|
# @raise [Android::NotFoundError] path file does'nt exist
|
38
40
|
# @raise [Android::NotApkFileError] path file is not Apk file.
|
39
41
|
def initialize(filepath)
|
42
|
+
Zip.warn_invalid_date = false
|
43
|
+
|
40
44
|
@path = filepath
|
41
45
|
raise NotFoundError, "'#{filepath}'" unless File.exist? @path
|
42
46
|
begin
|
43
47
|
@zip = Zip::File.open(@path)
|
44
48
|
rescue Zip::Error => e
|
45
|
-
raise NotApkFileError, e.message
|
49
|
+
raise NotApkFileError, e.message
|
46
50
|
end
|
47
51
|
|
48
52
|
@bindata = File.open(@path, 'rb') {|f| f.read }
|
@@ -51,7 +55,7 @@ module Android
|
|
51
55
|
begin
|
52
56
|
@resource = Android::Resource.new(self.file(RESOURCE))
|
53
57
|
rescue => e
|
54
|
-
$stderr.puts "failed to parse resource
|
58
|
+
$stderr.puts "failed to parse resource: #{e}"
|
55
59
|
#$stderr.puts e.backtrace
|
56
60
|
end
|
57
61
|
begin
|
data/lib/android/axml_parser.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rexml/document'
|
2
4
|
require 'stringio'
|
3
5
|
|
4
|
-
|
5
6
|
module Android
|
6
7
|
# binary AXML parser
|
7
8
|
# @see https://android.googlesource.com/platform/frameworks/base.git Android OS frameworks source
|
@@ -12,8 +13,10 @@ module Android
|
|
12
13
|
#
|
13
14
|
# /frameworks/base/libs/androidfw/ResourceTypes.cpp
|
14
15
|
class AXMLParser
|
16
|
+
HEADER = "\x03\x00\x08\x00"
|
17
|
+
|
15
18
|
def self.axml?(data)
|
16
|
-
(data[0..3] ==
|
19
|
+
(data[0..3] == HEADER)
|
17
20
|
end
|
18
21
|
|
19
22
|
# axml parse error
|
data/lib/android/axml_writer.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module Android
|
3
4
|
class Dex
|
@@ -39,7 +40,7 @@ module Android
|
|
39
40
|
ACCESSORS.select{|e| ((e[:value] & @flag) != 0) }.map{|e| e[:name] }.join(' ')
|
40
41
|
end
|
41
42
|
end
|
42
|
-
|
43
|
+
|
43
44
|
# access flag object for method in dex
|
44
45
|
class MethodAccessFlag < AccessFlag
|
45
46
|
ACCESSORS = [
|