apk_extractor.c (55581B)
1 /* 2 This file is part of libextractor. 3 Copyright (C) 2026 Vidyut Samanta and Christian Grothoff 4 5 libextractor is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published 7 by the Free Software Foundation; either version 3, or (at your 8 option) any later version. 9 10 libextractor is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with libextractor; see the file COPYING. If not, write to the 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 /** 21 * @file plugins/apk_extractor.c 22 * @brief plugin to support Android packages and Java archives 23 * @author Christian Grothoff 24 * 25 * An APK and a JAR are both ZIP files, and so are a docx, an ODF 26 * document and any old archive, so the plugin identifies them by the 27 * member they must contain -- `AndroidManifest.xml' for an APK, 28 * `META-INF/MANIFEST.MF' for a JAR -- and returns without a word 29 * otherwise. An APK contains both, which is why the Android manifest 30 * is looked for first. 31 * 32 * What is worth having here is what the package may do (its declared 33 * permissions), what built it (the JDK or SDK version), and who signed 34 * it (the subject of the signing certificate). 35 * 36 * References: 37 * - AOSP frameworks/base/libs/androidfw/include/androidfw/ResourceTypes.h 38 * for the binary XML ("AXML") chunk format 39 * - https://source.android.com/docs/security/features/apksigning for the 40 * APK Signing Block 41 * - the JAR File Specification for `META-INF/MANIFEST.MF' 42 * - RFC 5652 (PKCS#7/CMS) and RFC 5280 for the signature block 43 */ 44 #include "platform.h" 45 #include "extractor.h" 46 #include "forensics.h" 47 #include "unzip.h" 48 49 50 /** 51 * Name we report our meta data under. 52 */ 53 #define PLUGIN_NAME "apk" 54 55 /** 56 * Never read more than this from `AndroidManifest.xml'. Real ones are 57 * a few tens of kilobytes even for very large applications. 58 */ 59 #define MAX_AXML (512 * 1024) 60 61 /** 62 * Never read more than this from `META-INF/MANIFEST.MF'. 63 */ 64 #define MAX_MANIFEST (256 * 1024) 65 66 /** 67 * Never read more than this from a `META-INF/*.RSA' signature block. 68 */ 69 #define MAX_PKCS7 (256 * 1024) 70 71 /** 72 * Never read more than this of the APK Signing Block. 73 */ 74 #define MAX_SIG_BLOCK (64 * 1024) 75 76 /** 77 * Upper bound on the number of ZIP members we walk. The end of central 78 * directory record counts entries in 16 bits, so this cannot be reached 79 * by a well-formed archive. 80 */ 81 #define MAX_MEMBERS 65535 82 83 /** 84 * Upper bound on the number of chunks and elements we walk in the 85 * binary XML. 86 */ 87 #define MAX_CHUNKS 65536 88 89 /** 90 * Upper bound on the number of strings in an AXML string pool. 91 */ 92 #define MAX_POOL_STRINGS 200000 93 94 /** 95 * Upper bound on the nesting depth we follow when walking DER. 96 */ 97 #define MAX_DER_DEPTH 16 98 99 /* AXML chunk types, from ResourceTypes.h */ 100 #define RES_XML_TYPE 0x0003 101 #define RES_STRING_POOL_TYPE 0x0001 102 #define RES_XML_START_ELEMENT_TYPE 0x0102 103 104 /* Res_value data types */ 105 #define TYPE_STRING 0x03 106 #define TYPE_INT_DEC 0x10 107 #define TYPE_INT_HEX 0x11 108 #define TYPE_INT_BOOLEAN 0x12 109 110 /* APK Signing Block pair identifiers */ 111 #define APK_SIG_SCHEME_V2 0x7109871AU 112 #define APK_SIG_SCHEME_V3 0xF05368C0U 113 #define APK_SIG_SCHEME_V31 0x1B93AD61U 114 115 116 /** 117 * A parsed AXML string pool. 118 */ 119 struct StringPool 120 { 121 /** 122 * Table of @e count 32 bit offsets into @e data. 123 */ 124 const unsigned char *offsets; 125 126 /** 127 * The string data itself. 128 */ 129 const unsigned char *data; 130 131 /** 132 * Number of bytes in @e data. 133 */ 134 size_t data_len; 135 136 /** 137 * Number of strings in the pool. 138 */ 139 uint32_t count; 140 141 /** 142 * True if the strings are UTF-8, false if they are UTF-16LE. 143 */ 144 int utf8; 145 }; 146 147 148 /** 149 * What we learned from walking the ZIP central directory. 150 */ 151 struct ArchiveFacts 152 { 153 /** 154 * Base name of the `META-INF/<alias>.RSA' (or .DSA, .EC) member, 155 * which is conventionally the signer's key alias. 156 */ 157 char sig_alias[128]; 158 159 /** 160 * Full member name of the signature block, empty if unsigned. 161 */ 162 char sig_member[256]; 163 164 /** 165 * Distinct ABI directory names seen under `lib/'. 166 */ 167 char abis[8][32]; 168 169 /** 170 * Number of entries used in @e abis. 171 */ 172 unsigned int num_abis; 173 174 /** 175 * Number of `classes*.dex' members. 176 */ 177 unsigned int num_dex; 178 179 /** 180 * Total number of members. 181 */ 182 unsigned int num_members; 183 }; 184 185 186 /** 187 * Find @a needle in @a hay. `memmem()' is a GNU extension and this only 188 * ever runs over buffers of a few tens of kilobytes. 189 * 190 * @param hay buffer to search 191 * @param hlen number of bytes in @a hay 192 * @param needle bytes to look for 193 * @param nlen number of bytes in @a needle 194 * @return pointer into @a hay, NULL if @a needle does not occur 195 */ 196 static const unsigned char * 197 mem_find (const unsigned char *hay, 198 size_t hlen, 199 const char *needle, 200 size_t nlen) 201 { 202 if ( (0 == nlen) || 203 (nlen > hlen) ) 204 return NULL; 205 for (size_t i = 0; i + nlen <= hlen; i++) 206 if (0 == memcmp (&hay[i], 207 needle, 208 nlen)) 209 return &hay[i]; 210 return NULL; 211 } 212 213 214 /** 215 * Read a whole member out of a ZIP archive. 216 * 217 * @param uf the archive 218 * @param name member to read 219 * @param cap never read more than this many bytes 220 * @param[out] len number of bytes read 221 * @return the member's contents with a NUL appended, NULL on error; 222 * caller must free 223 */ 224 static unsigned char * 225 read_member (struct EXTRACTOR_UnzipFile *uf, 226 const char *name, 227 size_t cap, 228 size_t *len) 229 { 230 struct EXTRACTOR_UnzipFileInfo fi; 231 unsigned char *buf; 232 size_t size; 233 size_t got = 0; 234 235 *len = 0; 236 if (EXTRACTOR_UNZIP_OK != 237 EXTRACTOR_common_unzip_go_find_local_file (uf, 238 name, 239 2)) 240 return NULL; 241 if (EXTRACTOR_UNZIP_OK != 242 EXTRACTOR_common_unzip_get_current_file_info (uf, 243 &fi, 244 NULL, 0, 245 NULL, 0, 246 NULL, 0)) 247 return NULL; 248 size = (size_t) fi.uncompressed_size; 249 if (0 == size) 250 return NULL; 251 if (size > cap) 252 size = cap; 253 if (NULL == (buf = malloc (size + 1))) 254 return NULL; 255 if (EXTRACTOR_UNZIP_OK != 256 EXTRACTOR_common_unzip_open_current_file (uf)) 257 { 258 free (buf); 259 return NULL; 260 } 261 while (got < size) 262 { 263 ssize_t ret; 264 265 ret = EXTRACTOR_common_unzip_read_current_file (uf, 266 &buf[got], 267 size - got); 268 if (0 >= ret) 269 break; /* error or end of member */ 270 if (((size_t) ret) > size - got) 271 break; /* cannot happen, but do not overrun if it does */ 272 got += (size_t) ret; 273 } 274 (void) EXTRACTOR_common_unzip_close_current_file (uf); 275 if (0 == got) 276 { 277 free (buf); 278 return NULL; 279 } 280 buf[got] = '\0'; 281 *len = got; 282 return buf; 283 } 284 285 286 /* ------------------------------------------------------------------ */ 287 /* JAR manifest */ 288 /* ------------------------------------------------------------------ */ 289 290 291 /** 292 * Report the value of one `META-INF/MANIFEST.MF' header, if it is one 293 * we care about. 294 * 295 * @param ec extraction context 296 * @param key header name, NUL-terminated 297 * @param value header value, NUL-terminated and already unfolded 298 * @return 1 if the caller should stop extracting, 0 to continue 299 */ 300 static int 301 emit_manifest_header (struct EXTRACTOR_ExtractContext *ec, 302 const char *key, 303 const char *value) 304 { 305 static const struct 306 { 307 const char *key; 308 enum EXTRACTOR_MetaType type; 309 } map[] = { 310 { "Main-Class", EXTRACTOR_METATYPE_ENTRY_POINT }, 311 /* these three name the exact JDK the archive was built with */ 312 { "Created-By", EXTRACTOR_METATYPE_TOOLCHAIN }, 313 { "Build-Jdk", EXTRACTOR_METATYPE_TOOLCHAIN }, 314 { "Build-Jdk-Spec", EXTRACTOR_METATYPE_TOOLCHAIN }, 315 { "Class-Path", EXTRACTOR_METATYPE_LIBRARY_DEPENDENCY }, 316 { "Implementation-Title", EXTRACTOR_METATYPE_TITLE }, 317 { "Implementation-Version", EXTRACTOR_METATYPE_SOFTWARE_VERSION }, 318 { "Implementation-Vendor", EXTRACTOR_METATYPE_VENDOR }, 319 { "Implementation-URL", EXTRACTOR_METATYPE_URL }, 320 { "Specification-Title", EXTRACTOR_METATYPE_SUBJECT }, 321 { "Specification-Version", EXTRACTOR_METATYPE_FORMAT_VERSION }, 322 { "Specification-Vendor", EXTRACTOR_METATYPE_ORGANIZATION }, 323 /* OSGi bundle headers */ 324 { "Bundle-SymbolicName", EXTRACTOR_METATYPE_APPLICATION_ID }, 325 { "Bundle-Name", EXTRACTOR_METATYPE_PRODUCT_NAME }, 326 { "Bundle-Version", EXTRACTOR_METATYPE_PACKAGE_VERSION }, 327 { "Bundle-Vendor", EXTRACTOR_METATYPE_VENDOR }, 328 { "Bundle-Description", EXTRACTOR_METATYPE_DESCRIPTION }, 329 { "Bundle-License", EXTRACTOR_METATYPE_LICENSE }, 330 { "Bundle-RequiredExecutionEnvironment", 331 EXTRACTOR_METATYPE_MINIMUM_OS_VERSION }, 332 { "Import-Package", EXTRACTOR_METATYPE_LIBRARY_DEPENDENCY }, 333 { NULL, EXTRACTOR_METATYPE_RESERVED } 334 }; 335 336 for (unsigned int i = 0; NULL != map[i].key; i++) 337 if (0 == strcasecmp (key, 338 map[i].key)) 339 return EXTRACTOR_forensic_emit_text_ (ec, 340 PLUGIN_NAME, 341 map[i].type, 342 value, 343 strlen (value)); 344 return 0; 345 } 346 347 348 /** 349 * Walk the main section of a `META-INF/MANIFEST.MF'. 350 * 351 * The format is `Key: Value' with CRLF line breaks, and no line may 352 * exceed 72 bytes, so long values are broken across continuation lines 353 * that begin with a single space which is not part of the value. Only 354 * the main section (everything before the first blank line) describes 355 * the archive; what follows is one section per signed member. 356 * 357 * @param ec extraction context 358 * @param data the manifest 359 * @param len number of bytes in @a data 360 * @return 1 if the caller should stop extracting, 0 to continue 361 */ 362 static int 363 parse_jar_manifest (struct EXTRACTOR_ExtractContext *ec, 364 const char *data, 365 size_t len) 366 { 367 char key[128]; 368 char value[EXTRACTOR_FORENSIC_MAX_STRING]; 369 size_t pos = 0; 370 size_t klen = 0; 371 size_t vlen = 0; 372 unsigned int headers = 0; 373 374 key[0] = '\0'; 375 while ( (pos < len) && 376 (headers < 256) ) 377 { 378 const char *nl; 379 const char *line; 380 size_t line_len; 381 const char *colon; 382 383 nl = memchr (&data[pos], 384 '\n', 385 len - pos); 386 line = &data[pos]; 387 line_len = (NULL == nl) 388 ? len - pos 389 : (size_t) (nl - line); 390 pos += line_len + ((NULL == nl) ? 0 : 1); 391 if ( (0 < line_len) && 392 ('\r' == line[line_len - 1]) ) 393 line_len--; 394 if (0 == line_len) 395 break; /* end of the main section */ 396 if (' ' == line[0]) 397 { 398 /* continuation of the previous header */ 399 size_t add = line_len - 1; 400 401 if (0 == klen) 402 continue; /* continuation without a header; ignore */ 403 if (add > sizeof (value) - 1 - vlen) 404 add = sizeof (value) - 1 - vlen; 405 memcpy (&value[vlen], 406 &line[1], 407 add); 408 vlen += add; 409 value[vlen] = '\0'; 410 continue; 411 } 412 /* a new header starts, so the previous one is complete */ 413 if ( (0 != klen) && 414 (0 != emit_manifest_header (ec, 415 key, 416 value)) ) 417 return 1; 418 klen = 0; 419 vlen = 0; 420 headers++; 421 colon = memchr (line, 422 ':', 423 line_len); 424 if (NULL == colon) 425 continue; 426 klen = (size_t) (colon - line); 427 if (klen > sizeof (key) - 1) 428 klen = sizeof (key) - 1; 429 memcpy (key, 430 line, 431 klen); 432 key[klen] = '\0'; 433 vlen = line_len - (size_t) (colon - line) - 1; 434 if ( (0 < vlen) && 435 (' ' == colon[1]) ) 436 { 437 colon++; 438 vlen--; 439 } 440 if (vlen > sizeof (value) - 1) 441 vlen = sizeof (value) - 1; 442 memcpy (value, 443 &colon[1], 444 vlen); 445 value[vlen] = '\0'; 446 } 447 if ( (0 != klen) && 448 (0 != emit_manifest_header (ec, 449 key, 450 value)) ) 451 return 1; 452 return 0; 453 } 454 455 456 /* ------------------------------------------------------------------ */ 457 /* PKCS#7 signature block */ 458 /* ------------------------------------------------------------------ */ 459 460 461 /** 462 * One DER tag-length-value triple. 463 */ 464 struct Tlv 465 { 466 /** 467 * The tag byte. 468 */ 469 unsigned int tag; 470 471 /** 472 * Offset of the value within the enclosing buffer. 473 */ 474 size_t start; 475 476 /** 477 * Number of bytes in the value. 478 */ 479 size_t len; 480 481 /** 482 * Offset just past the value, i.e. where the next TLV begins. 483 */ 484 size_t next; 485 }; 486 487 488 /** 489 * Decode the DER tag-length-value triple at @a pos. 490 * 491 * Only the definite-length, low-tag-number form is accepted; a 492 * certificate that needs anything else is not one we are going to 493 * understand anyway. 494 * 495 * @param buf the buffer 496 * @param end offset just past the region the TLV must fit in 497 * @param pos offset of the tag byte 498 * @param[out] tlv where to store the result 499 * @return 1 on success, 0 if the encoding is malformed or truncated 500 */ 501 static int 502 der_read (const unsigned char *buf, 503 size_t end, 504 size_t pos, 505 struct Tlv *tlv) 506 { 507 uint64_t len; 508 size_t p = pos; 509 510 if (p + 2 > end) 511 return 0; 512 tlv->tag = buf[p]; 513 if (0x1F == (tlv->tag & 0x1F)) 514 return 0; /* high tag number form */ 515 p++; 516 if (buf[p] < 0x80) 517 { 518 len = buf[p]; 519 p++; 520 } 521 else 522 { 523 unsigned int n = buf[p] & 0x7F; 524 525 if ( (0 == n) || 526 (n > 4) ) 527 return 0; /* indefinite length, or longer than we will ever want */ 528 p++; 529 if (p + n > end) 530 return 0; 531 len = 0; 532 for (unsigned int i = 0; i < n; i++) 533 len = (len << 8) | buf[p + i]; 534 p += n; 535 } 536 if (len > (uint64_t) (end - p)) 537 return 0; 538 tlv->start = p; 539 tlv->len = (size_t) len; 540 tlv->next = p + (size_t) len; 541 return 1; 542 } 543 544 545 /** 546 * Append the short name for an X.500 attribute type to @a out. 547 * 548 * Attribute types we do not have a name for are skipped rather than 549 * spelled as an OID: a distinguished name that uses one is not one a 550 * human is going to recognise either way. 551 * 552 * @param oid the OID's content bytes 553 * @param len number of bytes in @a oid 554 * @return the short name, NULL if unknown 555 */ 556 static const char * 557 x500_name (const unsigned char *oid, 558 size_t len) 559 { 560 static const struct 561 { 562 const char *name; 563 size_t len; 564 const unsigned char oid[12]; 565 } known[] = { 566 { "CN", 3, { 0x55, 0x04, 0x03 } }, 567 { "SN", 3, { 0x55, 0x04, 0x04 } }, 568 { "serialNumber", 3, { 0x55, 0x04, 0x05 } }, 569 { "C", 3, { 0x55, 0x04, 0x06 } }, 570 { "L", 3, { 0x55, 0x04, 0x07 } }, 571 { "ST", 3, { 0x55, 0x04, 0x08 } }, 572 { "STREET", 3, { 0x55, 0x04, 0x09 } }, 573 { "O", 3, { 0x55, 0x04, 0x0A } }, 574 { "OU", 3, { 0x55, 0x04, 0x0B } }, 575 { "T", 3, { 0x55, 0x04, 0x0C } }, 576 { "GN", 3, { 0x55, 0x04, 0x2A } }, 577 { "emailAddress", 9, 578 { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01 } }, 579 { "DC", 10, 580 { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19 } }, 581 { "UID", 10, 582 { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x01 } }, 583 { NULL, 0, { 0 } } 584 }; 585 586 for (unsigned int i = 0; NULL != known[i].name; i++) 587 if ( (known[i].len == len) && 588 (0 == memcmp (known[i].oid, 589 oid, 590 len)) ) 591 return known[i].name; 592 return NULL; 593 } 594 595 596 /** 597 * Render an X.501 `Name' as an RFC 4514 style distinguished name. 598 * 599 * The relative distinguished names are emitted in the order they appear 600 * in the encoding, which is what `openssl x509 -subject' prints too. 601 * 602 * @param buf buffer holding the encoding 603 * @param name the `Name' TLV (a SEQUENCE OF RelativeDistinguishedName) 604 * @param[out] out where to write the result, NUL-terminated 605 * @param outsz number of bytes available in @a out, at least 2 606 * @return 1 on success, 0 if nothing could be rendered 607 */ 608 static int 609 der_render_name (const unsigned char *buf, 610 const struct Tlv *name, 611 char *out, 612 size_t outsz) 613 { 614 size_t o = 0; 615 size_t pos = name->start; 616 unsigned int rdns = 0; 617 618 out[0] = '\0'; 619 while ( (pos < name->start + name->len) && 620 (rdns++ < 32) ) 621 { 622 struct Tlv rdn; 623 size_t apos; 624 625 if (! der_read (buf, 626 name->start + name->len, 627 pos, 628 &rdn)) 629 break; 630 pos = rdn.next; 631 if (0x31 != rdn.tag) 632 continue; /* not a SET */ 633 apos = rdn.start; 634 while (apos < rdn.start + rdn.len) 635 { 636 struct Tlv atv; 637 struct Tlv oid; 638 struct Tlv value; 639 const char *label; 640 641 if (! der_read (buf, 642 rdn.start + rdn.len, 643 apos, 644 &atv)) 645 break; 646 apos = atv.next; 647 if (0x30 != atv.tag) 648 continue; 649 if (! der_read (buf, 650 atv.start + atv.len, 651 atv.start, 652 &oid)) 653 continue; 654 if (0x06 != oid.tag) 655 continue; 656 if (! der_read (buf, 657 atv.start + atv.len, 658 oid.next, 659 &value)) 660 continue; 661 /* UTF8String, PrintableString, T61String, IA5String; BMPString 662 and UniversalString are left out because they would need a 663 conversion we would only ever exercise on broken input */ 664 if ( (0x0C != value.tag) && 665 (0x13 != value.tag) && 666 (0x14 != value.tag) && 667 (0x16 != value.tag) ) 668 continue; 669 label = x500_name (&buf[oid.start], 670 oid.len); 671 if (NULL == label) 672 continue; 673 if (0 != o) 674 { 675 if (o + 2 >= outsz) 676 break; 677 out[o++] = ','; 678 out[o++] = ' '; 679 } 680 if (o + strlen (label) + 1 >= outsz) 681 break; 682 memcpy (&out[o], 683 label, 684 strlen (label)); 685 o += strlen (label); 686 out[o++] = '='; 687 for (size_t i = 0; i < value.len; i++) 688 { 689 unsigned char c = buf[value.start + i]; 690 691 if (o + 2 >= outsz) 692 break; 693 /* RFC 4514 escaping, so that a CN containing a comma cannot 694 look like two relative distinguished names */ 695 if ( (',' == c) || ('+' == c) || ('"' == c) || ('\\' == c) || 696 ('<' == c) || ('>' == c) || (';' == c) ) 697 out[o++] = '\\'; 698 out[o++] = (char) c; 699 } 700 } 701 } 702 out[o] = '\0'; 703 return (0 != o); 704 } 705 706 707 /** 708 * Pull the signer's distinguished name out of a PKCS#7 signature block. 709 * 710 * The certificates in a `META-INF/*.RSA' come in no particular order -- 711 * in a chain signed archive the certificate authority typically comes 712 * first -- so the signer is identified the way RFC 5652 says: by 713 * matching the SignerInfo's issuerAndSerialNumber against each 714 * certificate's issuer and serial number. 715 * 716 * @param buf the DER encoding 717 * @param len number of bytes in @a buf 718 * @param[out] out where to write the distinguished name, NUL-terminated 719 * @param outsz number of bytes available in @a out, at least 2 720 * @return 1 on success, 0 if the block could not be understood 721 */ 722 static int 723 pkcs7_signer_dn (const unsigned char *buf, 724 size_t len, 725 char *out, 726 size_t outsz) 727 { 728 struct Tlv content_info; 729 struct Tlv oid; 730 struct Tlv explicit0; 731 struct Tlv signed_data; 732 struct Tlv tlv; 733 struct Tlv certs; 734 struct Tlv signer_infos; 735 struct Tlv signer_issuer; 736 struct Tlv signer_serial; 737 size_t pos; 738 size_t end; 739 int have_signer = 0; 740 int have_certs = 0; 741 unsigned int fields = 0; 742 743 out[0] = '\0'; 744 if (! der_read (buf, len, 0, &content_info)) 745 return 0; 746 if (0x30 != content_info.tag) 747 return 0; 748 end = content_info.start + content_info.len; 749 if (! der_read (buf, end, content_info.start, &oid)) 750 return 0; 751 if (0x06 != oid.tag) 752 return 0; 753 if (! der_read (buf, end, oid.next, &explicit0)) 754 return 0; 755 if (0xA0 != explicit0.tag) 756 return 0; 757 if (! der_read (buf, 758 explicit0.start + explicit0.len, 759 explicit0.start, 760 &signed_data)) 761 return 0; 762 if (0x30 != signed_data.tag) 763 return 0; 764 /* SignedData ::= SEQUENCE { version, digestAlgorithms, contentInfo, 765 [0] certificates OPTIONAL, 766 [1] crls OPTIONAL, signerInfos } 767 The first three fields have to be stepped over positionally: 768 digestAlgorithms is a SET and so is signerInfos, so a search by tag 769 would stop at the wrong one. */ 770 end = signed_data.start + signed_data.len; 771 pos = signed_data.start; 772 for (unsigned int i = 0; i < 3; i++) 773 { 774 if (! der_read (buf, end, pos, &tlv)) 775 return 0; 776 pos = tlv.next; 777 } 778 memset (&signer_infos, 779 0, 780 sizeof (signer_infos)); 781 while ( (pos < end) && 782 (fields++ < MAX_DER_DEPTH) ) 783 { 784 if (! der_read (buf, end, pos, &tlv)) 785 return 0; 786 pos = tlv.next; 787 if (0xA0 == tlv.tag) 788 { 789 certs = tlv; 790 have_certs = 1; 791 } 792 else if (0x31 == tlv.tag) 793 { 794 signer_infos = tlv; 795 break; 796 } 797 } 798 if (! have_certs) 799 return 0; 800 /* SignerInfo ::= SEQUENCE { version, issuerAndSerialNumber, ... } */ 801 if (der_read (buf, 802 signer_infos.start + signer_infos.len, 803 signer_infos.start, 804 &tlv) && 805 (0x30 == tlv.tag)) 806 { 807 struct Tlv version; 808 struct Tlv ias; 809 810 if (der_read (buf, tlv.start + tlv.len, tlv.start, &version) && 811 der_read (buf, tlv.start + tlv.len, version.next, &ias) && 812 (0x30 == ias.tag) && 813 der_read (buf, ias.start + ias.len, ias.start, &signer_issuer) && 814 der_read (buf, ias.start + ias.len, signer_issuer.next, 815 &signer_serial) && 816 (0x30 == signer_issuer.tag) && 817 (0x02 == signer_serial.tag)) 818 have_signer = 1; 819 } 820 /* walk the certificates and take the one the SignerInfo points at */ 821 pos = certs.start; 822 end = certs.start + certs.len; 823 for (unsigned int i = 0; (pos < end) && (i < 32); i++) 824 { 825 struct Tlv cert; 826 struct Tlv tbs; 827 struct Tlv field; 828 struct Tlv serial; 829 struct Tlv issuer; 830 struct Tlv validity; 831 struct Tlv subject; 832 833 if (! der_read (buf, end, pos, &cert)) 834 break; 835 pos = cert.next; 836 if (0x30 != cert.tag) 837 continue; 838 if (! der_read (buf, cert.start + cert.len, cert.start, &tbs)) 839 continue; 840 if (0x30 != tbs.tag) 841 continue; 842 /* TBSCertificate ::= SEQUENCE { [0] version DEFAULT v1, 843 serialNumber, signature, issuer, validity, subject, ... } */ 844 if (! der_read (buf, tbs.start + tbs.len, tbs.start, &field)) 845 continue; 846 if (0xA0 == field.tag) 847 { 848 if (! der_read (buf, tbs.start + tbs.len, field.next, &serial)) 849 continue; 850 } 851 else 852 { 853 serial = field; 854 } 855 if (0x02 != serial.tag) 856 continue; 857 if (! der_read (buf, tbs.start + tbs.len, serial.next, &field)) 858 continue; /* signature algorithm */ 859 if (! der_read (buf, tbs.start + tbs.len, field.next, &issuer)) 860 continue; 861 if (0x30 != issuer.tag) 862 continue; 863 if (! der_read (buf, tbs.start + tbs.len, issuer.next, &validity)) 864 continue; 865 if (! der_read (buf, tbs.start + tbs.len, validity.next, &subject)) 866 continue; 867 if (0x30 != subject.tag) 868 continue; 869 if (have_signer) 870 { 871 /* RFC 5652 identifies the signer's certificate by issuer name 872 and serial number, so match on both */ 873 if ( (signer_serial.len != serial.len) || 874 (0 != memcmp (&buf[signer_serial.start], 875 &buf[serial.start], 876 serial.len)) ) 877 continue; 878 if ( (signer_issuer.len != issuer.len) || 879 (0 != memcmp (&buf[signer_issuer.start], 880 &buf[issuer.start], 881 issuer.len)) ) 882 continue; 883 } 884 return der_render_name (buf, 885 &subject, 886 out, 887 outsz); 888 } 889 return 0; 890 } 891 892 893 /* ------------------------------------------------------------------ */ 894 /* binary XML */ 895 /* ------------------------------------------------------------------ */ 896 897 898 /** 899 * Fetch string number @a idx out of an AXML string pool, converted to 900 * UTF-8 and NUL-terminated. 901 * 902 * @param sp the pool 903 * @param idx index of the string 904 * @param[out] out where to write the string 905 * @param outsz number of bytes available in @a out, at least 8 906 * @return number of bytes written, 0 if the string could not be read 907 */ 908 static size_t 909 pool_string (const struct StringPool *sp, 910 uint32_t idx, 911 char *out, 912 size_t outsz) 913 { 914 const unsigned char *p; 915 size_t avail; 916 uint32_t off; 917 918 out[0] = '\0'; 919 if ( (NULL == sp->offsets) || 920 (idx >= sp->count) ) 921 return 0; 922 off = EXTRACTOR_forensic_le32_ (&sp->offsets[4 * (size_t) idx]); 923 if (((size_t) off) >= sp->data_len) 924 return 0; 925 p = &sp->data[off]; 926 avail = sp->data_len - off; 927 if (sp->utf8) 928 { 929 size_t k = 0; 930 size_t n8; 931 932 /* two varints: the length in UTF-16 code units, then the length in 933 bytes; a leading set high bit means the value takes two bytes */ 934 if (avail < 1) 935 return 0; 936 if (0 != (p[k] & 0x80)) 937 { 938 if (avail < 2) 939 return 0; 940 k += 2; 941 } 942 else 943 { 944 k += 1; 945 } 946 if (avail < k + 1) 947 return 0; 948 if (0 != (p[k] & 0x80)) 949 { 950 if (avail < k + 2) 951 return 0; 952 n8 = (size_t) (((((size_t) p[k]) & 0x7F) << 8) | p[k + 1]); 953 k += 2; 954 } 955 else 956 { 957 n8 = p[k]; 958 k += 1; 959 } 960 if (n8 > avail - k) 961 return 0; 962 if (n8 > outsz - 1) 963 n8 = outsz - 1; 964 memcpy (out, 965 &p[k], 966 n8); 967 out[n8] = '\0'; 968 if (! EXTRACTOR_forensic_utf8_valid_ (out, 969 n8)) 970 { 971 out[0] = '\0'; 972 return 0; 973 } 974 return n8; 975 } 976 { 977 size_t k = 2; 978 size_t n16; 979 size_t o = 0; 980 981 if (avail < 2) 982 return 0; 983 n16 = EXTRACTOR_forensic_le16_ (p); 984 if (0 != (n16 & 0x8000)) 985 { 986 if (avail < 4) 987 return 0; 988 n16 = (((n16 & 0x7FFF) << 16) 989 | EXTRACTOR_forensic_le16_ (&p[2])); 990 k = 4; 991 } 992 if (n16 > (avail - k) / 2) 993 return 0; 994 for (size_t i = 0; i < n16; i++) 995 { 996 uint32_t cp = EXTRACTOR_forensic_le16_ (&p[k + 2 * i]); 997 998 if ( (0xD800 <= cp) && (0xDBFF >= cp) && (i + 1 < n16) ) 999 { 1000 uint32_t lo = EXTRACTOR_forensic_le16_ (&p[k + 2 * (i + 1)]); 1001 1002 if ( (0xDC00 <= lo) && (0xDFFF >= lo) ) 1003 { 1004 cp = 0x10000 + ((cp - 0xD800) << 10) + (lo - 0xDC00); 1005 i++; 1006 } 1007 } 1008 if ( (0xD800 <= cp) && (0xDFFF >= cp) ) 1009 break; /* unpaired surrogate; stop rather than guess */ 1010 if (cp < 0x80) 1011 { 1012 if (o + 2 > outsz) 1013 break; 1014 out[o++] = (char) cp; 1015 } 1016 else if (cp < 0x800) 1017 { 1018 if (o + 3 > outsz) 1019 break; 1020 out[o++] = (char) (0xC0 | (cp >> 6)); 1021 out[o++] = (char) (0x80 | (cp & 0x3F)); 1022 } 1023 else if (cp < 0x10000) 1024 { 1025 if (o + 4 > outsz) 1026 break; 1027 out[o++] = (char) (0xE0 | (cp >> 12)); 1028 out[o++] = (char) (0x80 | ((cp >> 6) & 0x3F)); 1029 out[o++] = (char) (0x80 | (cp & 0x3F)); 1030 } 1031 else 1032 { 1033 if (o + 5 > outsz) 1034 break; 1035 out[o++] = (char) (0xF0 | (cp >> 18)); 1036 out[o++] = (char) (0x80 | ((cp >> 12) & 0x3F)); 1037 out[o++] = (char) (0x80 | ((cp >> 6) & 0x3F)); 1038 out[o++] = (char) (0x80 | (cp & 0x3F)); 1039 } 1040 } 1041 out[o] = '\0'; 1042 return o; 1043 } 1044 } 1045 1046 1047 /** 1048 * Spell an Android API level as the marketing version people recognise. 1049 * 1050 * @param api the API level 1051 * @return the version string, NULL if the level is not in the table 1052 */ 1053 static const char * 1054 android_release (uint32_t api) 1055 { 1056 static const char *table[] = { 1057 NULL, "1.0", "1.1", "1.5", "1.6", "2.0", "2.0.1", "2.1", "2.2", 1058 "2.3", "2.3.3", "3.0", "3.1", "3.2", "4.0", "4.0.3", "4.1", "4.2", 1059 "4.3", "4.4", "4.4W", "5.0", "5.1", "6.0", "7.0", "7.1", "8.0", 1060 "8.1", "9", "10", "11", "12", "12L", "13", "14", "15", "16" 1061 }; 1062 1063 if ( (0 == api) || 1064 (api >= sizeof (table) / sizeof (table[0])) ) 1065 return NULL; 1066 return table[api]; 1067 } 1068 1069 1070 /** 1071 * Report an API level, naming the Android release where we know it. 1072 * 1073 * @param ec extraction context 1074 * @param type meta data type 1075 * @param api the API level 1076 * @return 1 if the caller should stop extracting, 0 to continue 1077 */ 1078 static int 1079 emit_api_level (struct EXTRACTOR_ExtractContext *ec, 1080 enum EXTRACTOR_MetaType type, 1081 uint32_t api) 1082 { 1083 const char *rel = android_release (api); 1084 1085 if (NULL == rel) 1086 return EXTRACTOR_forensic_emit_ (ec, 1087 PLUGIN_NAME, 1088 type, 1089 "Android API %u", 1090 (unsigned int) api); 1091 return EXTRACTOR_forensic_emit_ (ec, 1092 PLUGIN_NAME, 1093 type, 1094 "Android API %u (Android %s)", 1095 (unsigned int) api, 1096 rel); 1097 } 1098 1099 1100 /** 1101 * Report the attributes of one AXML element, if it is an element we 1102 * care about. 1103 * 1104 * @param ec extraction context 1105 * @param sp the string pool 1106 * @param element the element's name 1107 * @param attrs pointer to the first attribute 1108 * @param count number of attributes 1109 * @param stride number of bytes per attribute 1110 * @param[in,out] permissions number of permissions reported so far 1111 * @param[in,out] have_sdk set once compileSdkVersion has been reported 1112 * @return 1 if the caller should stop extracting, 0 to continue 1113 */ 1114 static int 1115 emit_element (struct EXTRACTOR_ExtractContext *ec, 1116 const struct StringPool *sp, 1117 const char *element, 1118 const unsigned char *attrs, 1119 unsigned int count, 1120 size_t stride, 1121 unsigned int *permissions, 1122 int *have_sdk) 1123 { 1124 int is_manifest = (0 == strcmp (element, "manifest")); 1125 int is_uses_sdk = (0 == strcmp (element, "uses-sdk")); 1126 int is_permission = (0 == strcmp (element, "uses-permission")); 1127 int is_application = (0 == strcmp (element, "application")); 1128 1129 if (! (is_manifest || is_uses_sdk || is_permission || is_application)) 1130 return 0; 1131 for (unsigned int i = 0; i < count; i++) 1132 { 1133 const unsigned char *a = &attrs[i * stride]; 1134 char name[128]; 1135 char value[EXTRACTOR_FORENSIC_MAX_STRING]; 1136 uint32_t data; 1137 unsigned int dtype; 1138 1139 if (0 == pool_string (sp, 1140 EXTRACTOR_forensic_le32_ (&a[4]), 1141 name, 1142 sizeof (name))) 1143 continue; /* attribute names are given by resource id only in 1144 files aapt did not produce; we do not guess */ 1145 dtype = a[15]; 1146 data = EXTRACTOR_forensic_le32_ (&a[16]); 1147 value[0] = '\0'; 1148 if (TYPE_STRING == dtype) 1149 (void) pool_string (sp, 1150 data, 1151 value, 1152 sizeof (value)); 1153 if (is_manifest) 1154 { 1155 if ( (0 == strcmp (name, "package")) && 1156 (TYPE_STRING == dtype) ) 1157 { 1158 if (0 != 1159 EXTRACTOR_forensic_emit_text_ (ec, 1160 PLUGIN_NAME, 1161 EXTRACTOR_METATYPE_PACKAGE_NAME, 1162 value, 1163 strlen (value))) 1164 return 1; 1165 } 1166 else if (0 == strcmp (name, "versionCode")) 1167 { 1168 if (TYPE_STRING == dtype) 1169 { 1170 if (0 != 1171 EXTRACTOR_forensic_emit_text_ ( 1172 ec, 1173 PLUGIN_NAME, 1174 EXTRACTOR_METATYPE_PACKAGE_VERSION, 1175 value, 1176 strlen (value))) 1177 return 1; 1178 } 1179 else if (0 != 1180 EXTRACTOR_forensic_emit_ ( 1181 ec, 1182 PLUGIN_NAME, 1183 EXTRACTOR_METATYPE_PACKAGE_VERSION, 1184 "%u", 1185 (unsigned int) data)) 1186 return 1; 1187 } 1188 else if ( (0 == strcmp (name, "versionName")) && 1189 (TYPE_STRING == dtype) ) 1190 { 1191 if (0 != 1192 EXTRACTOR_forensic_emit_text_ ( 1193 ec, 1194 PLUGIN_NAME, 1195 EXTRACTOR_METATYPE_SOFTWARE_VERSION, 1196 value, 1197 strlen (value))) 1198 return 1; 1199 } 1200 else if ( (0 == strcmp (name, "compileSdkVersion")) && 1201 (TYPE_STRING != dtype) ) 1202 { 1203 *have_sdk = 1; 1204 if (0 != 1205 emit_api_level (ec, 1206 EXTRACTOR_METATYPE_TOOLCHAIN, 1207 data)) 1208 return 1; 1209 } 1210 else if ( (0 == strcmp (name, "platformBuildVersionCode")) && 1211 (TYPE_STRING != dtype) && 1212 (! *have_sdk) ) 1213 { 1214 /* what older builds of aapt wrote instead of 1215 compileSdkVersion; reporting both would say the same thing 1216 twice */ 1217 *have_sdk = 1; 1218 if (0 != 1219 emit_api_level (ec, 1220 EXTRACTOR_METATYPE_TOOLCHAIN, 1221 data)) 1222 return 1; 1223 } 1224 } 1225 else if (is_uses_sdk) 1226 { 1227 if ( (0 == strcmp (name, "minSdkVersion")) && 1228 (TYPE_STRING != dtype) ) 1229 { 1230 if (0 != 1231 emit_api_level (ec, 1232 EXTRACTOR_METATYPE_MINIMUM_OS_VERSION, 1233 data)) 1234 return 1; 1235 } 1236 else if ( (0 == strcmp (name, "targetSdkVersion")) && 1237 (TYPE_STRING != dtype) ) 1238 { 1239 if (0 != 1240 emit_api_level (ec, 1241 EXTRACTOR_METATYPE_TARGET_OS, 1242 data)) 1243 return 1; 1244 } 1245 } 1246 else if (is_permission) 1247 { 1248 if ( (0 != strcmp (name, "name")) || 1249 (TYPE_STRING != dtype) ) 1250 continue; 1251 /* every declared permission is counted, but only the first few 1252 dozen are reported: what matters on a first pass is the 1253 characterisation, and the total is reported separately */ 1254 (*permissions)++; 1255 if (*permissions > EXTRACTOR_FORENSIC_MAX_ITEMS) 1256 continue; 1257 if (0 != 1258 EXTRACTOR_forensic_emit_text_ (ec, 1259 PLUGIN_NAME, 1260 EXTRACTOR_METATYPE_PERMISSION, 1261 value, 1262 strlen (value))) 1263 return 1; 1264 } 1265 else /* is_application */ 1266 { 1267 if (0 == strcmp (name, "label")) 1268 { 1269 /* usually a resource reference, and a bare `@0x7f...' would 1270 tell nobody anything */ 1271 if (TYPE_STRING != dtype) 1272 continue; 1273 if (0 != 1274 EXTRACTOR_forensic_emit_text_ (ec, 1275 PLUGIN_NAME, 1276 EXTRACTOR_METATYPE_TITLE, 1277 value, 1278 strlen (value))) 1279 return 1; 1280 } 1281 else if ( (0 == strcmp (name, "debuggable")) && 1282 (TYPE_INT_BOOLEAN == dtype) && 1283 (0 != data) ) 1284 { 1285 /* a debuggable package that was shipped is worth a look */ 1286 if (0 != 1287 EXTRACTOR_forensic_emit_ (ec, 1288 PLUGIN_NAME, 1289 EXTRACTOR_METATYPE_ATTRIBUTES, 1290 "debuggable")) 1291 return 1; 1292 } 1293 else if ( ( (0 == strcmp (name, "allowBackup")) || 1294 (0 == strcmp (name, "usesCleartextTraffic")) || 1295 (0 == strcmp (name, "extractNativeLibs")) ) && 1296 (TYPE_INT_BOOLEAN == dtype) ) 1297 { 1298 if (0 != 1299 EXTRACTOR_forensic_emit_ (ec, 1300 PLUGIN_NAME, 1301 EXTRACTOR_METATYPE_ATTRIBUTES, 1302 "%s: %s", 1303 name, 1304 (0 != data) ? "true" : "false")) 1305 return 1; 1306 } 1307 else if (0 == strcmp (name, "networkSecurityConfig")) 1308 { 1309 if (0 != 1310 EXTRACTOR_forensic_emit_ (ec, 1311 PLUGIN_NAME, 1312 EXTRACTOR_METATYPE_ATTRIBUTES, 1313 "networkSecurityConfig: %s", 1314 ('\0' != value[0]) 1315 ? value 1316 : "present")) 1317 return 1; 1318 } 1319 } 1320 } 1321 return 0; 1322 } 1323 1324 1325 /** 1326 * Walk a binary `AndroidManifest.xml'. 1327 * 1328 * The document is a flat list of chunks: a header, a string pool, an 1329 * optional resource map, and then one chunk per XML event. Only the 1330 * start element chunks matter here, and only four element names, so the 1331 * walk stays linear and never recurses. 1332 * 1333 * @param ec extraction context 1334 * @param data the document 1335 * @param len number of bytes in @a data 1336 * @return 1 if the caller should stop extracting, 0 to continue 1337 */ 1338 static int 1339 parse_axml (struct EXTRACTOR_ExtractContext *ec, 1340 const unsigned char *data, 1341 size_t len) 1342 { 1343 struct StringPool sp; 1344 size_t pos; 1345 size_t total; 1346 uint16_t hdr_size; 1347 unsigned int chunks = 0; 1348 unsigned int permissions = 0; 1349 int have_sdk = 0; 1350 1351 memset (&sp, 1352 0, 1353 sizeof (sp)); 1354 if (len < 8) 1355 return 0; 1356 if (RES_XML_TYPE != EXTRACTOR_forensic_le16_ (data)) 1357 return 0; 1358 hdr_size = EXTRACTOR_forensic_le16_ (&data[2]); 1359 total = (size_t) EXTRACTOR_forensic_le32_ (&data[4]); 1360 if ( (hdr_size < 8) || 1361 (((size_t) hdr_size) > len) ) 1362 return 0; 1363 if ( (total > len) || 1364 (total < 8) ) 1365 total = len; /* truncated by our read cap, or by the file */ 1366 pos = hdr_size; 1367 while ( (pos + 8 <= total) && 1368 (chunks++ < MAX_CHUNKS) ) 1369 { 1370 uint16_t type = EXTRACTOR_forensic_le16_ (&data[pos]); 1371 uint16_t chdr = EXTRACTOR_forensic_le16_ (&data[pos + 2]); 1372 uint32_t csize = EXTRACTOR_forensic_le32_ (&data[pos + 4]); 1373 1374 if ( (csize < 8) || 1375 (chdr < 8) || 1376 (((uint64_t) csize) > total - pos) || 1377 (chdr > csize) ) 1378 break; /* malformed, or no forward progress */ 1379 if (RES_STRING_POOL_TYPE == type) 1380 { 1381 uint32_t count; 1382 uint32_t flags; 1383 uint32_t strings_start; 1384 uint32_t styles_start; 1385 1386 if (chdr < 28) 1387 { 1388 pos += csize; 1389 continue; 1390 } 1391 count = EXTRACTOR_forensic_le32_ (&data[pos + 8]); 1392 flags = EXTRACTOR_forensic_le32_ (&data[pos + 16]); 1393 strings_start = EXTRACTOR_forensic_le32_ (&data[pos + 20]); 1394 styles_start = EXTRACTOR_forensic_le32_ (&data[pos + 24]); 1395 if ( (count > MAX_POOL_STRINGS) || 1396 (((uint64_t) count) * 4 > csize - 28) || 1397 (strings_start > csize) || 1398 (strings_start < 28) ) 1399 { 1400 pos += csize; 1401 continue; 1402 } 1403 sp.count = count; 1404 sp.offsets = &data[pos + 28]; 1405 sp.data = &data[pos + strings_start]; 1406 sp.data_len = csize - strings_start; 1407 if ( (0 != styles_start) && 1408 (styles_start > strings_start) && 1409 (styles_start <= csize) ) 1410 sp.data_len = styles_start - strings_start; 1411 sp.utf8 = (0 != (flags & 0x100)); 1412 } 1413 else if (RES_XML_START_ELEMENT_TYPE == type) 1414 { 1415 const unsigned char *ext; 1416 char element[128]; 1417 uint16_t attr_start; 1418 uint16_t attr_size; 1419 uint16_t attr_count; 1420 uint64_t need; 1421 1422 if ( (chdr < 16) || 1423 (csize - chdr < 20) ) 1424 { 1425 pos += csize; 1426 continue; 1427 } 1428 ext = &data[pos + chdr]; 1429 attr_start = EXTRACTOR_forensic_le16_ (&ext[8]); 1430 attr_size = EXTRACTOR_forensic_le16_ (&ext[10]); 1431 attr_count = EXTRACTOR_forensic_le16_ (&ext[12]); 1432 /* every attribute is a ResXMLTree_attribute: four 32 bit words 1433 plus a Res_value, and implementations are allowed to make the 1434 record longer, never shorter */ 1435 if (attr_size < 20) 1436 { 1437 pos += csize; 1438 continue; 1439 } 1440 need = ((uint64_t) attr_start) 1441 + ((uint64_t) attr_count) * attr_size; 1442 if (need > (uint64_t) (csize - chdr)) 1443 { 1444 pos += csize; 1445 continue; 1446 } 1447 if (0 == pool_string (&sp, 1448 EXTRACTOR_forensic_le32_ (&ext[4]), 1449 element, 1450 sizeof (element))) 1451 { 1452 pos += csize; 1453 continue; 1454 } 1455 if (0 != 1456 emit_element (ec, 1457 &sp, 1458 element, 1459 &data[pos + chdr + attr_start], 1460 attr_count, 1461 attr_size, 1462 &permissions, 1463 &have_sdk)) 1464 return 1; 1465 } 1466 pos += csize; 1467 } 1468 if (permissions > EXTRACTOR_FORENSIC_MAX_ITEMS) 1469 return EXTRACTOR_forensic_emit_ (ec, 1470 PLUGIN_NAME, 1471 EXTRACTOR_METATYPE_COMMENT, 1472 "%u permissions declared", 1473 permissions); 1474 return 0; 1475 } 1476 1477 1478 /* ------------------------------------------------------------------ */ 1479 /* ZIP container */ 1480 /* ------------------------------------------------------------------ */ 1481 1482 1483 /** 1484 * Walk the ZIP central directory once and note the things that can be 1485 * read off member names alone. 1486 * 1487 * @param uf the archive 1488 * @param[out] af where to store what we found 1489 */ 1490 static void 1491 scan_members (struct EXTRACTOR_UnzipFile *uf, 1492 struct ArchiveFacts *af) 1493 { 1494 char name[512]; 1495 unsigned int seen = 0; 1496 1497 memset (af, 1498 0, 1499 sizeof (*af)); 1500 if (EXTRACTOR_UNZIP_OK != 1501 EXTRACTOR_common_unzip_go_to_first_file (uf)) 1502 return; 1503 do 1504 { 1505 size_t nlen; 1506 1507 if (seen++ >= MAX_MEMBERS) 1508 break; 1509 if (EXTRACTOR_UNZIP_OK != 1510 EXTRACTOR_common_unzip_get_current_file_info (uf, 1511 NULL, 1512 name, 1513 sizeof (name), 1514 NULL, 0, 1515 NULL, 0)) 1516 continue; 1517 af->num_members++; 1518 nlen = strlen (name); 1519 if ( (0 == strncmp (name, "classes", strlen ("classes"))) && 1520 (4 < nlen) && 1521 (0 == strcmp (&name[nlen - 4], ".dex")) ) 1522 { 1523 af->num_dex++; 1524 continue; 1525 } 1526 if (0 == strncmp (name, "lib/", strlen ("lib/"))) 1527 { 1528 const char *abi = &name[strlen ("lib/")]; 1529 const char *slash = strchr (abi, '/'); 1530 size_t alen; 1531 1532 if (NULL == slash) 1533 continue; 1534 alen = (size_t) (slash - abi); 1535 if ( (0 == alen) || 1536 (alen >= sizeof (af->abis[0])) ) 1537 continue; 1538 for (unsigned int i = 0; i < af->num_abis; i++) 1539 if ( (0 == strncmp (af->abis[i], abi, alen)) && 1540 ('\0' == af->abis[i][alen]) ) 1541 { 1542 alen = 0; 1543 break; 1544 } 1545 if (0 == alen) 1546 continue; 1547 if (af->num_abis >= sizeof (af->abis) / sizeof (af->abis[0])) 1548 continue; 1549 memcpy (af->abis[af->num_abis], 1550 abi, 1551 alen); 1552 af->abis[af->num_abis][alen] = '\0'; 1553 af->num_abis++; 1554 continue; 1555 } 1556 if ( ('\0' == af->sig_member[0]) && 1557 (0 == strncmp (name, "META-INF/", strlen ("META-INF/"))) && 1558 (4 < nlen) && 1559 ( (0 == strcasecmp (&name[nlen - 4], ".RSA")) || 1560 (0 == strcasecmp (&name[nlen - 4], ".DSA")) ) ) 1561 { 1562 const char *base = &name[strlen ("META-INF/")]; 1563 1564 if (NULL == strchr (base, '/')) 1565 { 1566 memcpy (af->sig_member, 1567 name, 1568 (nlen < sizeof (af->sig_member)) 1569 ? nlen + 1 1570 : sizeof (af->sig_member)); 1571 af->sig_member[sizeof (af->sig_member) - 1] = '\0'; 1572 snprintf (af->sig_alias, 1573 sizeof (af->sig_alias), 1574 "%.*s", 1575 (int) (strlen (base) - 4), 1576 base); 1577 } 1578 } 1579 } 1580 while (EXTRACTOR_UNZIP_OK == 1581 EXTRACTOR_common_unzip_go_to_next_file (uf)); 1582 } 1583 1584 1585 /** 1586 * Report which APK signature schemes the file carries. 1587 * 1588 * The v2 and v3 signatures live in an "APK Signing Block", which sits 1589 * between the last local file entry and the central directory and is 1590 * found from the end: the block ends with its own size and the magic 1591 * string `APK Sig Block 42' immediately before the central directory. 1592 * 1593 * @param ec extraction context 1594 * @return 1 if the caller should stop extracting, 0 to continue 1595 */ 1596 static int 1597 emit_signing_block (struct EXTRACTOR_ExtractContext *ec) 1598 { 1599 unsigned char eocd[22]; 1600 unsigned char foot[24]; 1601 unsigned char *block; 1602 uint64_t size; 1603 uint64_t cd_off; 1604 uint64_t block_size; 1605 uint64_t start; 1606 size_t read_len; 1607 size_t pos; 1608 int ret = 0; 1609 1610 size = ec->get_size (ec->cls); 1611 if ( (UINT64_MAX == size) || 1612 (size < 22 + 24) ) 1613 return 0; 1614 /* the usual case is an archive with no comment, so the end of central 1615 directory record is the last 22 bytes */ 1616 if (! EXTRACTOR_forensic_read_ (ec, 1617 (int64_t) (size - 22), 1618 eocd, 1619 sizeof (eocd))) 1620 return 0; 1621 if (0 != memcmp (eocd, 1622 "PK\x05\x06", 1623 4)) 1624 { 1625 unsigned char *tail; 1626 size_t tail_len = (size > 65557) ? 65557 : (size_t) size; 1627 const unsigned char *found = NULL; 1628 1629 if (NULL == (tail = malloc (tail_len))) 1630 return 0; 1631 if (EXTRACTOR_forensic_read_ (ec, 1632 (int64_t) (size - tail_len), 1633 tail, 1634 tail_len)) 1635 for (size_t i = tail_len - 22 + 1; i-- > 0;) 1636 if (0 == memcmp (&tail[i], 1637 "PK\x05\x06", 1638 4)) 1639 { 1640 found = &tail[i]; 1641 break; 1642 } 1643 if (NULL == found) 1644 { 1645 free (tail); 1646 return 0; 1647 } 1648 memcpy (eocd, 1649 found, 1650 sizeof (eocd)); 1651 free (tail); 1652 } 1653 cd_off = EXTRACTOR_forensic_le32_ (&eocd[16]); 1654 if ( (cd_off < 24) || 1655 (cd_off > size) ) 1656 return 0; 1657 if (! EXTRACTOR_forensic_read_ (ec, 1658 (int64_t) (cd_off - 24), 1659 foot, 1660 sizeof (foot))) 1661 return 0; 1662 if (0 != memcmp (&foot[8], 1663 "APK Sig Block 42", 1664 16)) 1665 return 0; 1666 block_size = EXTRACTOR_forensic_le64_ (&foot[0]); 1667 /* written as a subtraction so that a huge size field cannot overflow; 1668 cd_off is at least 24 here */ 1669 if ( (block_size < 24) || 1670 (block_size > cd_off - 8) ) 1671 return 0; 1672 start = cd_off - block_size - 8; 1673 /* the pairs run from just after the leading size field up to the 1674 trailing size field */ 1675 read_len = (size_t) (block_size - 24); 1676 if (read_len > MAX_SIG_BLOCK) 1677 read_len = MAX_SIG_BLOCK; 1678 if (0 == read_len) 1679 return 0; 1680 if (NULL == (block = malloc (read_len))) 1681 return 0; 1682 if (! EXTRACTOR_forensic_read_ (ec, 1683 (int64_t) (start + 8), 1684 block, 1685 read_len)) 1686 { 1687 free (block); 1688 return 0; 1689 } 1690 pos = 0; 1691 for (unsigned int i = 0; (i < 64) && (pos + 12 <= read_len); i++) 1692 { 1693 uint64_t plen = EXTRACTOR_forensic_le64_ (&block[pos]); 1694 uint32_t id = EXTRACTOR_forensic_le32_ (&block[pos + 8]); 1695 const char *scheme = NULL; 1696 1697 if (plen < 4) 1698 break; /* no forward progress */ 1699 switch (id) 1700 { 1701 case APK_SIG_SCHEME_V2: scheme = "v2"; break; 1702 case APK_SIG_SCHEME_V3: scheme = "v3"; break; 1703 case APK_SIG_SCHEME_V31: scheme = "v3.1"; break; 1704 default: break; 1705 } 1706 if ( (NULL != scheme) && 1707 (0 != 1708 EXTRACTOR_forensic_emit_ (ec, 1709 PLUGIN_NAME, 1710 EXTRACTOR_METATYPE_SIGNER, 1711 "APK Signature Scheme %s", 1712 scheme)) ) 1713 { 1714 ret = 1; 1715 break; 1716 } 1717 if (plen > read_len - pos - 8) 1718 break; 1719 pos += (size_t) plen + 8; 1720 } 1721 free (block); 1722 return ret; 1723 } 1724 1725 1726 /** 1727 * Report who signed the archive. 1728 * 1729 * @param ec extraction context 1730 * @param uf the archive 1731 * @param af what the central directory walk found 1732 * @return 1 if the caller should stop extracting, 0 to continue 1733 */ 1734 static int 1735 emit_signature (struct EXTRACTOR_ExtractContext *ec, 1736 struct EXTRACTOR_UnzipFile *uf, 1737 const struct ArchiveFacts *af) 1738 { 1739 unsigned char *der; 1740 size_t der_len; 1741 char dn[EXTRACTOR_FORENSIC_MAX_STRING]; 1742 int ret = 0; 1743 1744 if ('\0' == af->sig_member[0]) 1745 return 0; 1746 if (0 != 1747 EXTRACTOR_forensic_emit_ (ec, 1748 PLUGIN_NAME, 1749 EXTRACTOR_METATYPE_SIGNER, 1750 "JAR signing (v1), alias %s", 1751 af->sig_alias)) 1752 return 1; 1753 der = read_member (uf, 1754 af->sig_member, 1755 MAX_PKCS7, 1756 &der_len); 1757 if (NULL == der) 1758 return 0; 1759 if (pkcs7_signer_dn (der, 1760 der_len, 1761 dn, 1762 sizeof (dn))) 1763 ret = EXTRACTOR_forensic_emit_text_ (ec, 1764 PLUGIN_NAME, 1765 EXTRACTOR_METATYPE_SIGNER, 1766 dn, 1767 strlen (dn)); 1768 free (der); 1769 return ret; 1770 } 1771 1772 1773 /** 1774 * Report the facts that follow from the member names alone. 1775 * 1776 * @param ec extraction context 1777 * @param af what the central directory walk found 1778 * @return 1 if the caller should stop extracting, 0 to continue 1779 */ 1780 static int 1781 emit_archive_facts (struct EXTRACTOR_ExtractContext *ec, 1782 const struct ArchiveFacts *af) 1783 { 1784 for (unsigned int i = 0; i < af->num_abis; i++) 1785 if (0 != 1786 EXTRACTOR_forensic_emit_text_ ( 1787 ec, 1788 PLUGIN_NAME, 1789 EXTRACTOR_METATYPE_TARGET_ARCHITECTURE, 1790 af->abis[i], 1791 strlen (af->abis[i]))) 1792 return 1; 1793 if ( (0 != af->num_dex) && 1794 (0 != 1795 EXTRACTOR_forensic_emit_ (ec, 1796 PLUGIN_NAME, 1797 EXTRACTOR_METATYPE_COMMENT, 1798 "%u dex file%s", 1799 af->num_dex, 1800 (1 == af->num_dex) ? "" : "s")) ) 1801 return 1; 1802 if ( (0 != af->num_members) && 1803 (0 != 1804 EXTRACTOR_forensic_emit_ (ec, 1805 PLUGIN_NAME, 1806 EXTRACTOR_METATYPE_ENTRY_COUNT, 1807 "%u", 1808 af->num_members)) ) 1809 return 1; 1810 return 0; 1811 } 1812 1813 1814 /** 1815 * Main entry method for the apk extraction plugin. 1816 * 1817 * @param ec extraction context provided to the plugin 1818 */ 1819 void 1820 EXTRACTOR_apk_extract_method (struct EXTRACTOR_ExtractContext *ec); 1821 1822 void 1823 EXTRACTOR_apk_extract_method (struct EXTRACTOR_ExtractContext *ec) 1824 { 1825 unsigned char magic[4]; 1826 struct EXTRACTOR_UnzipFile *uf; 1827 struct ArchiveFacts af; 1828 unsigned char *member; 1829 size_t member_len; 1830 int is_apk; 1831 1832 if (! EXTRACTOR_forensic_read_ (ec, 1833 0, 1834 magic, 1835 sizeof (magic))) 1836 return; 1837 if (0 != memcmp (magic, 1838 "PK\x03\x04", 1839 4)) 1840 return; 1841 if (NULL == (uf = EXTRACTOR_common_unzip_open (ec))) 1842 return; 1843 /* an APK contains a JAR manifest too, so look for the Android 1844 manifest first */ 1845 if (EXTRACTOR_UNZIP_OK == 1846 EXTRACTOR_common_unzip_go_find_local_file (uf, 1847 "AndroidManifest.xml", 1848 2)) 1849 { 1850 is_apk = 1; 1851 } 1852 else if (EXTRACTOR_UNZIP_OK == 1853 EXTRACTOR_common_unzip_go_find_local_file (uf, 1854 "META-INF/MANIFEST.MF", 1855 2)) 1856 { 1857 is_apk = 0; 1858 } 1859 else 1860 { 1861 (void) EXTRACTOR_common_unzip_close (uf); 1862 return; /* somebody else's ZIP */ 1863 } 1864 if (0 != 1865 ec->proc (ec->cls, 1866 PLUGIN_NAME, 1867 EXTRACTOR_METATYPE_MIMETYPE, 1868 EXTRACTOR_METAFORMAT_UTF8, 1869 "text/plain", 1870 is_apk 1871 ? "application/vnd.android.package-archive" 1872 : "application/java-archive", 1873 is_apk 1874 ? strlen ("application/vnd.android.package-archive") + 1 1875 : strlen ("application/java-archive") + 1)) 1876 goto CLEANUP; 1877 if (is_apk) 1878 { 1879 member = read_member (uf, 1880 "AndroidManifest.xml", 1881 MAX_AXML, 1882 &member_len); 1883 if (NULL != member) 1884 { 1885 int stop = parse_axml (ec, 1886 member, 1887 member_len); 1888 1889 free (member); 1890 if (stop) 1891 goto CLEANUP; 1892 } 1893 } 1894 else 1895 { 1896 member = read_member (uf, 1897 "META-INF/MANIFEST.MF", 1898 MAX_MANIFEST, 1899 &member_len); 1900 if (NULL != member) 1901 { 1902 int stop = parse_jar_manifest (ec, 1903 (const char *) member, 1904 member_len); 1905 1906 free (member); 1907 if (stop) 1908 goto CLEANUP; 1909 } 1910 } 1911 scan_members (uf, 1912 &af); 1913 if (0 != 1914 emit_archive_facts (ec, 1915 &af)) 1916 goto CLEANUP; 1917 if (0 != 1918 emit_signature (ec, 1919 uf, 1920 &af)) 1921 goto CLEANUP; 1922 if (is_apk) 1923 (void) emit_signing_block (ec); 1924 CLEANUP: 1925 (void) EXTRACTOR_common_unzip_close (uf); 1926 } 1927 1928 1929 /* end of apk_extractor.c */