[Информационная безопасность, Разработка под Android, Реверс-инжиниринг] Пасхалка в APK-файлах: что такое Frosting
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Автор: Константин Молодяков
Структура файла — увлекательный мир со своими историей, тайнами и собственным цирком уродов, где выступают костыльные решения. Если в ней покопаться, можно найти много интересного.
Я наткнулся на одну особенность APK-файлов — специальную подпись с особым блоком метаданных, Frosting. Она позволяет однозначно определить, распространялся ли файл через Google Play. Эта подпись будет полезна для антивирусных вендоров и песочниц при анализе вредоносов. Кроме того, она может помочь криминалистам при поиске источника файла.
Информации об этом практически нет. Удалось найти только раздел Security metadata in early 2018 в Android Developers Blog и утилиту Avast, которая позволяет проверить данную подпись. Я решил изучить эту штуку, проверить корректность предположений разработчиков Avast о содержании Frosting-блока и поделиться своими выводами.
Frosting и APK Signing Block
Google использует специальную подпись APK-файлов при публикации приложений в Google Play. Эта подпись лежит в APK Signing Block, который находится перед центральной директорией ZIP-файла и после его основного содержимого:
Для идентификации APK Signing Block используется magic — APK Sig Block 42. Внутри блока подписи могут лежать другие блоки, предназначение которых определяется 4-байтовым ID. Получается расширение ZIP-формата с обратной совместимостью. Если интересно почитать подробнее или увидеть исходники, метод ApkSigningBlockUtils.findSignature описан тут.
Возьмем какой-нибудь файл, например 2124948e2b7897cd6fbbe5fbd655c26d. Посмотреть идентификаторы блоков, содержащихся в APK Signing Block, можно с помощью androguard:
from androguard.core.bytecodes import apk
apk_obj = apk.APK("2124948e2b7897cd6fbbe5fbd655c26d.apk")
apk_obj.parse_v2_v3_signature()
print(["0x%X" % key for key in apk_obj._v2_blocks.keys()])
['0x7109871A', '0x2146444E']
Существует несколько блоков с разными индентификаторами, которые официально описаны в документации:
- 0x7109871a (APK_SIGNATURE_SCHEME_V2_BLOCK_ID) — блок схемы подписи APK версии 2;
- 0xf05368c0 (APK_SIGNATURE_SCHEME_V3_BLOCK_ID) — блок схемы подписи APK версии 3.
Некоторые блоки можно найти в исходниках Android:
- 0x42726577 (VERITY_PADDING_BLOCK_ID) — блок, используемый для нулевого выравнивающего блока;
- 0x6dff800d (SOURCE_STAMP_BLOCK_ID) — относительно новый вид блоков.
Встречаются и другие блоки:
- 0x504b4453 (DEPENDENCY_INFO_BLOCK_ID) — блок, в котором, по всей видимости, содержится метаинформация о зависимостях, сохраняемая плагином Android Gradle для определения проблем с ними;
- 0x71777777 (APK_CHANNEL_BLOCK_ID) — блок китайской приблуды Walle для сборки, который содержит JSON с именем канала;
- 0xff3b5998 — нулевой блок, который встретился мне в файле — найти какую-либо информацию о нем я не смог;
- 0x2146444e — блок с необходимой метаинформацией от Google Play.
Frosting и «Play Маркет»
Вернемся к анализу рассматриваемого блока 0x2146444e. Для начала следует изучить внутренности приложения «Play Маркет».
.method public static b(ByteBuffer)ByteBuffer
.registers 2
00000000 invoke-static bny->a(ByteBuffer)aea, p0
00000006 move-result-object p0
00000008 const v0, 0x2146444E
0000000E invoke-virtual aea->a(I)Object, p0, v0
00000014 move-result-object p0
00000016 check-cast p0, bnx
0000001A if-eqz p0, :00000024
0000001E iget-object p0, p0, bnx->a:ByteBuffer
00000022 return-object p0
00000024 new-instance p0, SigBlockUtil$BlockNotFoundException
00000028 const-string v0, "Block entry id (go/apk-structure-glossary) "
"not present in APK Signing Block"
0000002C invoke-direct SigBlockUtil$BlockNotFoundException->
<init>(String)V, p0, v0
00000032 throw p0
.end method
Интересующий нас идентификатор обнаружен в двух местах. Смотрим глубже. Довольно быстро находим класс, отвечающий за разбор блока. Здесь же первый раз среди констант появляется название Frosting-блока:
public enum aysn implements avto {
UNKNOWN(0),
SUCCESS(81),
NO_FROSTING_BLOCK(1),
FROSTING_BLOCK_TOO_SHORT(2),
BAD_SIGNED_DATA_LENGTH_VARINT(3),
NON_POSITIVE_SIGNED_DATA_LENGTH(4),
SIGNED_DATA_LENGTH_TOO_LONG(5),
BAD_FROSTING_LENGTH_VARINT(6),
NON_POSITIVE_FROSTING_LENGTH(7),
FROSTING_LENGTH_BEYOND_SIGNED_DATA(8),
FROSTING_LENGTH_BEYOND_BLOCK(9),
MALFORMED_FROSTING(10),
// ...
INSTALLER_NO_ACCOUNT_WITH_MATCHING_REGION(74);
// ...
}
Я сравнил разные версии приложения «Play Маркет» и заметил следующее: код, отвечающий за разбор такого вида подписи, появился примерно в январе 2018 года вместе с выходом версии 8.6.X. Блок с метаданными Frosting существовал и раньше, но именно в этот период он принял тот вид, в котором существует сейчас.
Для разбора данных нам понадобится примитив чтения 4-байтового числа. Схема представляет собой стандартный varint без каких-либо ухищрений с отрицательными числами:
private static int read_int32(ByteBuffer arg2) {
int v0 = arg2.get();
if(v0 >= 0) {
return v0;
}
int v0_1 = v0 & 0x7F;
int v1 = arg2.get();
if(v1 >= 0) {
return v1 << 7 | v0_1;
}
v0_1 |= (v1 & 0x7F) << 7;
int v1_1 = arg2.get();
if(v1_1 >= 0) {
return v1_1 << 14 | v0_1;
}
v0_1 |= (v1_1 & 0x7F) << 14;
int v1_2 = arg2.get();
if(v1_2 >= 0) {
return v1_2 << 21 | v0_1;
}
int v2 = arg2.get();
int v0_2 = v0_1 | (v1_2 & 0x7F) << 21 | v2 << 28;
if(v2 >= 0) {
return v0_2;
}
throw new IllegalArgumentException();
}
Функция разбора блока довольно большая, хоть и устроена просто. Она позволяет разобраться в самой структуре данных:
{
var_int32 size_signed_data,
var_int32 size_frosting,
byte frosting[size_frosting],
var_int32 size_validation_sequence,
array validation_sequence {
var_int32 size_validation_data,
var_int32 validation_strategy,
var_int32 signing_key_index,
byte sha256[0x20]},
var_int32 size_signature_sequence,
array signature_sequence {
var_int32 size_signature,
byte signature[size_signature]}}
Для проверки подписи используются хеш и ключ первого поля из последовательности validation_sequence, у которого validation_strategy равен нулю. Сама подпись забирается из последовательности signature_sequence с таким же порядковым номером, как у записи из validation_sequence. На рисунке ниже представлен поясняющий псевдокод:
def get_signing_data(frosting_block):
for i, validation in enumerate(frosting_block.validation_sequence):
if validation.validation_strategy != 0:
continue
return (
validation.sha256, validation.signing_key_index,
frosting_block.signature_sequence[i].signature)
raise AttributeError()
Значение signing_key_index указывает на индекс в массиве finsky.peer_app_sharing_api.frosting_public_keys, который определен следующим образом и пока содержит только один ключ:
gyd.iH = arip.a(
"finsky.peer_app_sharing_api.min_tos_version", v8);
gyd.iI = arip.a(
"finsky.peer_app_sharing_api.frosting_public_keys",
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZH2+1+E07dnErAD3L6BbTnaohU0bbXriNlJI7VxJU+LjdSwPyXR5pomARAMoyPkMksLz/gitUPtFuJoPL2ziEw==");
gyd.iJ = arip.a(
"finsky.peer_app_sharing_api.startup_package_blacklist",
"com.android.vending,com.google.android.gms,com.android.providers.downloads");
gyd.iK = arip.a(
"finsky.frosting_only_update_time_ms", Long.valueOf(TimeUnit.DAYS.toMillis(30L)));
Подписываются данные размером size_signed_data, начиная с переменной size_frosting, алгоритмом ECDSA_SHA256. При этом подписываемые данные содержат SHA-256 от данных файла:
1) данные от начала файла до блока подписи;
2) данные от central directory до конца end of central directory, с заменой в end of central directory значения поля offset of start of central with respect to the starting disk number на оффсет блока подписи.
Если есть блок подписи схемы версии 2, то он вставляется между данными из пунктов 1 и 2 с добавлением APK_SIGNATURE_SCHEME_V2_BLOCK_ID перед ним.
Функция, вычисляющая хеш в приложении «Play Маркет», выглядит так:
private static byte[] get_frosting_hash(RandomAccessFile f_apk,
long offset_signing_block, ByteBuffer signature_scheme_v2_block,
long offset_zip_central_dir, long size_from_central_dir_to_end_central_dir,
ByteBuffer end_central_dir) {
MessageDigest v0;
try {
v0 = MessageDigest.getInstance("SHA-256");
}
catch(NoSuchAlgorithmException unused_ex) {
throw new FrostingUtil.FailureException(aysn.N); // NO_SHA_256_ALGORITHM
}
mcc.update_digest(v0, f_apk, 0L, offset_signing_block);
if(signature_scheme_v2_block != null) {
v0.update(mcc.a);
v0.update(signature_scheme_v2_block);
}
mcc.update_digest(v0, f_apk, offset_zip_central_dir,
size_from_central_dir_to_end_central_dir);
bnz.a(end_central_dir, offset_signing_block);
end_central_dir.position(end_central_dir.position());
end_central_dir.limit(end_central_dir.limit());
v0.update(end_central_dir);
return v0.digest();
}
Frosting и ProtoBuf
Этой информации достаточно, чтобы проверить валидность подписи. Но, увы, мне так и не удалось узнать, что скрывается в данных Frosting-блока. У меня получилось лишь определить, что данные имеют формат ProtoBuf и могут сильно отличаться по размеру и наличию полей в зависимости от файла.
Обычно декодированные без схемы данные выглядят так (4b005c9e9ea0731330a757fcf3abeb6e):
cat ./ru.sberbankmobile_11.1.0_2020072413.protobuf | ./protodec -p
{
"1:0:varint": 2,
"2:1:varint": 0,
"3:2:varint": 1,
"4:3:varint": 1603811598348,
"5:4:embedded": {
"8:0:embedded": {
"1:0:embedded": {
"1:0:varint": 21
},
"6:1:varint": 3
},
"9:1:embedded": {
"1:0:embedded": {
"1:0:varint": 2020072413,
"4:1:varint": 3
},
"2:1:embedded": {
"1:0:varint": 2020072414,
"4:1:varint": 5
}
},
"10:2:embedded": {
"1:0:bytes": [
255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 7,
0, 40, 0, 16, 0, 0, 80, 5, 16, 64, 0, 56
]
}
},
"8:5:varint": 1,
"9:6:varint": 2
}
Но встречаются экземпляры (471c589acc800135eb318057c43a8068), содержащие под пятьсот полей.
Скрытый текст
SPL
{
"1:0:varint": 1,
"2:1:varint": 1,
"3:2:varint": 1,
"4:3:varint": 1593452906098,
"5:4:embedded": {
"7:0:embedded": {
"1:0:varint": 1,
"2:1:varint": 1
},
"8:1:embedded": {
"1:0:embedded": {
"1:0:varint": 16
},
"6:1:varint": 3,
"6:2:varint": 2
},
"9:2:embedded": {
"1:0:embedded": {
"1:0:varint": 2021505050,
"4:1:varint": 3,
"4:2:varint": 2
}
},
"10:3:embedded": {
"1:0:bytes": [
221, 255, 227, 239, 247, 127, 255, 191, 239, 191, 255, 255, 255, 255,
247, 255, 255, 0, 0, 8, 0, 16, 0, 0, 16, 5, 16, 64, 0, 32],
"3:1:embedded": {
"1:0:bytes": [
137, 204, 247, 126, 103, 225, 96, 185, 11, 67, 239, 227, 193, 247,
248, 68, 8, 2, 37, 20, 197, 120, 249, 112, 81, 240, 131, 124, 231,
64, 45, 116, 60, 212, 47, 211, 175, 84, 218, 140, 61, 140, 116, 14,
9, 38, 64, 21, 87, 196, 128, 228, 201, 237, 248, 67, 96, 229, 131,
79, 217, 94, 223, 232, 73, 222, 177, 132, 162, 191, 144, 84, 83, 77,
253, 70, 207, 180, 53, 131, 75, 2, 111, 84, 212, 4, 33, 100, 160, 78,
253, 54, 63, 120, 67, 18, 92, 196, 101, 214, 245, 149, 11, 217, 102,
93, 243, 158, 87, 133, 135, 85, 179, 175, 58, 242, 217, 52, 37, 128,
81, 76, 10, 113, 96, 205, 150, 253, 12, 105, 74, 1, 25, 146, 160,
126, 93, 196, 179, 143, 145, 106, 135, 242, 136, 186, 96, 164, 61,
11, 56, 229, 113, 104, 68, 162, 179, 105, 25, 125, 27, 43, 162, 94,
238, 237, 75, 89, 0, 112, 98, 49, 129, 49, 208, 89, 163, 66, 174,
119, 27, 135, 109, 105, 204],
"2:1:varint": 13
}
},
"12:4:embedded": {
"1:0:embedded": {
"5:0:varint": 21
},
"2:1:embedded": {
"1:0:varint": 0,
"2:1:embedded": {
"1:0:bytes": [
41, 93, 201, 211, 27, 15, 203, 207, 160, 84, 10, 4, 65, 194, 92,
146, 191, 221, 207, 134, 150, 216, 77, 234, 223, 53, 187, 49, 207,
136, 84, 82]
},
"3:2:embedded": {
"1:0:bytes": [
80, 168, 41, 12, 177, 59, 101, 235, 150, 116, 174, 248, 213, 250,
72, 228, 35, 56, 11, 184, 197, 36, 206, 168, 225, 19, 221, 82, 213,
106, 206, 248],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 120
}
}
},
"3:3:embedded": {
"1:0:bytes": [
59, 234, 46, 139, 75, 154, 134, 17, 78, 53, 232, 182, 38, 151, 51,
63, 38, 71, 1, 189, 112, 252, 157, 201, 177, 179, 163, 159, 188,
22, 181, 221],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 160
}
}
},
"3:4:embedded": {
"1:0:bytes": [
202, 210, 137, 99, 138, 209, 74, 181, 118, 190, 8, 18, 68, 86, 137,
151, 223, 217, 226, 19, 248, 109, 240, 206, 216, 31, 232, 18, 87,
167, 17, 251],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 240
}
}
},
"3:5:embedded": {
"1:0:bytes": [
191, 119, 224, 30, 167, 161, 4, 135, 44, 155, 92, 208, 26, 168,
120, 198, 195, 65, 125, 110, 58, 168, 92, 171, 56, 41, 131, 172,
176, 171, 78, 223],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 320
}
}
},
"3:6:embedded": {
"1:0:bytes": [
246, 143, 161, 148, 32, 191, 55, 116, 35, 71, 23, 31, 83, 35, 218,
162, 116, 40, 111, 227, 122, 3, 151, 57, 45, 54, 156, 94, 171, 146,
185, 175],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 480
}
}
},
"3:7:embedded": {
"1:0:bytes": [
5, 217, 66, 174, 71, 16, 113, 53, 143, 20, 129, 142, 83, 16, 107,
217, 105, 193, 85, 234, 236, 46, 45, 168, 7, 17, 71, 171, 18, 239,
131, 23],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 640
}
}
},
"3:8:embedded": {
"1:0:bytes": [
134, 163, 146, 36, 137, 172, 95, 238, 205, 214, 71, 99, 209, 190,
16, 59, 205, 59, 201, 2, 146, 43, 117, 131, 131, 218, 64, 251, 108,
217, 37, 141],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 213
}
}
},
"3:9:embedded": {
"1:0:bytes": [
186, 26, 67, 178, 23, 52, 226, 60, 224, 196, 139, 119, 120, 246,
20, 110, 238, 52, 171, 50, 107, 40, 225, 89, 86, 93, 183, 41, 195,
150, 1, 234],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 7
}
}
},
"3:10:embedded": {
"1:0:bytes": [
58, 32, 81, 63, 166, 190, 81, 128, 63, 140, 253, 185, 32, 231, 65,
64, 145, 144, 158, 160, 114, 51, 147, 56, 145, 78, 131, 124, 155,
244, 135, 29],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 47
}
}
},
"3:11:embedded": {
"1:0:bytes": [
208, 138, 65, 103, 12, 44, 60, 179, 81, 117, 125, 125, 32, 171, 58,
255, 61, 9, 184, 59, 17, 165, 38, 250, 2, 126, 131, 206, 204, 106,
121, 122],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 172
}
}
},
"3:12:embedded": {
"1:0:bytes": [
31, 249, 92, 139, 0, 179, 127, 14, 76, 18, 118, 130, 116, 231, 107,
180, 104, 172, 152, 12, 126, 119, 18, 158, 162, 145, 126, 39, 92,
184, 71, 29],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 148
}
}
},
"3:13:embedded": {
"1:0:bytes": [
215, 70, 132, 253, 56, 142, 20, 226, 80, 118, 251, 124, 96, 236,
23, 198, 249, 38, 100, 213, 16, 125, 232, 138, 142, 127, 236, 127,
185, 25, 114, 190],
"2:1:embedded": {
"7:0:embedded": {
"1:0:string": "IW"
}
}
},
"3:14:embedded": {
"1:0:bytes": [
87, 151, 187, 223, 182, 225, 35, 238, 176, 44, 82, 149, 122, 132,
165, 219, 225, 29, 73, 188, 200, 85, 139, 102, 160, 115, 38, 107,
248, 236, 198, 127],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 153
}
}
},
"3:15:embedded": {
"1:0:bytes": [
41, 181, 59, 170, 70, 192, 248, 215, 162, 173, 176, 230, 98, 201,
85, 97, 46, 213, 204, 180, 97, 160, 104, 131, 96, 116, 115, 239,
75, 4, 152, 127],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 171
}
}
},
"3:16:embedded": {
"1:0:bytes": [
66, 31, 252, 95, 240, 235, 159, 130, 37, 247, 203, 210, 165, 40, 2,
37, 157, 33, 78, 114, 102, 214, 7, 15, 128, 103, 91, 63, 138, 113,
125, 119],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 3
}
}
},
"3:17:embedded": {
"1:0:bytes": [
38, 209, 2, 170, 201, 97, 61, 107, 59, 193, 146, 187, 51, 241, 22,
232, 147, 33, 169, 77, 71, 109, 213, 77, 47, 247, 160, 158, 111,
206, 156, 243],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 184
}
}
},
"3:18:embedded": {
"1:0:bytes": [
195, 229, 130, 114, 114, 109, 5, 1, 40, 156, 47, 239, 0, 169, 239,
211, 98, 138, 113, 182, 234, 23, 214, 125, 49, 107, 142, 168, 175,
253, 223, 124],
"2:1:embedded": {
"7:0:embedded": {
"1:0:string": "IN"
}
}
},
"3:19:embedded": {
"1:0:bytes": [
53, 252, 95, 223, 136, 114, 75, 101, 122, 251, 97, 128, 49, 203,
183, 223, 33, 50, 56, 209, 198, 238, 135, 15, 85, 128, 142, 242,
221, 17, 110, 219],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 77
}
}
},
"3:20:embedded": {
"1:0:bytes": [
31, 231, 69, 193, 155, 115, 41, 39, 125, 98, 164, 106, 101, 40, 15,
168, 63, 161, 40, 158, 119, 56, 170, 131, 97, 143, 204, 117, 219,
228, 115, 58],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 51
}
}
},
"3:21:embedded": {
"1:0:bytes": [
58, 114, 14, 110, 167, 28, 66, 253, 106, 5, 106, 130, 219, 199,
234, 73, 126, 0, 63, 102, 153, 172, 52, 224, 22, 145, 84, 42, 74,
216, 210, 58],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 154
}
}
},
"3:22:embedded": {
"1:0:bytes": [
3, 198, 55, 89, 63, 195, 67, 117, 23, 19, 208, 6, 64, 61, 55, 60,
106, 216, 150, 133, 175, 51, 211, 254, 106, 150, 250, 240, 10, 49,
163, 47],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 84
}
}
},
"3:23:embedded": {
"1:0:bytes": [
43, 113, 17, 252, 89, 90, 79, 80, 158, 159, 123, 186, 207, 137, 84,
186, 68, 155, 105, 111, 176, 215, 70, 107, 51, 237, 73, 155, 242,
122, 10, 46],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 325
}
}
},
"3:24:embedded": {
"1:0:bytes": [
163, 118, 101, 102, 1, 115, 201, 144, 237, 239, 117, 79, 163, 127,
173, 149, 33, 211, 90, 111, 82, 50, 146, 101, 80, 30, 22, 112,
153, 164, 19, 150],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 258
}
}
},
"3:25:embedded": {
"1:0:bytes": [
11, 171, 219, 11, 212, 240, 116, 80, 201, 168, 63, 75, 188, 168,
236, 220, 108, 157, 49, 226, 17, 158, 105, 188, 44, 180, 67, 196,
36, 31, 46, 149],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 161
}
}
},
"3:26:embedded": {
"1:0:bytes": [
233, 52, 162, 8, 5, 80, 139, 147, 172, 124, 252, 124, 75, 146, 182,
53, 109, 29, 220, 18, 52, 120, 53, 83, 255, 138, 143, 39, 194, 61,
163, 196],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 46
}
}
},
"3:27:embedded": {
"1:0:bytes": [
82, 61, 18, 192, 210, 218, 157, 38, 65, 86, 39, 30, 138, 32, 248,
114, 10, 148, 210, 251, 130, 23, 54, 116, 104, 206, 141, 102, 169,
191, 5, 233],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 38
}
}
},
"3:28:embedded": {
"1:0:bytes": [
47, 251, 190, 153, 104, 136, 52, 169, 146, 57, 29, 6, 153, 167, 3,
209, 5, 30, 100, 215, 240, 47, 96, 103, 114, 164, 131, 197, 69,
112, 4, 86],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 129
}
}
},
"3:29:embedded": {
"1:0:bytes": [
93, 192, 14, 10, 50, 59, 229, 14, 140, 132, 196, 12, 219, 149, 215,
224, 125, 6, 139, 61, 6, 144, 255, 96, 5, 37, 216, 91, 137, 135,
41, 24],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 25
}
}
},
"3:30:embedded": {
"1:0:bytes": [
10, 2, 142, 220, 179, 122, 72, 30, 24, 127, 28, 65, 31, 28, 73,
126, 198, 238, 62, 156, 228, 87, 163, 9, 38, 116, 106, 48, 25,
152, 159, 179],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 126
}
}
},
"3:31:embedded": {
"1:0:bytes": [
81, 12, 199, 94, 25, 57, 186, 111, 6, 142, 64, 231, 47, 149, 116,
21, 53, 34, 89, 104, 13, 47, 184, 121, 38, 4, 206, 64, 179, 247,
20, 137],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 156
}
}
},
"3:32:embedded": {
"1:0:bytes": [
171, 95, 184, 6, 120, 203, 22, 123, 134, 45, 181, 225, 90, 186,
233, 210, 8, 55, 43, 48, 169, 47, 10, 200, 161, 216, 118, 98, 61,
215, 124, 135],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 158
}
}
},
"3:33:embedded": {
"1:0:bytes": [
198, 24, 206, 30, 88, 136, 6, 128, 184, 53, 150, 247, 25, 79, 56,
60, 81, 143, 13, 123, 107, 35, 86, 162, 122, 7, 216, 27, 27, 249,
19, 47],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 63
}
}
},
"3:34:embedded": {
"1:0:bytes": [
230, 93, 108, 31, 194, 183, 82, 253, 244, 34, 6, 1, 7, 69, 80, 147,
131, 89, 158, 29, 236, 115, 92, 196, 44, 178, 254, 238, 121, 246,
113, 68],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 104
}
}
},
"3:35:embedded": {
"1:0:bytes": [
147, 204, 39, 33, 249, 108, 184, 249, 48, 14, 165, 120, 66, 9, 137,
134, 5, 48, 106, 48, 105, 140, 144, 159, 125, 179, 124, 71, 158,
117, 131, 210],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 19
}
}
},
"3:36:embedded": {
"1:0:bytes": [
89, 255, 33, 10, 191, 177, 183, 189, 245, 158, 109, 205, 126, 163,
104, 71, 57, 35, 124, 14, 130, 83, 188, 213, 129, 96, 249, 122, 39,
106, 120, 195],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 80
}
}
},
"3:37:embedded": {
"1:0:bytes": [
105, 92, 221, 66, 185, 181, 94, 19, 30, 129, 85, 145, 196, 110, 14,
125, 216, 251, 11, 186, 138, 194, 135, 243, 1, 172, 32, 128, 159,
113, 84, 87],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 106
}
}
},
"3:38:embedded": {
"1:0:bytes": [
157, 183, 189, 153, 219, 24, 43, 100, 235, 0, 132, 119, 215, 108,
236, 153, 22, 241, 252, 211, 231, 116, 33, 113, 123, 237, 138, 202,
213, 153, 43, 88],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 123
}
}
},
"3:39:embedded": {
"1:0:bytes": [
146, 229, 59, 43, 145, 105, 186, 201, 142, 14, 158, 90, 5, 28, 230,
197, 134, 18, 13, 219, 74, 209, 84, 214, 210, 54, 70, 1, 56, 31,
218, 54],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 58
}
}
},
"3:40:embedded": {
"1:0:bytes": [
220, 242, 61, 79, 217, 248, 85, 208, 85, 163, 104, 176, 88, 2, 114,
108, 131, 202, 204, 53, 110, 75, 239, 56, 136, 67, 248, 247, 12,
63, 191, 12],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 175
}
}
},
"3:41:embedded": {
"1:0:bytes": [
71, 68, 176, 15, 211, 98, 59, 27, 187, 227, 14, 91, 53, 120, 129,
50, 108, 107, 103, 66, 252, 217, 178, 77, 184, 147, 91, 90, 19,
111, 128, 53],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 134
}
}
},
"3:42:embedded": {
"1:0:bytes": [
201, 51, 220, 118, 187, 125, 87, 7, 246, 185, 155, 52, 220, 28, 12,
90, 48, 123, 202, 135, 233, 18, 3, 137, 10, 222, 223, 206, 111,
196, 255, 235],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 78
}
}
},
"3:43:embedded": {
"1:0:bytes": [
144, 123, 192, 106, 90, 212, 71, 96, 188, 5, 46, 223, 100, 12, 58,
99, 141, 127, 17, 14, 181, 44, 129, 224, 57, 134, 157, 34, 245, 78,
63, 60],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 130
}
}
},
"3:44:embedded": {
"1:0:bytes": [
21, 33, 78, 136, 74, 131, 86, 48, 170, 99, 67, 146, 12, 42, 119,
249, 70, 198, 221, 127, 241, 175, 42, 0, 12, 66, 71, 172, 59, 17,
27, 228],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 56
}
}
},
"3:45:embedded": {
"1:0:bytes": [
45, 178, 69, 5, 175, 52, 44, 90, 190, 94, 100, 180, 238, 153, 189,
58, 248, 181, 189, 134, 151, 53, 68, 244, 110, 252, 95, 156, 34,
248, 195, 141],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 90
}
}
},
"3:46:embedded": {
"1:0:bytes": [
91, 22, 185, 64, 72, 46, 38, 48, 20, 244, 241, 114, 1, 64, 97, 227,
136, 54, 169, 201, 133, 11, 182, 88, 154, 1, 142, 138, 24, 112,
166, 16],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 168
}
}
},
"3:47:embedded": {
"1:0:bytes": [
27, 146, 39, 199, 46, 197, 241, 106, 223, 55, 129, 191, 176, 123,
232, 151, 44, 180, 31, 142, 137, 201, 21, 52, 94, 201, 111, 170,
169, 93, 55, 131],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 76
}
}
},
"3:48:embedded": {
"1:0:bytes": [
193, 124, 22, 3, 213, 34, 101, 149, 246, 22, 8, 15, 68, 75, 165,
76, 38, 150, 247, 77, 2, 140, 154, 249, 2, 205, 73, 232, 130, 104,
69, 159],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 66
}
}
},
"3:49:embedded": {
"1:0:bytes": [
5, 193, 68, 1, 180, 40, 46, 163, 192, 112, 174, 29, 81, 223, 190,
244, 3, 142, 55, 211, 8, 2, 192, 194, 30, 20, 55, 42, 41, 68, 125,
127],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 136
}
}
},
"3:50:embedded": {
"1:0:bytes": [
83, 24, 100, 126, 8, 186, 138, 33, 95, 127, 89, 36, 2, 106, 137,
183, 242, 92, 104, 95, 122, 198, 162, 7, 255, 251, 123, 96, 225,
149, 63, 111],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 29
}
}
},
"3:51:embedded": {
"1:0:bytes": [
194, 142, 59, 4, 54, 96, 70, 2, 123, 91, 9, 252, 170, 235, 182, 98,
37, 143, 10, 210, 186, 173, 103, 165, 149, 47, 171, 59, 201, 209,
250, 66],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 107
}
}
},
"3:52:embedded": {
"1:0:bytes": [
99, 76, 68, 203, 167, 245, 211, 142, 143, 66, 189, 190, 254, 178,
37, 12, 61, 195, 104, 178, 165, 186, 113, 253, 215, 1, 169, 54,
129, 175, 212, 70],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 35
}
}
},
"3:53:embedded": {
"1:0:bytes": [
92, 240, 11, 68, 247, 15, 103, 182, 210, 65, 243, 114, 153, 230,
135, 241, 160, 60, 31, 140, 166, 85, 107, 163, 252, 119, 167, 35,
195, 207, 141, 18],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 20
}
}
},
"3:54:embedded": {
"1:0:bytes": [
52, 163, 30, 105, 147, 104, 203, 234, 85, 78, 118, 91, 238, 243,
81, 81, 183, 127, 166, 173, 2, 33, 111, 160, 93, 35, 4, 128, 97,
231, 134, 223],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 40
}
}
},
"3:55:embedded": {
"1:0:bytes": [
15, 45, 48, 189, 170, 219, 22, 126, 243, 217, 200, 106, 165, 165,
120, 108, 150, 111, 105, 150, 85, 8, 120, 155, 210, 148, 32, 198,
145, 49, 115, 16],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 26
}
}
},
"3:56:embedded": {
"1:0:bytes": [
27, 250, 155, 159, 74, 227, 46, 27, 185, 4, 150, 8, 184, 21, 240,
149, 45, 244, 81, 252, 85, 159, 50, 201, 247, 73, 42, 60, 127, 194,
238, 197],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 36
}
}
},
"3:57:embedded": {
"1:0:bytes": [
108, 3, 162, 113, 54, 72, 115, 18, 228, 40, 151, 67, 169, 226, 153,
58, 138, 252, 59, 67, 200, 53, 128, 160, 233, 148, 198, 100, 2,
236, 64, 76],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 127
}
}
},
"3:58:embedded": {
"1:0:bytes": [
49, 49, 177, 65, 227, 61, 198, 32, 171, 82, 125, 100, 152, 38, 31,
134, 206, 214, 41, 7, 221, 160, 238, 165, 79, 21, 214, 112, 178,
61, 11, 9],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 118
}
}
},
"3:59:embedded": {
"1:0:bytes": [
20, 105, 162, 168, 235, 1, 24, 192, 39, 86, 5, 217, 99, 35, 205,
139, 169, 93, 95, 58, 226, 208, 58, 100, 127, 228, 120, 31, 18, 41,
125, 188],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 24
}
}
},
"3:60:embedded": {
"1:0:bytes": [
34, 182, 106, 248, 174, 109, 85, 82, 233, 185, 158, 189, 109, 180,
122, 16, 147, 191, 174, 75, 237, 181, 28, 126, 154, 187, 117, 74,
222, 183, 40, 42],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 140
}
}
},
"3:61:embedded": {
"1:0:bytes": [
26, 231, 159, 209, 255, 47, 66, 73, 25, 159, 150, 146, 159, 24,
180, 147, 187, 127, 158, 136, 140, 26, 16, 163, 73, 22, 192, 248,
72, 201, 123, 70],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 160
}
}
},
"3:62:embedded": {
"1:0:bytes": [
203, 229, 192, 110, 98, 83, 18, 72, 171, 75, 44, 16, 145, 234, 53,
21, 92, 92, 252, 180, 147, 252, 134, 164, 131, 200, 84, 216, 173,
57, 215, 64],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 65
}
}
},
"3:63:embedded": {
"1:0:bytes": [
27, 37, 29, 129, 135, 60, 21, 21, 130, 47, 246, 84, 230, 29, 106,
8, 164, 126, 104, 33, 221, 10, 59, 198, 65, 59, 120, 175, 206,
115, 159, 192],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 150
}
}
},
"3:64:embedded": {
"1:0:bytes": [
247, 70, 240, 58, 235, 170, 216, 77, 82, 133, 127, 229, 69, 233,
41, 152, 29, 26, 140, 211, 60, 199, 111, 14, 228, 194, 135, 49,
207, 62, 100, 88],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 3
}
}
},
"3:65:embedded": {
"1:0:embedded": {
"3:0:bytes": [
240, 189, 141, 59, 178, 229, 21, 207, 150, 181, 18, 214, 123,
229, 94, 213, 47, 55, 0, 35, 94, 176, 10, 239, 63, 91, 177, 203,
181, 232]
},
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 2
}
}
}
},
"3:2:embedded": {
"1:0:varint": 1,
"2:1:embedded": {
"1:0:bytes": [
33, 255, 48, 173, 71, 120, 45, 62, 197, 131, 213, 202, 76, 94, 249,
217, 35, 187, 218, 99, 4, 123, 252, 140, 225, 146, 188, 168, 168,
162, 182, 43]
},
"3:2:embedded": {
"1:0:bytes": [
25, 141, 201, 30, 174, 20, 216, 191, 35, 48, 111, 202, 181, 109,
38, 200, 22, 81, 86, 189, 190, 86, 13, 133, 64, 168, 191, 133, 34,
39, 191, 224],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 3
}
}
},
"3:3:embedded": {
"1:0:bytes": [
71, 158, 85, 141, 109, 205, 49, 21, 217, 217, 209, 39, 252, 123,
76, 99, 122, 134, 75, 8, 32, 224, 96, 181, 34, 239, 108, 110, 14,
13, 46, 205],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 2
}
}
}
},
"3:3:embedded": {
"1:0:varint": 0,
"2:1:embedded": {
"1:0:bytes": [
203, 190, 37, 85, 163, 233, 86, 189, 68, 5, 138, 164, 64, 165, 54,
146, 237, 162, 128, 49, 148, 179, 51, 34, 217, 7, 38, 108, 182,
197, 160, 179]
}
},
"3:4:embedded": {
"1:0:varint": 0,
"2:1:embedded": {
"1:0:bytes": [
163, 159, 42, 53, 128, 115, 90, 161, 149, 19, 157, 15, 58, 113,
122, 238, 204, 104, 91, 216, 78, 131, 30, 240, 110, 166, 106, 159,
237, 125, 147, 82]
},
"3:2:embedded": {
"1:0:bytes": [
57, 32, 198, 203, 112, 159, 189, 236, 244, 113, 104, 205, 165,
135, 237, 217, 163, 184, 202, 45, 241, 164, 164, 78, 112, 12, 177,
124, 204, 213, 16, 78],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 3
}
}
},
"3:3:embedded": {
"1:0:bytes": [
220, 184, 103, 130, 108, 220, 83, 140, 36, 238, 139, 5, 167, 253,
252, 136, 76, 43, 72, 36, 245, 92, 47, 147, 40, 134, 117, 179, 88,
9, 164, 70],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 2
}
}
}
},
"3:5:embedded": {
"1:0:varint": 1,
"2:1:embedded": {
"1:0:bytes": [
240, 142, 243, 236, 188, 6, 32, 37, 148, 220, 19, 135, 176, 7, 175,
172, 234, 124, 152, 61, 115, 11, 68, 50, 219, 32, 182, 146, 2, 41,
153, 192]
},
"3:2:embedded": {
"1:0:bytes": [
245, 12, 255, 55, 29, 151, 184, 242, 250, 247, 191, 244, 52, 251,
172, 66, 40, 242, 47, 67, 168, 136, 224, 201, 229, 16, 64, 4, 36,
207, 164, 97],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 3
}
}
},
"3:3:embedded": {
"1:0:bytes": [
98, 200, 36, 229, 239, 75, 96, 35, 195, 26, 180, 253, 4, 232, 178,
167, 173, 163, 171, 110, 154, 60, 20, 229, 82, 52, 201, 194, 199,
137, 188, 237],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 2
}
}
}
},
"3:6:embedded": {
"1:0:varint": 1,
"2:1:embedded": {
"1:0:bytes": [
36, 1, 15, 223, 76, 25, 153, 9, 204, 90, 139, 114, 200, 122, 201,
226, 179, 79, 135, 58, 82, 134, 136, 184, 34, 249, 131, 132, 127,
38, 46, 245]
},
"3:2:embedded": {
"1:0:bytes": [
110, 242, 238, 199, 145, 159, 168, 178, 187, 136, 71, 7, 156, 155,
102, 157, 218, 30, 147, 63, 91, 89, 147, 79, 29, 133, 10, 154, 77,
107, 15, 23],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 3
}
}
},
"3:3:embedded": {
"1:0:bytes": [
193, 203, 71, 244, 30, 18, 158, 188, 15, 77, 73, 13, 22, 120, 82,
107, 224, 130, 68, 135, 58, 123, 59, 135, 29, 86, 232, 139, 54, 74,
77, 121],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 2
}
}
}
},
"3:7:embedded": {
"1:0:varint": 0,
"2:1:embedded": {
"1:0:embedded": {
"2:0:varint": 495613890054,
"192224:1:float32": 4.882061335059751e-12,
"13:2:float64": -1.0035307849984653e+45,
"14:3:float64": -9.42824039531738e+194
}
},
"3:2:embedded": {
"1:0:bytes": [
176, 193, 111, 217, 103, 210, 40, 38, 174, 253, 210, 197, 138, 118,
79, 56, 223, 186, 161, 214, 205, 215, 175, 9, 245, 199, 58, 188,
87, 17, 112, 187],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 3
}
}
},
"3:3:embedded": {
"1:0:bytes": [
233, 74, 153, 41, 23, 225, 3, 244, 202, 119, 170, 143, 9, 6, 210,
63, 125, 169, 131, 143, 182, 92, 221, 250, 202, 54, 145, 84, 30,
120, 18, 91],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 2
}
}
}
},
"3:8:embedded": {
"1:0:varint": 1,
"2:1:embedded": {
"1:0:bytes": [
168, 15, 228, 127, 125, 117, 127, 138, 147, 171, 112, 68, 159, 126,
29, 136, 159, 179, 53, 127, 49, 203, 4, 114, 246, 31, 236, 30, 138,
177, 114, 180]
},
"3:2:embedded": {
"1:0:bytes": [
175, 38, 148, 203, 5, 192, 218, 240, 99, 37, 193, 198, 171, 54,
171, 189, 43, 21, 47, 93, 178, 90, 122, 26, 84, 147, 81, 211, 72,
159, 117, 186],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 120
}
}
},
"3:3:embedded": {
"1:0:bytes": [
178, 168, 118, 168, 112, 230, 109, 168, 126, 135, 179, 184, 202,
71, 168, 52, 173, 232, 47, 90, 206, 58, 2, 36, 231, 168, 28, 159,
121, 169, 250, 225],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 160
}
}
},
"3:4:embedded": {
"1:0:bytes": [
27, 161, 172, 103, 148, 85, 34, 240, 54, 186, 19, 156, 128, 76,
161, 194, 205, 44, 121, 156, 95, 221, 165, 157, 48, 84, 171, 94,
213, 94, 38, 32],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 240
}
}
},
"3:5:embedded": {
"1:0:bytes": [
59, 22, 204, 77, 122, 25, 137, 251, 172, 27, 167, 105, 49, 28, 42,
101, 237, 95, 111, 59, 71, 48, 155, 192, 72, 229, 119, 45, 87, 83,
228, 126],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 320
}
}
},
"3:6:embedded": {
"1:0:bytes": [
8, 33, 151, 137, 172, 94, 16, 17, 78, 72, 18, 122, 33, 27, 94, 14,
210, 96, 130, 155, 222, 163, 85, 72, 14, 65, 157, 51, 80, 239, 102,
159],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 480
}
}
},
"3:7:embedded": {
"1:0:bytes": [
56, 238, 38, 244, 65, 33, 107, 152, 55, 119, 194, 4, 193, 171, 0,
161, 170, 76, 178, 1, 83, 171, 68, 124, 231, 251, 16, 58, 69, 140,
73, 27],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 640
}
}
},
"3:8:embedded": {
"1:0:bytes": [
234, 0, 220, 53, 6, 255, 39, 198, 77, 205, 185, 199, 74, 82, 77,
238, 19, 189, 175, 169, 229, 243, 213, 98, 178, 88, 114, 237, 130,
176, 18, 73],
"2:1:embedded": {
"1:0:embedded": {
"1:0:varint": 213
}
}
},
"3:9:embedded": {
"1:0:bytes": [
185, 165, 104, 89, 84, 74, 209, 29, 242, 21, 183, 113, 130, 246,
55, 41, 106, 125, 21, 102, 221, 45, 71, 190, 159, 70, 149, 140, 48,
167, 19, 193],
"2:1:embedded": {
"5:0:embedded": {
"1:0:varint": 40
}
}
},
"3:10:embedded": {
"1:0:bytes": [
220, 55, 196, 143, 179, 190, 76, 224, 62, 229, 56, 186, 142, 119,
251, 254, 170, 172, 89, 23, 229, 85, 169, 193, 135, 234, 5, 63, 19,
102, 182, 115],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 3
}
}
},
"3:11:embedded": {
"1:0:bytes": [
129, 101, 107, 114, 78, 83, 69, 51, 80, 76, 1, 218, 223, 168, 239,
110, 132, 179, 104, 145, 7, 183, 83, 83, 248, 208, 228, 139, 134,
120, 52, 26],
"2:1:embedded": {
"3:0:embedded": {
"1:0:varint": 2
}
}
}
},
"3:9:embedded": {
"1:0:varint": 0,
"2:1:embedded": {
"1:0:bytes": [
74, 175, 233, 99, 240, 93, 193, 197, 121, 201, 157, 138, 122, 204,
35, 17, 29, 212, 57, 239, 239, 42, 0, 122, 150, 248, 198, 205, 34,
3, 51, 162]
}
}
}
},
"7:5:varint": 1,
"8:6:varint": 2,
"9:7:varint": 2
}
В данных изредка попадаются занятные строки: android.hardware.ram.low, com.samsung.feature.SAMSUNG_EXPERIENCE, com.google.android.apps.photos.PIXEL_2018_PRELOAD. Эти строки — не очень документированные имена функций, которые могут быть у устройства.
Описание функций, если они есть, можно посмотреть, на устройстве в файлах в папке /etc/sysconfig/:
adb shell cat /etc/sysconfig/pixel_experience_2017.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- These are configurations that should exist on Google's 2017 and newer Nexus devices. -->
<config>
<!-- This is meant to be the canonical feature identifying 2017 and newer Nexus devices. -->
<feature name="com.google.android.feature.PIXEL_2017_EXPERIENCE" />
</config>
adb shell cat /etc/sysconfig/pixel_2017_exclusive.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- These are configurations that should exist on Google's 2017 devices (and not newer/older) -->
<config>
<!-- This defines the Photos preload feature for specifically the 2017 Pixel devices. -->
<feature name="com.google.android.apps.photos.PIXEL_2017_PRELOAD" />
</config>
В качестве документированного примера можно привести проверку наличия камеры запросом функции android.hardware.camera через метод hasSystemFeature класса PackageManager. Но зачем нужны эти строки, в данном контексте непонятно.
Мне не удалось угадать, найти или восстановить схему данных из классов APK «Play Маркет». Если кто-то расскажет, что там и как получилось это определить, будет интересно. Пока есть только предположения разработчиков утилиты от Avast о структуре ProtoBuf и о том, что строка com.google.android.apps.photos.PIXEL_2018_PRELOAD указывает, является ли приложение системным/предустановленным:
1 <varint> = 1 // frosting versions?
2 <varint> = 0
3 <varint> = 1
4 <varint> = 1541545744578 // Timestamp of the frosting creation?
5 <chunk> = message:
8 <chunk> = message:
1 <chunk> = message(1 <varint> = 22) // minSdkLevel?
6 <varint> = 2
9 <chunk> = message:
1 <chunk> = message(1 <varint> = 2266, 4 <varint> = 2) // versionCode
2 <chunk> = message(1 <varint> = 50003, 4 <varint> = 4)
10 <chunk> = message:
1 <chunk> = bytes (30) // ?? only last byte changes across apks
0000 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0010 FF FE FF FF FF FF FF FF FF FF FF FF FF 3F
'.............................?'
3 <chunk> = message:
1 <chunk> = bytes (32) // sha256 of something?
0000 16 F8 22 A6 93 26 89 34 D8 2A 88 BB 8C AD B6 68
0010 2C EB 77 A8 AA E4 5F AA F9 3C CA 63 44 2A A4 B9
'.."..&.4.*.....h,.w..._..<.cD*..'
2 <varint> = 20
Я бы хотел оставить несколько комментариев на этот счет.
1) По поводу строки com.google.android.apps.photos.PIXEL_2018_PRELOAD: легко доказать, что это неверное предположение. Скачаем несколько образов, предоставляемых Google, и увидим, что там нет не только таких строк, но и ни одного приложения, которое бы содержало блок Frosting.
Можно рассмотреть это более детально на образе walleye for Pixel 2 9.0.0 (PQ3A.190801.002, Aug 2019). Установим образ и обнаружим, что среди всех 187 APK-файлов нет ни одного файла, содержащего блок Frosting. Если обновить все приложения, блок Frosting обнаружится у 33 из 264 APK-файлов. При этом только у пяти из них присутствуют строки:
- com.google.android.as:
- com.google.android.feature.DPS
- com.google.android.feature.PIXEL_EXPERIENCE
- com.google.android.feature.PIXEL_2017_EXPERIENCE
- com.google.android.feature.PIXEL_2019_EXPERIENCE
- com.google.android.feature.ANDROID_ONE_EXPERIENCE
- com.google.android.feature.PIXEL_2018_EXPERIENCE
- com.google.android.feature.PIXEL_2020_EXPERIENCE
- google.android.inputmethod.latin:
- android.hardware.ram.low
- google.android.dialer:
- com.google.android.apps.dialer.GO_EXPERIENCE
- com.google.android.feature.PIXEL_2020_EXPERIENCE
- google.android.GoogleCamera:
- android.hardware.camera.level.full
- google.android.apps.photos:
- com.google.android.feature.PIXEL_2020_EXPERIENCE
Можно предположить, что эти строки определяют необходимость функций на устройстве, куда устанавливается приложение. Но запросим полный список функций устройства, на котором проводилось обновление, и убедимся, что это не так.
Скрытый текст
SPL
adb shell pm list features
feature:reqGlEsVersion=0x30002
feature:android.hardware.audio.low_latency
feature:android.hardware.audio.output
feature:android.hardware.audio.pro
feature:android.hardware.bluetooth
feature:android.hardware.bluetooth_le
feature:android.hardware.camera
feature:android.hardware.camera.any
feature:android.hardware.camera.ar
feature:android.hardware.camera.autofocus
feature:android.hardware.camera.capability.manual_post_processing
feature:android.hardware.camera.capability.manual_sensor
feature:android.hardware.camera.capability.raw
feature:android.hardware.camera.flash
feature:android.hardware.camera.front
feature:android.hardware.camera.level.full
feature:android.hardware.faketouch
feature:android.hardware.fingerprint
feature:android.hardware.location
feature:android.hardware.location.gps
feature:android.hardware.location.network
feature:android.hardware.microphone
feature:android.hardware.nfc
feature:android.hardware.nfc.any
feature:android.hardware.nfc.hce
feature:android.hardware.nfc.hcef
feature:android.hardware.opengles.aep
feature:android.hardware.ram.normal
feature:android.hardware.screen.landscape
feature:android.hardware.screen.portrait
feature:android.hardware.sensor.accelerometer
feature:android.hardware.sensor.assist
feature:android.hardware.sensor.barometer
feature:android.hardware.sensor.compass
feature:android.hardware.sensor.gyroscope
feature:android.hardware.sensor.hifi_sensors
feature:android.hardware.sensor.light
feature:android.hardware.sensor.proximity
feature:android.hardware.sensor.stepcounter
feature:android.hardware.sensor.stepdetector
feature:android.hardware.telephony
feature:android.hardware.telephony.carrierlock
feature:android.hardware.telephony.cdma
feature:android.hardware.telephony.euicc
feature:android.hardware.telephony.gsm
feature:android.hardware.touchscreen
feature:android.hardware.touchscreen.multitouch
feature:android.hardware.touchscreen.multitouch.distinct
feature:android.hardware.touchscreen.multitouch.jazzhand
feature:android.hardware.usb.accessory
feature:android.hardware.usb.host
feature:android.hardware.vr.headtracking
feature:android.hardware.vr.high_performance
feature:android.hardware.vulkan.compute
feature:android.hardware.vulkan.level
feature:android.hardware.vulkan.version=4198400
feature:android.hardware.wifi
feature:android.hardware.wifi.aware
feature:android.hardware.wifi.direct
feature:android.hardware.wifi.passpoint
feature:android.hardware.wifi.rtt
feature:android.software.activities_on_secondary_displays
feature:android.software.app_widgets
feature:android.software.autofill
feature:android.software.backup
feature:android.software.cant_save_state
feature:android.software.companion_device_setup
feature:android.software.connectionservice
feature:android.software.cts
feature:android.software.device_admin
feature:android.software.device_id_attestation
feature:android.software.file_based_encryption
feature:android.software.home_screen
feature:android.software.input_methods
feature:android.software.live_wallpaper
feature:android.software.managed_users
feature:android.software.midi
feature:android.software.picture_in_picture
feature:android.software.print
feature:android.software.securely_removes_users
feature:android.software.sip
feature:android.software.sip.voip
feature:android.software.verified_boot
feature:android.software.voice_recognizers
feature:android.software.vr.mode
feature:android.software.webview
feature:com.google.android.apps.dialer.SUPPORTED
feature:com.google.android.apps.photos.PIXEL_2017_PRELOAD
feature:com.google.android.feature.EXCHANGE_6_2
feature:com.google.android.feature.GOOGLE_BUILD
feature:com.google.android.feature.GOOGLE_EXPERIENCE
feature:com.google.android.feature.PIXEL_2017_EXPERIENCE
feature:com.google.android.feature.PIXEL_EXPERIENCE
feature:com.google.android.feature.TURBO_PRELOAD
feature:com.google.android.feature.WELLBEING
feature:com.google.android.feature.ZERO_TOUCH
feature:com.google.hardware.camera.easel
feature:com.verizon.hardware.telephony.ehrpd
feature:com.verizon.hardware.telephony.lte
2) С frosting versions я не согласен, так как можно найти похожие данные, но со значениями, отличными от 1. Максимальное значение этого поля, которое мне попадалось, –– 26.
3) С timestamp of the frosting creation я не согласен: я понаблюдал за конкретным приложением и заметил, что с выходом новых версий значение этого поля не обязательно растет. Оно скачет и может быть отрицательным.
4) MinSdkLevel и VersionCode выглядят правдоподобно.
Заключение
Итак, блок Frosting в подписи помогает однозначно определить, распространялся ли файл через официальный магазин. Больше никакой пользы из этой подписи извлечь не удалось.
Ловите напоследок пример использования такой информации в отчете мобильной песочницы ApkLab:
===========
Источник:
habr.com
===========
Похожие новости:
- [Информационная безопасность, Антивирусная защита, Автомобильные гаджеты] Как взламывают подключенные автомобили и что с этим делать
- [Open source, Разработка под Android] Делюсь небольшим, но полезным плагином: Deeplink Helper для Android Studio
- [Информационная безопасность, Google Chrome, Расширения для браузеров, Браузеры] В бета-версии Chrome 88 включили Manifest V3, который изменит доступ расширений к данным
- [Информационная безопасность, Системное администрирование, Сетевые технологии] Состоялся релиз CrowdSec v.1.0.0
- [Разработка мобильных приложений, Разработка под Android, Разработка под MacOS] Переходим В OFFLINE FIRST с использованием Core Data и Managed Document(s)
- [Информационная безопасность, Мессенджеры, Видеоконференцсвязь] Мы нашли опасную уязвимость в Microsoft Teams, но компания устранила её только спустя два месяца (перевод)
- [Информационная безопасность, Криптография, Open source, Законодательство в IT] Немецкий суд заставил почтового провайдера Tutanota установить бэкдор
- [Информационная безопасность, Медгаджеты] General Electric оставила пароль по умолчанию в медицинских аппаратах радиотерапии
- [Программирование, Разработка мобильных приложений, Разработка под Android, Kotlin] Практическое руководство по использованию Hilt с Kotlin (перевод)
- [Информационная безопасность, Читальный зал, Научно-популярное] Геоблокировка: как ограничивают доступ к информации и кому это нужно
Теги для поиска: #_informatsionnaja_bezopasnost (Информационная безопасность), #_razrabotka_pod_android (Разработка под Android), #_reversinzhiniring (Реверс-инжиниринг), #_razrabotka_pod_android (разработка под android), #_reversinzhiniring (реверс-инжиниринг), #_informatsionnaja_bezopasnost (информационная безопасность), #_frosting, #_blog_kompanii_bi.zone (
Блог компании BI.ZONE
), #_informatsionnaja_bezopasnost (
Информационная безопасность
), #_razrabotka_pod_android (
Разработка под Android
), #_reversinzhiniring (
Реверс-инжиниринг
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:25
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Автор: Константин Молодяков Структура файла — увлекательный мир со своими историей, тайнами и собственным цирком уродов, где выступают костыльные решения. Если в ней покопаться, можно найти много интересного. Я наткнулся на одну особенность APK-файлов — специальную подпись с особым блоком метаданных, Frosting. Она позволяет однозначно определить, распространялся ли файл через Google Play. Эта подпись будет полезна для антивирусных вендоров и песочниц при анализе вредоносов. Кроме того, она может помочь криминалистам при поиске источника файла. Информации об этом практически нет. Удалось найти только раздел Security metadata in early 2018 в Android Developers Blog и утилиту Avast, которая позволяет проверить данную подпись. Я решил изучить эту штуку, проверить корректность предположений разработчиков Avast о содержании Frosting-блока и поделиться своими выводами. Frosting и APK Signing Block Google использует специальную подпись APK-файлов при публикации приложений в Google Play. Эта подпись лежит в APK Signing Block, который находится перед центральной директорией ZIP-файла и после его основного содержимого: Для идентификации APK Signing Block используется magic — APK Sig Block 42. Внутри блока подписи могут лежать другие блоки, предназначение которых определяется 4-байтовым ID. Получается расширение ZIP-формата с обратной совместимостью. Если интересно почитать подробнее или увидеть исходники, метод ApkSigningBlockUtils.findSignature описан тут. Возьмем какой-нибудь файл, например 2124948e2b7897cd6fbbe5fbd655c26d. Посмотреть идентификаторы блоков, содержащихся в APK Signing Block, можно с помощью androguard: from androguard.core.bytecodes import apk
apk_obj = apk.APK("2124948e2b7897cd6fbbe5fbd655c26d.apk") apk_obj.parse_v2_v3_signature() print(["0x%X" % key for key in apk_obj._v2_blocks.keys()]) ['0x7109871A', '0x2146444E'] Существует несколько блоков с разными индентификаторами, которые официально описаны в документации:
Некоторые блоки можно найти в исходниках Android:
Встречаются и другие блоки:
Frosting и «Play Маркет» Вернемся к анализу рассматриваемого блока 0x2146444e. Для начала следует изучить внутренности приложения «Play Маркет». .method public static b(ByteBuffer)ByteBuffer
.registers 2 00000000 invoke-static bny->a(ByteBuffer)aea, p0 00000006 move-result-object p0 00000008 const v0, 0x2146444E 0000000E invoke-virtual aea->a(I)Object, p0, v0 00000014 move-result-object p0 00000016 check-cast p0, bnx 0000001A if-eqz p0, :00000024 0000001E iget-object p0, p0, bnx->a:ByteBuffer 00000022 return-object p0 00000024 new-instance p0, SigBlockUtil$BlockNotFoundException 00000028 const-string v0, "Block entry id (go/apk-structure-glossary) " "not present in APK Signing Block" 0000002C invoke-direct SigBlockUtil$BlockNotFoundException-> <init>(String)V, p0, v0 00000032 throw p0 .end method Интересующий нас идентификатор обнаружен в двух местах. Смотрим глубже. Довольно быстро находим класс, отвечающий за разбор блока. Здесь же первый раз среди констант появляется название Frosting-блока: public enum aysn implements avto {
UNKNOWN(0), SUCCESS(81), NO_FROSTING_BLOCK(1), FROSTING_BLOCK_TOO_SHORT(2), BAD_SIGNED_DATA_LENGTH_VARINT(3), NON_POSITIVE_SIGNED_DATA_LENGTH(4), SIGNED_DATA_LENGTH_TOO_LONG(5), BAD_FROSTING_LENGTH_VARINT(6), NON_POSITIVE_FROSTING_LENGTH(7), FROSTING_LENGTH_BEYOND_SIGNED_DATA(8), FROSTING_LENGTH_BEYOND_BLOCK(9), MALFORMED_FROSTING(10), // ... INSTALLER_NO_ACCOUNT_WITH_MATCHING_REGION(74); // ... } Я сравнил разные версии приложения «Play Маркет» и заметил следующее: код, отвечающий за разбор такого вида подписи, появился примерно в январе 2018 года вместе с выходом версии 8.6.X. Блок с метаданными Frosting существовал и раньше, но именно в этот период он принял тот вид, в котором существует сейчас. Для разбора данных нам понадобится примитив чтения 4-байтового числа. Схема представляет собой стандартный varint без каких-либо ухищрений с отрицательными числами: private static int read_int32(ByteBuffer arg2) {
int v0 = arg2.get(); if(v0 >= 0) { return v0; } int v0_1 = v0 & 0x7F; int v1 = arg2.get(); if(v1 >= 0) { return v1 << 7 | v0_1; } v0_1 |= (v1 & 0x7F) << 7; int v1_1 = arg2.get(); if(v1_1 >= 0) { return v1_1 << 14 | v0_1; } v0_1 |= (v1_1 & 0x7F) << 14; int v1_2 = arg2.get(); if(v1_2 >= 0) { return v1_2 << 21 | v0_1; } int v2 = arg2.get(); int v0_2 = v0_1 | (v1_2 & 0x7F) << 21 | v2 << 28; if(v2 >= 0) { return v0_2; } throw new IllegalArgumentException(); } Функция разбора блока довольно большая, хоть и устроена просто. Она позволяет разобраться в самой структуре данных: {
var_int32 size_signed_data, var_int32 size_frosting, byte frosting[size_frosting], var_int32 size_validation_sequence, array validation_sequence { var_int32 size_validation_data, var_int32 validation_strategy, var_int32 signing_key_index, byte sha256[0x20]}, var_int32 size_signature_sequence, array signature_sequence { var_int32 size_signature, byte signature[size_signature]}} Для проверки подписи используются хеш и ключ первого поля из последовательности validation_sequence, у которого validation_strategy равен нулю. Сама подпись забирается из последовательности signature_sequence с таким же порядковым номером, как у записи из validation_sequence. На рисунке ниже представлен поясняющий псевдокод: def get_signing_data(frosting_block):
for i, validation in enumerate(frosting_block.validation_sequence): if validation.validation_strategy != 0: continue return ( validation.sha256, validation.signing_key_index, frosting_block.signature_sequence[i].signature) raise AttributeError() Значение signing_key_index указывает на индекс в массиве finsky.peer_app_sharing_api.frosting_public_keys, который определен следующим образом и пока содержит только один ключ: gyd.iH = arip.a(
"finsky.peer_app_sharing_api.min_tos_version", v8); gyd.iI = arip.a( "finsky.peer_app_sharing_api.frosting_public_keys", "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZH2+1+E07dnErAD3L6BbTnaohU0bbXriNlJI7VxJU+LjdSwPyXR5pomARAMoyPkMksLz/gitUPtFuJoPL2ziEw=="); gyd.iJ = arip.a( "finsky.peer_app_sharing_api.startup_package_blacklist", "com.android.vending,com.google.android.gms,com.android.providers.downloads"); gyd.iK = arip.a( "finsky.frosting_only_update_time_ms", Long.valueOf(TimeUnit.DAYS.toMillis(30L))); Подписываются данные размером size_signed_data, начиная с переменной size_frosting, алгоритмом ECDSA_SHA256. При этом подписываемые данные содержат SHA-256 от данных файла: 1) данные от начала файла до блока подписи; 2) данные от central directory до конца end of central directory, с заменой в end of central directory значения поля offset of start of central with respect to the starting disk number на оффсет блока подписи. Если есть блок подписи схемы версии 2, то он вставляется между данными из пунктов 1 и 2 с добавлением APK_SIGNATURE_SCHEME_V2_BLOCK_ID перед ним. Функция, вычисляющая хеш в приложении «Play Маркет», выглядит так: private static byte[] get_frosting_hash(RandomAccessFile f_apk,
long offset_signing_block, ByteBuffer signature_scheme_v2_block, long offset_zip_central_dir, long size_from_central_dir_to_end_central_dir, ByteBuffer end_central_dir) { MessageDigest v0; try { v0 = MessageDigest.getInstance("SHA-256"); } catch(NoSuchAlgorithmException unused_ex) { throw new FrostingUtil.FailureException(aysn.N); // NO_SHA_256_ALGORITHM } mcc.update_digest(v0, f_apk, 0L, offset_signing_block); if(signature_scheme_v2_block != null) { v0.update(mcc.a); v0.update(signature_scheme_v2_block); } mcc.update_digest(v0, f_apk, offset_zip_central_dir, size_from_central_dir_to_end_central_dir); bnz.a(end_central_dir, offset_signing_block); end_central_dir.position(end_central_dir.position()); end_central_dir.limit(end_central_dir.limit()); v0.update(end_central_dir); return v0.digest(); } Frosting и ProtoBuf Этой информации достаточно, чтобы проверить валидность подписи. Но, увы, мне так и не удалось узнать, что скрывается в данных Frosting-блока. У меня получилось лишь определить, что данные имеют формат ProtoBuf и могут сильно отличаться по размеру и наличию полей в зависимости от файла. Обычно декодированные без схемы данные выглядят так (4b005c9e9ea0731330a757fcf3abeb6e): cat ./ru.sberbankmobile_11.1.0_2020072413.protobuf | ./protodec -p
{ "1:0:varint": 2, "2:1:varint": 0, "3:2:varint": 1, "4:3:varint": 1603811598348, "5:4:embedded": { "8:0:embedded": { "1:0:embedded": { "1:0:varint": 21 }, "6:1:varint": 3 }, "9:1:embedded": { "1:0:embedded": { "1:0:varint": 2020072413, "4:1:varint": 3 }, "2:1:embedded": { "1:0:varint": 2020072414, "4:1:varint": 5 } }, "10:2:embedded": { "1:0:bytes": [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 7, 0, 40, 0, 16, 0, 0, 80, 5, 16, 64, 0, 56 ] } }, "8:5:varint": 1, "9:6:varint": 2 } Но встречаются экземпляры (471c589acc800135eb318057c43a8068), содержащие под пятьсот полей. Скрытый текстSPL{
"1:0:varint": 1, "2:1:varint": 1, "3:2:varint": 1, "4:3:varint": 1593452906098, "5:4:embedded": { "7:0:embedded": { "1:0:varint": 1, "2:1:varint": 1 }, "8:1:embedded": { "1:0:embedded": { "1:0:varint": 16 }, "6:1:varint": 3, "6:2:varint": 2 }, "9:2:embedded": { "1:0:embedded": { "1:0:varint": 2021505050, "4:1:varint": 3, "4:2:varint": 2 } }, "10:3:embedded": { "1:0:bytes": [ 221, 255, 227, 239, 247, 127, 255, 191, 239, 191, 255, 255, 255, 255, 247, 255, 255, 0, 0, 8, 0, 16, 0, 0, 16, 5, 16, 64, 0, 32], "3:1:embedded": { "1:0:bytes": [ 137, 204, 247, 126, 103, 225, 96, 185, 11, 67, 239, 227, 193, 247, 248, 68, 8, 2, 37, 20, 197, 120, 249, 112, 81, 240, 131, 124, 231, 64, 45, 116, 60, 212, 47, 211, 175, 84, 218, 140, 61, 140, 116, 14, 9, 38, 64, 21, 87, 196, 128, 228, 201, 237, 248, 67, 96, 229, 131, 79, 217, 94, 223, 232, 73, 222, 177, 132, 162, 191, 144, 84, 83, 77, 253, 70, 207, 180, 53, 131, 75, 2, 111, 84, 212, 4, 33, 100, 160, 78, 253, 54, 63, 120, 67, 18, 92, 196, 101, 214, 245, 149, 11, 217, 102, 93, 243, 158, 87, 133, 135, 85, 179, 175, 58, 242, 217, 52, 37, 128, 81, 76, 10, 113, 96, 205, 150, 253, 12, 105, 74, 1, 25, 146, 160, 126, 93, 196, 179, 143, 145, 106, 135, 242, 136, 186, 96, 164, 61, 11, 56, 229, 113, 104, 68, 162, 179, 105, 25, 125, 27, 43, 162, 94, 238, 237, 75, 89, 0, 112, 98, 49, 129, 49, 208, 89, 163, 66, 174, 119, 27, 135, 109, 105, 204], "2:1:varint": 13 } }, "12:4:embedded": { "1:0:embedded": { "5:0:varint": 21 }, "2:1:embedded": { "1:0:varint": 0, "2:1:embedded": { "1:0:bytes": [ 41, 93, 201, 211, 27, 15, 203, 207, 160, 84, 10, 4, 65, 194, 92, 146, 191, 221, 207, 134, 150, 216, 77, 234, 223, 53, 187, 49, 207, 136, 84, 82] }, "3:2:embedded": { "1:0:bytes": [ 80, 168, 41, 12, 177, 59, 101, 235, 150, 116, 174, 248, 213, 250, 72, 228, 35, 56, 11, 184, 197, 36, 206, 168, 225, 19, 221, 82, 213, 106, 206, 248], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 120 } } }, "3:3:embedded": { "1:0:bytes": [ 59, 234, 46, 139, 75, 154, 134, 17, 78, 53, 232, 182, 38, 151, 51, 63, 38, 71, 1, 189, 112, 252, 157, 201, 177, 179, 163, 159, 188, 22, 181, 221], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 160 } } }, "3:4:embedded": { "1:0:bytes": [ 202, 210, 137, 99, 138, 209, 74, 181, 118, 190, 8, 18, 68, 86, 137, 151, 223, 217, 226, 19, 248, 109, 240, 206, 216, 31, 232, 18, 87, 167, 17, 251], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 240 } } }, "3:5:embedded": { "1:0:bytes": [ 191, 119, 224, 30, 167, 161, 4, 135, 44, 155, 92, 208, 26, 168, 120, 198, 195, 65, 125, 110, 58, 168, 92, 171, 56, 41, 131, 172, 176, 171, 78, 223], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 320 } } }, "3:6:embedded": { "1:0:bytes": [ 246, 143, 161, 148, 32, 191, 55, 116, 35, 71, 23, 31, 83, 35, 218, 162, 116, 40, 111, 227, 122, 3, 151, 57, 45, 54, 156, 94, 171, 146, 185, 175], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 480 } } }, "3:7:embedded": { "1:0:bytes": [ 5, 217, 66, 174, 71, 16, 113, 53, 143, 20, 129, 142, 83, 16, 107, 217, 105, 193, 85, 234, 236, 46, 45, 168, 7, 17, 71, 171, 18, 239, 131, 23], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 640 } } }, "3:8:embedded": { "1:0:bytes": [ 134, 163, 146, 36, 137, 172, 95, 238, 205, 214, 71, 99, 209, 190, 16, 59, 205, 59, 201, 2, 146, 43, 117, 131, 131, 218, 64, 251, 108, 217, 37, 141], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 213 } } }, "3:9:embedded": { "1:0:bytes": [ 186, 26, 67, 178, 23, 52, 226, 60, 224, 196, 139, 119, 120, 246, 20, 110, 238, 52, 171, 50, 107, 40, 225, 89, 86, 93, 183, 41, 195, 150, 1, 234], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 7 } } }, "3:10:embedded": { "1:0:bytes": [ 58, 32, 81, 63, 166, 190, 81, 128, 63, 140, 253, 185, 32, 231, 65, 64, 145, 144, 158, 160, 114, 51, 147, 56, 145, 78, 131, 124, 155, 244, 135, 29], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 47 } } }, "3:11:embedded": { "1:0:bytes": [ 208, 138, 65, 103, 12, 44, 60, 179, 81, 117, 125, 125, 32, 171, 58, 255, 61, 9, 184, 59, 17, 165, 38, 250, 2, 126, 131, 206, 204, 106, 121, 122], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 172 } } }, "3:12:embedded": { "1:0:bytes": [ 31, 249, 92, 139, 0, 179, 127, 14, 76, 18, 118, 130, 116, 231, 107, 180, 104, 172, 152, 12, 126, 119, 18, 158, 162, 145, 126, 39, 92, 184, 71, 29], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 148 } } }, "3:13:embedded": { "1:0:bytes": [ 215, 70, 132, 253, 56, 142, 20, 226, 80, 118, 251, 124, 96, 236, 23, 198, 249, 38, 100, 213, 16, 125, 232, 138, 142, 127, 236, 127, 185, 25, 114, 190], "2:1:embedded": { "7:0:embedded": { "1:0:string": "IW" } } }, "3:14:embedded": { "1:0:bytes": [ 87, 151, 187, 223, 182, 225, 35, 238, 176, 44, 82, 149, 122, 132, 165, 219, 225, 29, 73, 188, 200, 85, 139, 102, 160, 115, 38, 107, 248, 236, 198, 127], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 153 } } }, "3:15:embedded": { "1:0:bytes": [ 41, 181, 59, 170, 70, 192, 248, 215, 162, 173, 176, 230, 98, 201, 85, 97, 46, 213, 204, 180, 97, 160, 104, 131, 96, 116, 115, 239, 75, 4, 152, 127], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 171 } } }, "3:16:embedded": { "1:0:bytes": [ 66, 31, 252, 95, 240, 235, 159, 130, 37, 247, 203, 210, 165, 40, 2, 37, 157, 33, 78, 114, 102, 214, 7, 15, 128, 103, 91, 63, 138, 113, 125, 119], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 3 } } }, "3:17:embedded": { "1:0:bytes": [ 38, 209, 2, 170, 201, 97, 61, 107, 59, 193, 146, 187, 51, 241, 22, 232, 147, 33, 169, 77, 71, 109, 213, 77, 47, 247, 160, 158, 111, 206, 156, 243], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 184 } } }, "3:18:embedded": { "1:0:bytes": [ 195, 229, 130, 114, 114, 109, 5, 1, 40, 156, 47, 239, 0, 169, 239, 211, 98, 138, 113, 182, 234, 23, 214, 125, 49, 107, 142, 168, 175, 253, 223, 124], "2:1:embedded": { "7:0:embedded": { "1:0:string": "IN" } } }, "3:19:embedded": { "1:0:bytes": [ 53, 252, 95, 223, 136, 114, 75, 101, 122, 251, 97, 128, 49, 203, 183, 223, 33, 50, 56, 209, 198, 238, 135, 15, 85, 128, 142, 242, 221, 17, 110, 219], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 77 } } }, "3:20:embedded": { "1:0:bytes": [ 31, 231, 69, 193, 155, 115, 41, 39, 125, 98, 164, 106, 101, 40, 15, 168, 63, 161, 40, 158, 119, 56, 170, 131, 97, 143, 204, 117, 219, 228, 115, 58], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 51 } } }, "3:21:embedded": { "1:0:bytes": [ 58, 114, 14, 110, 167, 28, 66, 253, 106, 5, 106, 130, 219, 199, 234, 73, 126, 0, 63, 102, 153, 172, 52, 224, 22, 145, 84, 42, 74, 216, 210, 58], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 154 } } }, "3:22:embedded": { "1:0:bytes": [ 3, 198, 55, 89, 63, 195, 67, 117, 23, 19, 208, 6, 64, 61, 55, 60, 106, 216, 150, 133, 175, 51, 211, 254, 106, 150, 250, 240, 10, 49, 163, 47], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 84 } } }, "3:23:embedded": { "1:0:bytes": [ 43, 113, 17, 252, 89, 90, 79, 80, 158, 159, 123, 186, 207, 137, 84, 186, 68, 155, 105, 111, 176, 215, 70, 107, 51, 237, 73, 155, 242, 122, 10, 46], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 325 } } }, "3:24:embedded": { "1:0:bytes": [ 163, 118, 101, 102, 1, 115, 201, 144, 237, 239, 117, 79, 163, 127, 173, 149, 33, 211, 90, 111, 82, 50, 146, 101, 80, 30, 22, 112, 153, 164, 19, 150], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 258 } } }, "3:25:embedded": { "1:0:bytes": [ 11, 171, 219, 11, 212, 240, 116, 80, 201, 168, 63, 75, 188, 168, 236, 220, 108, 157, 49, 226, 17, 158, 105, 188, 44, 180, 67, 196, 36, 31, 46, 149], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 161 } } }, "3:26:embedded": { "1:0:bytes": [ 233, 52, 162, 8, 5, 80, 139, 147, 172, 124, 252, 124, 75, 146, 182, 53, 109, 29, 220, 18, 52, 120, 53, 83, 255, 138, 143, 39, 194, 61, 163, 196], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 46 } } }, "3:27:embedded": { "1:0:bytes": [ 82, 61, 18, 192, 210, 218, 157, 38, 65, 86, 39, 30, 138, 32, 248, 114, 10, 148, 210, 251, 130, 23, 54, 116, 104, 206, 141, 102, 169, 191, 5, 233], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 38 } } }, "3:28:embedded": { "1:0:bytes": [ 47, 251, 190, 153, 104, 136, 52, 169, 146, 57, 29, 6, 153, 167, 3, 209, 5, 30, 100, 215, 240, 47, 96, 103, 114, 164, 131, 197, 69, 112, 4, 86], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 129 } } }, "3:29:embedded": { "1:0:bytes": [ 93, 192, 14, 10, 50, 59, 229, 14, 140, 132, 196, 12, 219, 149, 215, 224, 125, 6, 139, 61, 6, 144, 255, 96, 5, 37, 216, 91, 137, 135, 41, 24], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 25 } } }, "3:30:embedded": { "1:0:bytes": [ 10, 2, 142, 220, 179, 122, 72, 30, 24, 127, 28, 65, 31, 28, 73, 126, 198, 238, 62, 156, 228, 87, 163, 9, 38, 116, 106, 48, 25, 152, 159, 179], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 126 } } }, "3:31:embedded": { "1:0:bytes": [ 81, 12, 199, 94, 25, 57, 186, 111, 6, 142, 64, 231, 47, 149, 116, 21, 53, 34, 89, 104, 13, 47, 184, 121, 38, 4, 206, 64, 179, 247, 20, 137], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 156 } } }, "3:32:embedded": { "1:0:bytes": [ 171, 95, 184, 6, 120, 203, 22, 123, 134, 45, 181, 225, 90, 186, 233, 210, 8, 55, 43, 48, 169, 47, 10, 200, 161, 216, 118, 98, 61, 215, 124, 135], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 158 } } }, "3:33:embedded": { "1:0:bytes": [ 198, 24, 206, 30, 88, 136, 6, 128, 184, 53, 150, 247, 25, 79, 56, 60, 81, 143, 13, 123, 107, 35, 86, 162, 122, 7, 216, 27, 27, 249, 19, 47], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 63 } } }, "3:34:embedded": { "1:0:bytes": [ 230, 93, 108, 31, 194, 183, 82, 253, 244, 34, 6, 1, 7, 69, 80, 147, 131, 89, 158, 29, 236, 115, 92, 196, 44, 178, 254, 238, 121, 246, 113, 68], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 104 } } }, "3:35:embedded": { "1:0:bytes": [ 147, 204, 39, 33, 249, 108, 184, 249, 48, 14, 165, 120, 66, 9, 137, 134, 5, 48, 106, 48, 105, 140, 144, 159, 125, 179, 124, 71, 158, 117, 131, 210], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 19 } } }, "3:36:embedded": { "1:0:bytes": [ 89, 255, 33, 10, 191, 177, 183, 189, 245, 158, 109, 205, 126, 163, 104, 71, 57, 35, 124, 14, 130, 83, 188, 213, 129, 96, 249, 122, 39, 106, 120, 195], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 80 } } }, "3:37:embedded": { "1:0:bytes": [ 105, 92, 221, 66, 185, 181, 94, 19, 30, 129, 85, 145, 196, 110, 14, 125, 216, 251, 11, 186, 138, 194, 135, 243, 1, 172, 32, 128, 159, 113, 84, 87], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 106 } } }, "3:38:embedded": { "1:0:bytes": [ 157, 183, 189, 153, 219, 24, 43, 100, 235, 0, 132, 119, 215, 108, 236, 153, 22, 241, 252, 211, 231, 116, 33, 113, 123, 237, 138, 202, 213, 153, 43, 88], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 123 } } }, "3:39:embedded": { "1:0:bytes": [ 146, 229, 59, 43, 145, 105, 186, 201, 142, 14, 158, 90, 5, 28, 230, 197, 134, 18, 13, 219, 74, 209, 84, 214, 210, 54, 70, 1, 56, 31, 218, 54], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 58 } } }, "3:40:embedded": { "1:0:bytes": [ 220, 242, 61, 79, 217, 248, 85, 208, 85, 163, 104, 176, 88, 2, 114, 108, 131, 202, 204, 53, 110, 75, 239, 56, 136, 67, 248, 247, 12, 63, 191, 12], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 175 } } }, "3:41:embedded": { "1:0:bytes": [ 71, 68, 176, 15, 211, 98, 59, 27, 187, 227, 14, 91, 53, 120, 129, 50, 108, 107, 103, 66, 252, 217, 178, 77, 184, 147, 91, 90, 19, 111, 128, 53], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 134 } } }, "3:42:embedded": { "1:0:bytes": [ 201, 51, 220, 118, 187, 125, 87, 7, 246, 185, 155, 52, 220, 28, 12, 90, 48, 123, 202, 135, 233, 18, 3, 137, 10, 222, 223, 206, 111, 196, 255, 235], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 78 } } }, "3:43:embedded": { "1:0:bytes": [ 144, 123, 192, 106, 90, 212, 71, 96, 188, 5, 46, 223, 100, 12, 58, 99, 141, 127, 17, 14, 181, 44, 129, 224, 57, 134, 157, 34, 245, 78, 63, 60], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 130 } } }, "3:44:embedded": { "1:0:bytes": [ 21, 33, 78, 136, 74, 131, 86, 48, 170, 99, 67, 146, 12, 42, 119, 249, 70, 198, 221, 127, 241, 175, 42, 0, 12, 66, 71, 172, 59, 17, 27, 228], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 56 } } }, "3:45:embedded": { "1:0:bytes": [ 45, 178, 69, 5, 175, 52, 44, 90, 190, 94, 100, 180, 238, 153, 189, 58, 248, 181, 189, 134, 151, 53, 68, 244, 110, 252, 95, 156, 34, 248, 195, 141], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 90 } } }, "3:46:embedded": { "1:0:bytes": [ 91, 22, 185, 64, 72, 46, 38, 48, 20, 244, 241, 114, 1, 64, 97, 227, 136, 54, 169, 201, 133, 11, 182, 88, 154, 1, 142, 138, 24, 112, 166, 16], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 168 } } }, "3:47:embedded": { "1:0:bytes": [ 27, 146, 39, 199, 46, 197, 241, 106, 223, 55, 129, 191, 176, 123, 232, 151, 44, 180, 31, 142, 137, 201, 21, 52, 94, 201, 111, 170, 169, 93, 55, 131], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 76 } } }, "3:48:embedded": { "1:0:bytes": [ 193, 124, 22, 3, 213, 34, 101, 149, 246, 22, 8, 15, 68, 75, 165, 76, 38, 150, 247, 77, 2, 140, 154, 249, 2, 205, 73, 232, 130, 104, 69, 159], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 66 } } }, "3:49:embedded": { "1:0:bytes": [ 5, 193, 68, 1, 180, 40, 46, 163, 192, 112, 174, 29, 81, 223, 190, 244, 3, 142, 55, 211, 8, 2, 192, 194, 30, 20, 55, 42, 41, 68, 125, 127], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 136 } } }, "3:50:embedded": { "1:0:bytes": [ 83, 24, 100, 126, 8, 186, 138, 33, 95, 127, 89, 36, 2, 106, 137, 183, 242, 92, 104, 95, 122, 198, 162, 7, 255, 251, 123, 96, 225, 149, 63, 111], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 29 } } }, "3:51:embedded": { "1:0:bytes": [ 194, 142, 59, 4, 54, 96, 70, 2, 123, 91, 9, 252, 170, 235, 182, 98, 37, 143, 10, 210, 186, 173, 103, 165, 149, 47, 171, 59, 201, 209, 250, 66], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 107 } } }, "3:52:embedded": { "1:0:bytes": [ 99, 76, 68, 203, 167, 245, 211, 142, 143, 66, 189, 190, 254, 178, 37, 12, 61, 195, 104, 178, 165, 186, 113, 253, 215, 1, 169, 54, 129, 175, 212, 70], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 35 } } }, "3:53:embedded": { "1:0:bytes": [ 92, 240, 11, 68, 247, 15, 103, 182, 210, 65, 243, 114, 153, 230, 135, 241, 160, 60, 31, 140, 166, 85, 107, 163, 252, 119, 167, 35, 195, 207, 141, 18], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 20 } } }, "3:54:embedded": { "1:0:bytes": [ 52, 163, 30, 105, 147, 104, 203, 234, 85, 78, 118, 91, 238, 243, 81, 81, 183, 127, 166, 173, 2, 33, 111, 160, 93, 35, 4, 128, 97, 231, 134, 223], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 40 } } }, "3:55:embedded": { "1:0:bytes": [ 15, 45, 48, 189, 170, 219, 22, 126, 243, 217, 200, 106, 165, 165, 120, 108, 150, 111, 105, 150, 85, 8, 120, 155, 210, 148, 32, 198, 145, 49, 115, 16], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 26 } } }, "3:56:embedded": { "1:0:bytes": [ 27, 250, 155, 159, 74, 227, 46, 27, 185, 4, 150, 8, 184, 21, 240, 149, 45, 244, 81, 252, 85, 159, 50, 201, 247, 73, 42, 60, 127, 194, 238, 197], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 36 } } }, "3:57:embedded": { "1:0:bytes": [ 108, 3, 162, 113, 54, 72, 115, 18, 228, 40, 151, 67, 169, 226, 153, 58, 138, 252, 59, 67, 200, 53, 128, 160, 233, 148, 198, 100, 2, 236, 64, 76], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 127 } } }, "3:58:embedded": { "1:0:bytes": [ 49, 49, 177, 65, 227, 61, 198, 32, 171, 82, 125, 100, 152, 38, 31, 134, 206, 214, 41, 7, 221, 160, 238, 165, 79, 21, 214, 112, 178, 61, 11, 9], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 118 } } }, "3:59:embedded": { "1:0:bytes": [ 20, 105, 162, 168, 235, 1, 24, 192, 39, 86, 5, 217, 99, 35, 205, 139, 169, 93, 95, 58, 226, 208, 58, 100, 127, 228, 120, 31, 18, 41, 125, 188], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 24 } } }, "3:60:embedded": { "1:0:bytes": [ 34, 182, 106, 248, 174, 109, 85, 82, 233, 185, 158, 189, 109, 180, 122, 16, 147, 191, 174, 75, 237, 181, 28, 126, 154, 187, 117, 74, 222, 183, 40, 42], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 140 } } }, "3:61:embedded": { "1:0:bytes": [ 26, 231, 159, 209, 255, 47, 66, 73, 25, 159, 150, 146, 159, 24, 180, 147, 187, 127, 158, 136, 140, 26, 16, 163, 73, 22, 192, 248, 72, 201, 123, 70], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 160 } } }, "3:62:embedded": { "1:0:bytes": [ 203, 229, 192, 110, 98, 83, 18, 72, 171, 75, 44, 16, 145, 234, 53, 21, 92, 92, 252, 180, 147, 252, 134, 164, 131, 200, 84, 216, 173, 57, 215, 64], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 65 } } }, "3:63:embedded": { "1:0:bytes": [ 27, 37, 29, 129, 135, 60, 21, 21, 130, 47, 246, 84, 230, 29, 106, 8, 164, 126, 104, 33, 221, 10, 59, 198, 65, 59, 120, 175, 206, 115, 159, 192], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 150 } } }, "3:64:embedded": { "1:0:bytes": [ 247, 70, 240, 58, 235, 170, 216, 77, 82, 133, 127, 229, 69, 233, 41, 152, 29, 26, 140, 211, 60, 199, 111, 14, 228, 194, 135, 49, 207, 62, 100, 88], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 3 } } }, "3:65:embedded": { "1:0:embedded": { "3:0:bytes": [ 240, 189, 141, 59, 178, 229, 21, 207, 150, 181, 18, 214, 123, 229, 94, 213, 47, 55, 0, 35, 94, 176, 10, 239, 63, 91, 177, 203, 181, 232] }, "2:1:embedded": { "3:0:embedded": { "1:0:varint": 2 } } } }, "3:2:embedded": { "1:0:varint": 1, "2:1:embedded": { "1:0:bytes": [ 33, 255, 48, 173, 71, 120, 45, 62, 197, 131, 213, 202, 76, 94, 249, 217, 35, 187, 218, 99, 4, 123, 252, 140, 225, 146, 188, 168, 168, 162, 182, 43] }, "3:2:embedded": { "1:0:bytes": [ 25, 141, 201, 30, 174, 20, 216, 191, 35, 48, 111, 202, 181, 109, 38, 200, 22, 81, 86, 189, 190, 86, 13, 133, 64, 168, 191, 133, 34, 39, 191, 224], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 3 } } }, "3:3:embedded": { "1:0:bytes": [ 71, 158, 85, 141, 109, 205, 49, 21, 217, 217, 209, 39, 252, 123, 76, 99, 122, 134, 75, 8, 32, 224, 96, 181, 34, 239, 108, 110, 14, 13, 46, 205], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 2 } } } }, "3:3:embedded": { "1:0:varint": 0, "2:1:embedded": { "1:0:bytes": [ 203, 190, 37, 85, 163, 233, 86, 189, 68, 5, 138, 164, 64, 165, 54, 146, 237, 162, 128, 49, 148, 179, 51, 34, 217, 7, 38, 108, 182, 197, 160, 179] } }, "3:4:embedded": { "1:0:varint": 0, "2:1:embedded": { "1:0:bytes": [ 163, 159, 42, 53, 128, 115, 90, 161, 149, 19, 157, 15, 58, 113, 122, 238, 204, 104, 91, 216, 78, 131, 30, 240, 110, 166, 106, 159, 237, 125, 147, 82] }, "3:2:embedded": { "1:0:bytes": [ 57, 32, 198, 203, 112, 159, 189, 236, 244, 113, 104, 205, 165, 135, 237, 217, 163, 184, 202, 45, 241, 164, 164, 78, 112, 12, 177, 124, 204, 213, 16, 78], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 3 } } }, "3:3:embedded": { "1:0:bytes": [ 220, 184, 103, 130, 108, 220, 83, 140, 36, 238, 139, 5, 167, 253, 252, 136, 76, 43, 72, 36, 245, 92, 47, 147, 40, 134, 117, 179, 88, 9, 164, 70], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 2 } } } }, "3:5:embedded": { "1:0:varint": 1, "2:1:embedded": { "1:0:bytes": [ 240, 142, 243, 236, 188, 6, 32, 37, 148, 220, 19, 135, 176, 7, 175, 172, 234, 124, 152, 61, 115, 11, 68, 50, 219, 32, 182, 146, 2, 41, 153, 192] }, "3:2:embedded": { "1:0:bytes": [ 245, 12, 255, 55, 29, 151, 184, 242, 250, 247, 191, 244, 52, 251, 172, 66, 40, 242, 47, 67, 168, 136, 224, 201, 229, 16, 64, 4, 36, 207, 164, 97], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 3 } } }, "3:3:embedded": { "1:0:bytes": [ 98, 200, 36, 229, 239, 75, 96, 35, 195, 26, 180, 253, 4, 232, 178, 167, 173, 163, 171, 110, 154, 60, 20, 229, 82, 52, 201, 194, 199, 137, 188, 237], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 2 } } } }, "3:6:embedded": { "1:0:varint": 1, "2:1:embedded": { "1:0:bytes": [ 36, 1, 15, 223, 76, 25, 153, 9, 204, 90, 139, 114, 200, 122, 201, 226, 179, 79, 135, 58, 82, 134, 136, 184, 34, 249, 131, 132, 127, 38, 46, 245] }, "3:2:embedded": { "1:0:bytes": [ 110, 242, 238, 199, 145, 159, 168, 178, 187, 136, 71, 7, 156, 155, 102, 157, 218, 30, 147, 63, 91, 89, 147, 79, 29, 133, 10, 154, 77, 107, 15, 23], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 3 } } }, "3:3:embedded": { "1:0:bytes": [ 193, 203, 71, 244, 30, 18, 158, 188, 15, 77, 73, 13, 22, 120, 82, 107, 224, 130, 68, 135, 58, 123, 59, 135, 29, 86, 232, 139, 54, 74, 77, 121], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 2 } } } }, "3:7:embedded": { "1:0:varint": 0, "2:1:embedded": { "1:0:embedded": { "2:0:varint": 495613890054, "192224:1:float32": 4.882061335059751e-12, "13:2:float64": -1.0035307849984653e+45, "14:3:float64": -9.42824039531738e+194 } }, "3:2:embedded": { "1:0:bytes": [ 176, 193, 111, 217, 103, 210, 40, 38, 174, 253, 210, 197, 138, 118, 79, 56, 223, 186, 161, 214, 205, 215, 175, 9, 245, 199, 58, 188, 87, 17, 112, 187], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 3 } } }, "3:3:embedded": { "1:0:bytes": [ 233, 74, 153, 41, 23, 225, 3, 244, 202, 119, 170, 143, 9, 6, 210, 63, 125, 169, 131, 143, 182, 92, 221, 250, 202, 54, 145, 84, 30, 120, 18, 91], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 2 } } } }, "3:8:embedded": { "1:0:varint": 1, "2:1:embedded": { "1:0:bytes": [ 168, 15, 228, 127, 125, 117, 127, 138, 147, 171, 112, 68, 159, 126, 29, 136, 159, 179, 53, 127, 49, 203, 4, 114, 246, 31, 236, 30, 138, 177, 114, 180] }, "3:2:embedded": { "1:0:bytes": [ 175, 38, 148, 203, 5, 192, 218, 240, 99, 37, 193, 198, 171, 54, 171, 189, 43, 21, 47, 93, 178, 90, 122, 26, 84, 147, 81, 211, 72, 159, 117, 186], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 120 } } }, "3:3:embedded": { "1:0:bytes": [ 178, 168, 118, 168, 112, 230, 109, 168, 126, 135, 179, 184, 202, 71, 168, 52, 173, 232, 47, 90, 206, 58, 2, 36, 231, 168, 28, 159, 121, 169, 250, 225], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 160 } } }, "3:4:embedded": { "1:0:bytes": [ 27, 161, 172, 103, 148, 85, 34, 240, 54, 186, 19, 156, 128, 76, 161, 194, 205, 44, 121, 156, 95, 221, 165, 157, 48, 84, 171, 94, 213, 94, 38, 32], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 240 } } }, "3:5:embedded": { "1:0:bytes": [ 59, 22, 204, 77, 122, 25, 137, 251, 172, 27, 167, 105, 49, 28, 42, 101, 237, 95, 111, 59, 71, 48, 155, 192, 72, 229, 119, 45, 87, 83, 228, 126], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 320 } } }, "3:6:embedded": { "1:0:bytes": [ 8, 33, 151, 137, 172, 94, 16, 17, 78, 72, 18, 122, 33, 27, 94, 14, 210, 96, 130, 155, 222, 163, 85, 72, 14, 65, 157, 51, 80, 239, 102, 159], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 480 } } }, "3:7:embedded": { "1:0:bytes": [ 56, 238, 38, 244, 65, 33, 107, 152, 55, 119, 194, 4, 193, 171, 0, 161, 170, 76, 178, 1, 83, 171, 68, 124, 231, 251, 16, 58, 69, 140, 73, 27], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 640 } } }, "3:8:embedded": { "1:0:bytes": [ 234, 0, 220, 53, 6, 255, 39, 198, 77, 205, 185, 199, 74, 82, 77, 238, 19, 189, 175, 169, 229, 243, 213, 98, 178, 88, 114, 237, 130, 176, 18, 73], "2:1:embedded": { "1:0:embedded": { "1:0:varint": 213 } } }, "3:9:embedded": { "1:0:bytes": [ 185, 165, 104, 89, 84, 74, 209, 29, 242, 21, 183, 113, 130, 246, 55, 41, 106, 125, 21, 102, 221, 45, 71, 190, 159, 70, 149, 140, 48, 167, 19, 193], "2:1:embedded": { "5:0:embedded": { "1:0:varint": 40 } } }, "3:10:embedded": { "1:0:bytes": [ 220, 55, 196, 143, 179, 190, 76, 224, 62, 229, 56, 186, 142, 119, 251, 254, 170, 172, 89, 23, 229, 85, 169, 193, 135, 234, 5, 63, 19, 102, 182, 115], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 3 } } }, "3:11:embedded": { "1:0:bytes": [ 129, 101, 107, 114, 78, 83, 69, 51, 80, 76, 1, 218, 223, 168, 239, 110, 132, 179, 104, 145, 7, 183, 83, 83, 248, 208, 228, 139, 134, 120, 52, 26], "2:1:embedded": { "3:0:embedded": { "1:0:varint": 2 } } } }, "3:9:embedded": { "1:0:varint": 0, "2:1:embedded": { "1:0:bytes": [ 74, 175, 233, 99, 240, 93, 193, 197, 121, 201, 157, 138, 122, 204, 35, 17, 29, 212, 57, 239, 239, 42, 0, 122, 150, 248, 198, 205, 34, 3, 51, 162] } } } }, "7:5:varint": 1, "8:6:varint": 2, "9:7:varint": 2 } В данных изредка попадаются занятные строки: android.hardware.ram.low, com.samsung.feature.SAMSUNG_EXPERIENCE, com.google.android.apps.photos.PIXEL_2018_PRELOAD. Эти строки — не очень документированные имена функций, которые могут быть у устройства. Описание функций, если они есть, можно посмотреть, на устройстве в файлах в папке /etc/sysconfig/: adb shell cat /etc/sysconfig/pixel_experience_2017.xml
<?xml version="1.0" encoding="utf-8"?> <!-- These are configurations that should exist on Google's 2017 and newer Nexus devices. --> <config> <!-- This is meant to be the canonical feature identifying 2017 and newer Nexus devices. --> <feature name="com.google.android.feature.PIXEL_2017_EXPERIENCE" /> </config> adb shell cat /etc/sysconfig/pixel_2017_exclusive.xml <?xml version="1.0" encoding="utf-8"?> <!-- These are configurations that should exist on Google's 2017 devices (and not newer/older) --> <config> <!-- This defines the Photos preload feature for specifically the 2017 Pixel devices. --> <feature name="com.google.android.apps.photos.PIXEL_2017_PRELOAD" /> </config> В качестве документированного примера можно привести проверку наличия камеры запросом функции android.hardware.camera через метод hasSystemFeature класса PackageManager. Но зачем нужны эти строки, в данном контексте непонятно. Мне не удалось угадать, найти или восстановить схему данных из классов APK «Play Маркет». Если кто-то расскажет, что там и как получилось это определить, будет интересно. Пока есть только предположения разработчиков утилиты от Avast о структуре ProtoBuf и о том, что строка com.google.android.apps.photos.PIXEL_2018_PRELOAD указывает, является ли приложение системным/предустановленным: 1 <varint> = 1 // frosting versions?
2 <varint> = 0 3 <varint> = 1 4 <varint> = 1541545744578 // Timestamp of the frosting creation? 5 <chunk> = message: 8 <chunk> = message: 1 <chunk> = message(1 <varint> = 22) // minSdkLevel? 6 <varint> = 2 9 <chunk> = message: 1 <chunk> = message(1 <varint> = 2266, 4 <varint> = 2) // versionCode 2 <chunk> = message(1 <varint> = 50003, 4 <varint> = 4) 10 <chunk> = message: 1 <chunk> = bytes (30) // ?? only last byte changes across apks 0000 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0010 FF FE FF FF FF FF FF FF FF FF FF FF FF 3F '.............................?' 3 <chunk> = message: 1 <chunk> = bytes (32) // sha256 of something? 0000 16 F8 22 A6 93 26 89 34 D8 2A 88 BB 8C AD B6 68 0010 2C EB 77 A8 AA E4 5F AA F9 3C CA 63 44 2A A4 B9 '.."..&.4.*.....h,.w..._..<.cD*..' 2 <varint> = 20 Я бы хотел оставить несколько комментариев на этот счет. 1) По поводу строки com.google.android.apps.photos.PIXEL_2018_PRELOAD: легко доказать, что это неверное предположение. Скачаем несколько образов, предоставляемых Google, и увидим, что там нет не только таких строк, но и ни одного приложения, которое бы содержало блок Frosting. Можно рассмотреть это более детально на образе walleye for Pixel 2 9.0.0 (PQ3A.190801.002, Aug 2019). Установим образ и обнаружим, что среди всех 187 APK-файлов нет ни одного файла, содержащего блок Frosting. Если обновить все приложения, блок Frosting обнаружится у 33 из 264 APK-файлов. При этом только у пяти из них присутствуют строки:
Можно предположить, что эти строки определяют необходимость функций на устройстве, куда устанавливается приложение. Но запросим полный список функций устройства, на котором проводилось обновление, и убедимся, что это не так. Скрытый текстSPLadb shell pm list features
feature:reqGlEsVersion=0x30002 feature:android.hardware.audio.low_latency feature:android.hardware.audio.output feature:android.hardware.audio.pro feature:android.hardware.bluetooth feature:android.hardware.bluetooth_le feature:android.hardware.camera feature:android.hardware.camera.any feature:android.hardware.camera.ar feature:android.hardware.camera.autofocus feature:android.hardware.camera.capability.manual_post_processing feature:android.hardware.camera.capability.manual_sensor feature:android.hardware.camera.capability.raw feature:android.hardware.camera.flash feature:android.hardware.camera.front feature:android.hardware.camera.level.full feature:android.hardware.faketouch feature:android.hardware.fingerprint feature:android.hardware.location feature:android.hardware.location.gps feature:android.hardware.location.network feature:android.hardware.microphone feature:android.hardware.nfc feature:android.hardware.nfc.any feature:android.hardware.nfc.hce feature:android.hardware.nfc.hcef feature:android.hardware.opengles.aep feature:android.hardware.ram.normal feature:android.hardware.screen.landscape feature:android.hardware.screen.portrait feature:android.hardware.sensor.accelerometer feature:android.hardware.sensor.assist feature:android.hardware.sensor.barometer feature:android.hardware.sensor.compass feature:android.hardware.sensor.gyroscope feature:android.hardware.sensor.hifi_sensors feature:android.hardware.sensor.light feature:android.hardware.sensor.proximity feature:android.hardware.sensor.stepcounter feature:android.hardware.sensor.stepdetector feature:android.hardware.telephony feature:android.hardware.telephony.carrierlock feature:android.hardware.telephony.cdma feature:android.hardware.telephony.euicc feature:android.hardware.telephony.gsm feature:android.hardware.touchscreen feature:android.hardware.touchscreen.multitouch feature:android.hardware.touchscreen.multitouch.distinct feature:android.hardware.touchscreen.multitouch.jazzhand feature:android.hardware.usb.accessory feature:android.hardware.usb.host feature:android.hardware.vr.headtracking feature:android.hardware.vr.high_performance feature:android.hardware.vulkan.compute feature:android.hardware.vulkan.level feature:android.hardware.vulkan.version=4198400 feature:android.hardware.wifi feature:android.hardware.wifi.aware feature:android.hardware.wifi.direct feature:android.hardware.wifi.passpoint feature:android.hardware.wifi.rtt feature:android.software.activities_on_secondary_displays feature:android.software.app_widgets feature:android.software.autofill feature:android.software.backup feature:android.software.cant_save_state feature:android.software.companion_device_setup feature:android.software.connectionservice feature:android.software.cts feature:android.software.device_admin feature:android.software.device_id_attestation feature:android.software.file_based_encryption feature:android.software.home_screen feature:android.software.input_methods feature:android.software.live_wallpaper feature:android.software.managed_users feature:android.software.midi feature:android.software.picture_in_picture feature:android.software.print feature:android.software.securely_removes_users feature:android.software.sip feature:android.software.sip.voip feature:android.software.verified_boot feature:android.software.voice_recognizers feature:android.software.vr.mode feature:android.software.webview feature:com.google.android.apps.dialer.SUPPORTED feature:com.google.android.apps.photos.PIXEL_2017_PRELOAD feature:com.google.android.feature.EXCHANGE_6_2 feature:com.google.android.feature.GOOGLE_BUILD feature:com.google.android.feature.GOOGLE_EXPERIENCE feature:com.google.android.feature.PIXEL_2017_EXPERIENCE feature:com.google.android.feature.PIXEL_EXPERIENCE feature:com.google.android.feature.TURBO_PRELOAD feature:com.google.android.feature.WELLBEING feature:com.google.android.feature.ZERO_TOUCH feature:com.google.hardware.camera.easel feature:com.verizon.hardware.telephony.ehrpd feature:com.verizon.hardware.telephony.lte 2) С frosting versions я не согласен, так как можно найти похожие данные, но со значениями, отличными от 1. Максимальное значение этого поля, которое мне попадалось, –– 26. 3) С timestamp of the frosting creation я не согласен: я понаблюдал за конкретным приложением и заметил, что с выходом новых версий значение этого поля не обязательно растет. Оно скачет и может быть отрицательным. 4) MinSdkLevel и VersionCode выглядят правдоподобно. Заключение Итак, блок Frosting в подписи помогает однозначно определить, распространялся ли файл через официальный магазин. Больше никакой пользы из этой подписи извлечь не удалось. Ловите напоследок пример использования такой информации в отчете мобильной песочницы ApkLab: =========== Источник: habr.com =========== Похожие новости:
Блог компании BI.ZONE ), #_informatsionnaja_bezopasnost ( Информационная безопасность ), #_razrabotka_pod_android ( Разработка под Android ), #_reversinzhiniring ( Реверс-инжиниринг ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:25
Часовой пояс: UTC + 5