Introduction to Android Resources and ARSC
The Android Application Package (APK) is a treasure trove for reverse engineers. While Java bytecode (DEX) often takes center stage, the resource table, specifically the resources.arsc file, holds equally critical information. This binary file maps resource IDs to their actual values, paths, and configurations, making it indispensable for understanding an application’s UI, localized strings, and dynamic behavior without relying solely on decompiled code. Tools like Apktool excel at decompiling resources, but a deep, manual understanding of ARSC’s binary structure provides unparalleled insight into how Android manages its assets and can be crucial when automated tools fail or are insufficient.
This expert-level tutorial delves into the manual dissection of resources.arsc. We’ll explore its binary structure, identify key chunks, and demonstrate how to extract layout and drawable paths using a hex editor and basic scripting concepts. This approach fortifies your reverse engineering skills, allowing you to bypass potential obfuscation or understand resource linkages at a fundamental level.
Prerequisites for ARSC Dissection
Before we begin our deep dive, ensure you have the following:
- A target Android APK file.
- A powerful hex editor (e.g., 010 Editor, HxD, IDA Pro’s hex view).
- Basic understanding of binary data, structs, and little-endian byte ordering.
- Optional: A scripting language (e.g., Python) for automating byte parsing.
- Familiarity with Android resource types (layout, drawable, string, etc.).
The Android Resource Table (ARSC) – A Deeper Dive
The resources.arsc file is a binary representation of all compiled resources in an Android application, built from XML files (layouts, drawables, strings) and raw assets. It acts as an index, allowing the Android runtime to quickly locate resources based on their integer IDs. Its structure is composed of several interdependent chunks:
-
ResTable_headerThe top-level header for the entire ARSC file. It defines the number of packages contained within. Its structure is typically:
chunk.type(0x0002for ResTable header)chunk.headerSize(size of this header, e.g.,0x000C)chunk.size(total size of the ResTable chunk, including packages)packageCount(number ofResTable_packagechunks)
-
ResTable_packageEach APK typically contains at least one package, representing its own resources. This chunk defines a unique ID for the package, its name, and crucially, two string pools:
typeStrings: AResStringPool_headercontaining the names of resource types (e.g., “layout”, “drawable”, “string”).keyStrings: AnotherResStringPool_headercontaining the specific names of resources within that type (e.g., “activity_main”, “ic_launcher”).
-
ResTable_typeSpecThis chunk provides metadata for a specific resource type within a package (e.g., all `drawable` resources). It contains flags indicating whether resources of this type are public or private, and an array of configurations that apply to this type.
-
ResTable_typeThis is where the actual resource entries are defined for a specific type and configuration. For example, a
ResTable_typechunk might describe all `layout` resources for the `hdpi` configuration. It points to an array ofResTable_entrystructures. -
ResTable_entryEach
ResTable_entrycorresponds to a single resource entry (e.g., `R.layout.activity_main`). It contains flags (e.g., if the resource is a complex type) and a pointer to either an index in the `keyStrings` pool (for simple values) or aRes_valuestructure. -
Res_valueThis structure holds the actual value of a resource. Its
dataTypefield is critical, telling us how to interpret thedatafield (e.g., a string pool index, a reference to another resource, a raw integer value).
Initial Setup: Extracting resources.arsc
First, obtain your target APK and extract its contents. You can simply rename the .apk file to .zip and extract, or use the unzip command:
unzip your_app.apk -d your_app_extracted
Navigate into the extracted directory. You’ll find resources.arsc in the root.
Manual Dissection with a Hex Editor: Extracting Layouts and Drawables
Open resources.arsc in your hex editor. The file starts with the ResTable_header.
Step 1: Identify the ResTable_header
Look for the `chunk.type` value, which is 0x0002 (or `02 00` in little-endian). The subsequent 2 bytes are `headerSize` (often `0x000C`), and the next 4 bytes are `chunk.size` (total file size). Finally, the `packageCount` (2 bytes) indicates how many packages follow.
Example Hex View (Conceptual)
00000000: 02 00 0C 00 A4 8B 01 00 01 00 ... <-- chunk.type=0x0002, headerSize=0x000C, size=0x018BA4, packageCount=0x0001
Step 2: Locate the ResTable_package Chunk
Immediately following the ResTable_header is the ResTable_package chunk. It starts with its own header (`chunk.type` = 0x0200 or `00 02` little-endian, but note this type is `RES_TABLE_PACKAGE_TYPE`, not `RES_TABLE_HEADER_TYPE`). The key elements here are the offsets to `typeStrings` and `keyStrings` string pools.
package_id(4 bytes)package_name(128 bytes, UTF-16, often null-padded)typeStringsoffset (4 bytes)keyStringsoffset (4 bytes)
Use these offsets to jump to the beginning of the respective ResStringPool_headers. For instance, jump to the `typeStrings` offset. Inside this string pool, you’ll find entries like
Android Mobile Specs & Compare Directory
Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!
Compare Devices Specs →