app-info 3.0.0.beta1 → 3.0.0.beta3
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/.rubocop.yml +2 -0
- data/CHANGELOG.md +29 -3
- data/README.md +4 -4
- data/lib/app_info/aab.rb +57 -114
- data/lib/app_info/android/signature.rb +5 -5
- data/lib/app_info/android/signatures/base.rb +41 -37
- data/lib/app_info/android/signatures/info.rb +135 -129
- data/lib/app_info/android/signatures/v1.rb +56 -52
- data/lib/app_info/android/signatures/v2.rb +114 -110
- data/lib/app_info/android/signatures/v3.rb +124 -120
- data/lib/app_info/android/signatures/v4.rb +13 -9
- data/lib/app_info/android.rb +181 -0
- data/lib/app_info/apk.rb +68 -100
- data/lib/app_info/apple.rb +192 -0
- data/lib/app_info/certificate.rb +14 -19
- data/lib/app_info/const.rb +48 -13
- data/lib/app_info/dsym.rb +6 -3
- data/lib/app_info/error.rb +1 -7
- data/lib/app_info/file.rb +30 -4
- data/lib/app_info/helper/file_size.rb +1 -1
- data/lib/app_info/info_plist.rb +54 -25
- data/lib/app_info/ipa.rb +39 -118
- data/lib/app_info/macos.rb +38 -94
- data/lib/app_info/mobile_provision.rb +49 -20
- data/lib/app_info/pe.rb +103 -7
- data/lib/app_info/png_uncrush.rb +19 -0
- data/lib/app_info/proguard.rb +21 -2
- data/lib/app_info/protobuf/manifest.rb +5 -1
- data/lib/app_info/version.rb +1 -1
- data/lib/app_info.rb +4 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8ca25ba9f5e54dc762996f1b7393593393b29adcbe0622131a905aa2f494141
|
4
|
+
data.tar.gz: c2839b1ac586397d1f76833fd9b4947722892ae584d8942ccb8e0d706f207210
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb08a20e764b4c8c35c7c03f43c3472b89cf0ebf34889080ef28c52e97c51b8700c91d09acd073cf21ece653c19beab34ecfc4b0477a5c534d23314bb503ff83
|
7
|
+
data.tar.gz: c7aa998b3224be94bbb20589fe57906356e93788739383d89703fafd1856f0eca948c33d046561460400590bf727fcd633f98edcfb321f11d740bbe00aa48aa2
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -9,21 +9,44 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
9
9
|
|
10
10
|
> List all changes before release a new version.
|
11
11
|
|
12
|
-
## [3.0.0.
|
12
|
+
## [3.0.0.beta3] (2023-04-05)
|
13
|
+
|
14
|
+
### Added
|
15
|
+
|
16
|
+
- Android parser `.icons` method add exclude param to filter icons.
|
17
|
+
|
18
|
+
### Changed
|
19
|
+
|
20
|
+
- Rename `.platform` to `.manufacturer`, rename `.opera_sytem` to `.platform` for all parsers.
|
21
|
+
|
22
|
+
### Fixed
|
23
|
+
|
24
|
+
- Minor fixes.
|
25
|
+
|
26
|
+
## [3.0.0.beta2] (2023-04-04)
|
27
|
+
|
28
|
+
### Changed
|
29
|
+
|
30
|
+
- Re-organize categories `.platform`, `.opera_sytem` and `.device` for all parsers. [#58](https://github.com/icyleaf/app_info/pull/58)
|
31
|
+
- Change ExportType values type to symbol both IPA and macOS parsers. [#58](https://github.com/icyleaf/app_info/pull/58)
|
32
|
+
|
33
|
+
## [3.0.0.beta1] (2023-04-04)
|
13
34
|
|
14
35
|
### Added
|
15
36
|
|
16
37
|
- New Windows PE format parser. [#47](https://github.com/icyleaf/app_info/pull/47)
|
17
38
|
- Android parser add v2, v3 scheme signature support. [#55](https://github.com/icyleaf/app_info/pull/55]
|
18
39
|
- dSYM parer accept multi dSYM target in a zip file. [#56](https://github.com/icyleaf/app_info/pull/56)
|
40
|
+
- Better document for yardoc.
|
19
41
|
|
20
42
|
### Changed
|
21
43
|
|
22
44
|
- Add `AppInfo::File` base class for all parsers.
|
23
45
|
- Add `AppInfo::Certifiate` X509 certificate wrapped and apply in Android/MobileProvision.
|
24
|
-
- Remove `AppInfo::MobileProvision::DeveloperCertificate` class, use `AppInfo::Certifiate` instead.
|
25
46
|
- Remove `.sign_version` method in Android parser.
|
47
|
+
- Rename `.file_type` to `.format` method in all parers and return a `AppInfo::Format` type.
|
26
48
|
- Remove duplice `AppInfo::AndroidDevice` class.
|
49
|
+
- Remove `AppInfo::MobileProvision::DeveloperCertificate` class, use `AppInfo::Certifiate` instead.
|
27
50
|
- Deprecate `.signs` and `.certifiates` methods in Android parser, use `.signatures` instead.
|
28
51
|
- Deprecate `.developer_certs` method in MobileProvision parser, use `.certificates` instead.
|
29
52
|
|
@@ -269,7 +292,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
269
292
|
|
270
293
|
- Updated dependency of CFPropertly list be a range between 2.3.4. (thanks @[cschroed](https://github.com/cschroed))
|
271
294
|
|
272
|
-
[Unreleased]: https://github.com/icyleaf/app-info/compare/
|
295
|
+
[Unreleased]: https://github.com/icyleaf/app-info/compare/v3.0.0.beta3..HEAD
|
296
|
+
[3.0.0.beta3]: https://github.com/icyleaf/app-info/compare/v3.0.0.beta2...v3.0.0.beta3
|
297
|
+
[3.0.0.beta2]: https://github.com/icyleaf/app-info/compare/v3.0.0.beta1...v3.0.0.beta2
|
298
|
+
[3.0.0.beta1]: https://github.com/icyleaf/app-info/compare/v2.8.5...v3.0.0.beta1
|
273
299
|
[2.8.5]: https://github.com/icyleaf/app-info/compare/v2.8.4...v2.8.5
|
274
300
|
[2.8.4]: https://github.com/icyleaf/app-info/compare/v2.8.3...v2.8.4
|
275
301
|
[2.8.3]: https://github.com/icyleaf/app-info/compare/v2.8.2...v2.8.3
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
#
|
1
|
+
# app-info
|
2
2
|
|
3
|
-
[](.github/workflows/ci.yml)
|
4
|
+
[](https://rubygems.org/gems/app-info)
|
4
5
|
[](https://github.com/icyleaf/app_info/actions/workflows/ci.yml)
|
5
|
-
[](LICENSE)
|
6
|
+
[](LICENSE)
|
7
7
|
|
8
8
|
Teardown tool for mobile app (ipa, apk and aab file), macOS app, dSYM.zip file and Windows PE file.
|
9
9
|
Analysis metedata like version, name, icon etc.
|
data/lib/app_info/aab.rb
CHANGED
@@ -1,53 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'app_info/protobuf/manifest'
|
4
|
-
require 'image_size'
|
5
|
-
require 'forwardable'
|
6
4
|
|
7
5
|
module AppInfo
|
8
6
|
# Parse APK file parser
|
9
|
-
class AAB <
|
10
|
-
include Helper::HumanFileSize
|
11
|
-
extend Forwardable
|
12
|
-
|
13
|
-
attr_reader :file
|
14
|
-
|
15
|
-
# APK Devices
|
16
|
-
module Device
|
17
|
-
PHONE = 'Phone'
|
18
|
-
TABLET = 'Tablet'
|
19
|
-
WATCH = 'Watch'
|
20
|
-
TV = 'Television'
|
21
|
-
AUTOMOTIVE = 'Automotive'
|
22
|
-
end
|
23
|
-
|
7
|
+
class AAB < Android
|
24
8
|
BASE_PATH = 'base'
|
25
9
|
BASE_MANIFEST = "#{BASE_PATH}/manifest/AndroidManifest.xml"
|
26
10
|
BASE_RESOURCES = "#{BASE_PATH}/resources.pb"
|
27
11
|
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
def size(human_size: false)
|
38
|
-
file_to_human_size(@file, human_size: human_size)
|
39
|
-
end
|
40
|
-
|
41
|
-
# @return [Symbol] {Format::AAB}
|
42
|
-
def file_type
|
43
|
-
Format::AAB
|
44
|
-
end
|
45
|
-
|
46
|
-
# @return [String] {Platform::ANDROID}
|
47
|
-
def platform
|
48
|
-
Platform::ANDROID
|
49
|
-
end
|
50
|
-
|
12
|
+
# @!method version_name
|
13
|
+
# @see Protobuf::Manifest#version_name
|
14
|
+
# @return [String]
|
15
|
+
# @!method deep_links
|
16
|
+
# @see Protobuf::Manifest#deep_links
|
17
|
+
# @return [String]
|
18
|
+
# @!method schemes
|
19
|
+
# @see Protobuf::Manifest#schemes
|
20
|
+
# @return [String]
|
51
21
|
def_delegators :manifest, :version_name, :deep_links, :schemes
|
52
22
|
|
53
23
|
alias release_version version_name
|
@@ -70,43 +40,6 @@ module AppInfo
|
|
70
40
|
manifest.label
|
71
41
|
end
|
72
42
|
|
73
|
-
# @return [String] {Device}
|
74
|
-
def device_type
|
75
|
-
if wear?
|
76
|
-
Device::WATCH
|
77
|
-
elsif tv?
|
78
|
-
Device::TV
|
79
|
-
elsif automotive?
|
80
|
-
Device::AUTOMOTIVE
|
81
|
-
else
|
82
|
-
Device::PHONE
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
# TODO: find a way to detect
|
87
|
-
# Found answer but not works: https://stackoverflow.com/questions/9279111/determine-if-the-device-is-a-smartphone-or-tablet
|
88
|
-
# def tablet?
|
89
|
-
# resource.first_package
|
90
|
-
# .entries('bool')
|
91
|
-
# .select{|e| e.name == 'isTablet' }
|
92
|
-
# .size >= 1
|
93
|
-
# end
|
94
|
-
|
95
|
-
# @return [Boolean]
|
96
|
-
def wear?
|
97
|
-
!!use_features&.include?('android.hardware.type.watch')
|
98
|
-
end
|
99
|
-
|
100
|
-
# @return [Boolean]
|
101
|
-
def tv?
|
102
|
-
!!use_features&.include?('android.software.leanback')
|
103
|
-
end
|
104
|
-
|
105
|
-
# @return [Boolean]
|
106
|
-
def automotive?
|
107
|
-
!!use_features&.include?('android.hardware.type.automotive')
|
108
|
-
end
|
109
|
-
|
110
43
|
# @return [String]
|
111
44
|
def min_sdk_version
|
112
45
|
manifest.uses_sdk.min_sdk_version
|
@@ -132,39 +65,21 @@ module AppInfo
|
|
132
65
|
@use_permissions ||= manifest&.uses_permission&.map(&:name)
|
133
66
|
end
|
134
67
|
|
68
|
+
# @return [Protobuf::Node]
|
135
69
|
def activities
|
136
70
|
@activities ||= manifest.activities
|
137
71
|
end
|
138
72
|
|
73
|
+
# @return [Protobuf::Node]
|
139
74
|
def services
|
140
75
|
@services ||= manifest.services
|
141
76
|
end
|
142
77
|
|
78
|
+
# @return [Protobuf::Node]
|
143
79
|
def components
|
144
80
|
@components ||= manifest.components.transform_values
|
145
81
|
end
|
146
82
|
|
147
|
-
# Return multi version certifiates of signatures
|
148
|
-
# @return [Array<Hash>] signatures
|
149
|
-
# @see AppInfo::Android::Signature.verify
|
150
|
-
def signatures
|
151
|
-
@signatures ||= Android::Signature.verify(self)
|
152
|
-
end
|
153
|
-
|
154
|
-
# Legacy v1 scheme signatures, it will remove soon.
|
155
|
-
# @deprecated Use {#signatures}
|
156
|
-
# @return [Array<OpenSSL::PKCS7, nil>] signatures
|
157
|
-
def signs
|
158
|
-
@signs ||= v1sign&.signatures || []
|
159
|
-
end
|
160
|
-
|
161
|
-
# Legacy v1 scheme certificates, it will remove soon.
|
162
|
-
# @deprecated Use {#signatures}
|
163
|
-
# @return [Array<OpenSSL::PKCS7, nil>] certificates
|
164
|
-
def certificates
|
165
|
-
@certificates ||= v1sign&.certificates || []
|
166
|
-
end
|
167
|
-
|
168
83
|
def each_file
|
169
84
|
zip.each do |entry|
|
170
85
|
next unless entry.file?
|
@@ -187,6 +102,7 @@ module AppInfo
|
|
187
102
|
entry
|
188
103
|
end
|
189
104
|
|
105
|
+
# @return [Protobuf::Manifest]
|
190
106
|
def manifest
|
191
107
|
io = zip.read(zip.find_entry(BASE_MANIFEST))
|
192
108
|
@manifest ||= Protobuf::Manifest.parse(io, resource)
|
@@ -198,19 +114,49 @@ module AppInfo
|
|
198
114
|
@resource ||= Protobuf::Resources.parse(io)
|
199
115
|
end
|
200
116
|
|
201
|
-
#
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
#
|
207
|
-
|
117
|
+
# Full icons metadata
|
118
|
+
# @example full icons
|
119
|
+
# aab.icons
|
120
|
+
# # => [
|
121
|
+
# # {
|
122
|
+
# # name: 'ic_launcher.png',
|
123
|
+
# # file: '/path/to/ic_launcher.webp',
|
124
|
+
# # dimensions: [29, 29]
|
125
|
+
# # },
|
126
|
+
# # {
|
127
|
+
# # name: 'ic_launcher.png',
|
128
|
+
# # file: '/path/to/ic_launcher.png',
|
129
|
+
# # dimensions: [120, 120]
|
130
|
+
# # },
|
131
|
+
# # {
|
132
|
+
# # name: 'ic_launcher.xml',
|
133
|
+
# # file: '/path/to/ic_launcher.xml',
|
134
|
+
# # dimensions: [nil, nil]
|
135
|
+
# # },
|
136
|
+
# # ]
|
137
|
+
# @example exclude xml icons
|
138
|
+
# aab.icons(filter: :xml)
|
139
|
+
# # => [
|
140
|
+
# # {
|
141
|
+
# # name: 'ic_launcher.png',
|
142
|
+
# # file: '/path/to/ic_launcher.webp',
|
143
|
+
# # dimensions: [29, 29]
|
144
|
+
# # },
|
145
|
+
# # {
|
146
|
+
# # name: 'ic_launcher.png',
|
147
|
+
# # file: '/path/to/ic_launcher.png',
|
148
|
+
# # dimensions: [120, 120]
|
149
|
+
# # }
|
150
|
+
# # ]
|
151
|
+
# @param [String, Symbol, Array<Symbol, Array>] filter filter file extension name
|
152
|
+
# @return [Array<Hash{Symbol => String, Array<Integer>}>] icons paths of icons
|
153
|
+
def icons(exclude: nil)
|
208
154
|
@icons ||= manifest.icons.each_with_object([]) do |res, obj|
|
209
155
|
path = res.value
|
210
156
|
filename = ::File.basename(path)
|
211
157
|
filepath = ::File.join(contents, ::File.dirname(path))
|
212
158
|
file = ::File.join(filepath, filename)
|
213
|
-
FileUtils.mkdir_p
|
159
|
+
FileUtils.mkdir_p(filepath)
|
214
160
|
|
215
161
|
binary_data = read_file(path)
|
216
162
|
::File.write(file, binary_data, encoding: Encoding::BINARY)
|
@@ -221,6 +167,8 @@ module AppInfo
|
|
221
167
|
dimensions: ImageSize.path(file).size
|
222
168
|
}
|
223
169
|
end
|
170
|
+
|
171
|
+
extract_icon(@icons, exclude: exclude)
|
224
172
|
end
|
225
173
|
|
226
174
|
def clear!
|
@@ -235,18 +183,13 @@ module AppInfo
|
|
235
183
|
@info = nil
|
236
184
|
end
|
237
185
|
|
238
|
-
|
239
|
-
|
186
|
+
# @return [Zip::File]
|
187
|
+
def zip
|
188
|
+
@zip ||= Zip::File.open(@file)
|
240
189
|
end
|
241
190
|
|
242
191
|
private
|
243
192
|
|
244
|
-
def v1sign
|
245
|
-
@v1sign ||= Android::Signature::V1.verify(self)
|
246
|
-
rescue Android::Signature::NotFoundError
|
247
|
-
nil
|
248
|
-
end
|
249
|
-
|
250
193
|
def xml_file?(file)
|
251
194
|
::File.extname(file) == '.xml'
|
252
195
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module AppInfo
|
4
|
-
|
4
|
+
class Android < File
|
5
5
|
# Android Signature
|
6
6
|
#
|
7
7
|
# Support digest and length:
|
@@ -15,10 +15,10 @@ module AppInfo
|
|
15
15
|
class NotFoundError < NotFoundError; end
|
16
16
|
|
17
17
|
module Version
|
18
|
-
V1
|
19
|
-
V2
|
20
|
-
V3
|
21
|
-
V4
|
18
|
+
V1 = 1
|
19
|
+
V2 = 2
|
20
|
+
V3 = 3
|
21
|
+
V4 = 4
|
22
22
|
end
|
23
23
|
|
24
24
|
# All registerd verions to verify
|
@@ -2,43 +2,47 @@
|
|
2
2
|
|
3
3
|
require 'app_info/android/signatures/info'
|
4
4
|
|
5
|
-
module AppInfo
|
6
|
-
class
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
5
|
+
module AppInfo
|
6
|
+
class Android < File
|
7
|
+
module Signature
|
8
|
+
class Base
|
9
|
+
def self.verify(parser)
|
10
|
+
instance = new(parser)
|
11
|
+
instance.verify
|
12
|
+
instance
|
13
|
+
end
|
14
|
+
|
15
|
+
DESCRIPTION = 'APK Signature Scheme'
|
16
|
+
|
17
|
+
attr_reader :verified
|
18
|
+
|
19
|
+
def initialize(parser)
|
20
|
+
@parser = parser
|
21
|
+
@verified = false
|
22
|
+
end
|
23
|
+
|
24
|
+
# @abstract Subclass and override {#verify} to implement
|
25
|
+
def verify
|
26
|
+
raise NotImplementedError, ".#{__method__} method implantation required in #{self.class}"
|
27
|
+
end
|
28
|
+
|
29
|
+
# @abstract Subclass and override {#certificates} to implement
|
30
|
+
def certificates
|
31
|
+
raise NotImplementedError, ".#{__method__} method implantation required in #{self.class}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def scheme
|
35
|
+
"v#{version}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def description
|
39
|
+
"#{DESCRIPTION} #{scheme}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def logger
|
43
|
+
@parser.logger
|
44
|
+
end
|
45
|
+
end
|
42
46
|
end
|
43
47
|
end
|
44
48
|
end
|