ohmu
·
2026-10-15
1#include "common/android/dex.h"
2#include "common/android/zip.h"
3#include "common/debug.h"
4#include "common/io.h"
5#include "common/mallocHelper.h"
6
7#include <errno.h>
8#include <fcntl.h>
9#include <sys/mman.h>
10#include <sys/stat.h>
11
12#ifdef FF_HAVE_ZLIB
13 #include "common/zlib.h"
14#endif
15
16// Offsets into the dex header, from https://source.android.com/docs/core/runtime/dex-format.
17#define FF_DEX_ENDIAN_TAG 0x12345678u
18#define FF_DEX_HEADER_SIZE 0x70
19#define FF_DEX_OFF_FILE_SIZE 0x20
20#define FF_DEX_OFF_ENDIAN_TAG 0x28
21#define FF_DEX_OFF_STRING_IDS 0x3C
22#define FF_DEX_OFF_TYPE_IDS_SIZE 0x40
23#define FF_DEX_OFF_TYPE_IDS 0x44
24#define FF_DEX_OFF_FIELD_IDS_SIZE 0x50
25#define FF_DEX_OFF_FIELD_IDS 0x54
26#define FF_DEX_OFF_METHOD_IDS_SIZE 0x58
27#define FF_DEX_OFF_METHOD_IDS 0x5C
28#define FF_DEX_OFF_CLASS_DEFS_SIZE 0x60
29#define FF_DEX_OFF_CLASS_DEFS 0x64
30
31// class_def_item: [u32 class_idx][u32 access_flags][u32 superclass_idx][u32 interfaces_off]
32// [u32 source_file_idx][u32 annotations_off][u32 class_data_off][u32 static_values_off]
33#define FF_DEX_CLASS_DEF_SIZE 32
34#define FF_DEX_OFF_CLASS_DEF_DATA 24
35#define FF_DEX_OFF_CLASS_DEF_STATIC_VALUES 28
36
37// field_id_item: [u16 class_idx][u16 type_idx][u32 name_idx]
38#define FF_DEX_FIELD_ID_SIZE 8
39#define FF_DEX_OFF_FIELD_ID_TYPE 2
40#define FF_DEX_OFF_FIELD_ID_NAME 4
41
42// method_id_item: [u16 class_idx][u16 proto_idx][u32 name_idx]
43#define FF_DEX_METHOD_ID_SIZE 8
44#define FF_DEX_OFF_METHOD_ID_NAME 4
45
46// code_item: [u16 registers_size][u16 ins_size][u16 outs_size][u16 tries_size][u32 debug_info_off]
47// [u32 insns_size][u16 insns...]. Everything before the instruction stream is skipped by reading
48// `insns_size` and starting `insns` where it ends.
49#define FF_DEX_OFF_CODE_INSNS_SIZE 12
50#define FF_DEX_OFF_CODE_INSNS 16
51
52// The seven `iget*` opcodes, which are how a method reads an instance field. `iput*` shares the same
53// format and the same operand, and a `writeToParcel` does not store to a field, so one range covers
54// both and the walk does not have to tell them apart.
55#define FF_DEX_OP_FIELD_FIRST 0x52
56#define FF_DEX_OP_FIELD_LAST 0x5F
57
58#define FF_DEX_ENTRY "classes.dex"
59// How many `classesN.dex` entries a jar is walked for. A jar that spreads its classes over more
60// than this still resolves everything in the entries that were walked; only a class that lives in
61// one of the ones past the bound is reported as missing.
62#define FF_DEX_MAX_ENTRIES 10
63#define FF_DEX_MAGIC "dex\n"
64
65static uint16_t dexU16(const uint8_t* p) {
66 return (uint16_t) ((uint16_t) p[0] | (uint16_t) ((uint16_t) p[1] << 8));
67}
68
69static uint32_t dexU32(const uint8_t* p) {
70 return (uint32_t) p[0] | ((uint32_t) p[1] << 8) | ((uint32_t) p[2] << 16) | ((uint32_t) p[3] << 24);
71}
72
73// The dex header points at its tables with offsets that a corrupt or hostile file is free to set
74// anywhere, including past the end of the mapping. Testing `end - p` alone does not catch that: once
75// `p` is past `end` the subtraction is negative and casting it to size_t turns it into a huge value,
76// so the comparison passes and the read goes off the end. Both directions have to be one test.
77static bool dexInRange(const uint8_t* dex, const uint8_t* end, const uint8_t* p, size_t size) {
78 return p >= dex && p <= end && (size_t) (end - p) >= size;
79}
80
81// Same, for a table of `count` elements of `elementSize` bytes. `count` is 64-bit because the
82// callers add one to an index that came out of the file, and doing that in 32 bits can wrap to zero
83// and make the check pass for an index that is not in the table. Dividing rather than multiplying is
84// what keeps a hostile `count` from wrapping the size_t on a 32-bit build -- armeabi-v7a is one, and
85// there `count * 4` overflows for any count above 0x3FFFFFFF and the check passes again.
86static bool dexTableInRange(const uint8_t* dex, const uint8_t* end, const uint8_t* p, uint64_t count, size_t elementSize) {
87 if (p < dex || p > end) {
88 return false;
89 }
90 return (size_t) (end - p) / elementSize >= count;
91}
92
93// LEB128, at most five bytes for the 32-bit values a dex stores this way. `end` bounds every read:
94// the lengths and indexes decoded here come out of the file, so a truncated one must not walk off
95// the end. A read that runs into `end` yields what was decoded so far, and the callers treat the
96// resulting value as untrusted -- it is either compared against another count or used as an index
97// that is range checked in turn.
98static uint32_t dexUleb128(const uint8_t** p, const uint8_t* end) {
99 uint32_t value = 0;
100 for (int shift = 0; shift <= 28; shift += 7) {
101 if (*p >= end) {
102 break;
103 }
104 const uint8_t byte = *(*p)++;
105 value |= (uint32_t) (byte & 0x7f) << shift;
106 if ((byte & 0x80) == 0) {
107 break;
108 }
109 }
110 return value;
111}
112
113// The type tag a dex encoded_value carries in the low five bits of its header byte, per the
114// `encoded_value` table of the dex format.
115//
116// VALUE_NULL and VALUE_BOOLEAN are the trap. Their value *is* the header -- the type for a null,
117// the size nibble for a boolean -- and they carry **no payload bytes at all**, so the
118// `((size - 1) << 5) | type` rule that describes every other tag does not describe them. Taking the
119// size nibble at face value and reading one payload byte walks one byte too far, which pairs every
120// field after that with the wrong value. It is not a hypothetical: `IAudioService$Stub` declares ten
121// `PERMISSIONS_*` arrays that are all null, right behind its `DESCRIPTOR` string and ahead of its
122// 324 transaction constants, and those ten spurious bytes made
123// `TRANSACTION_getDevicesForAttributesUnprotected` read as 210 instead of 167 -- a code that reaches
124// a different method. `IWifiManager$Stub` has none ahead of the field the wifi module reads, which
125// is the only reason this went unnoticed.
126//
127// Naming VALUE_BOOLEAN also matters for a second reason: it is the tag a `static final boolean`
128// carries, and treating it as VALUE_INT would hand back a boolean where an int was asked for.
129typedef enum FFDexValueType : uint32_t {
130 FF_DEX_VALUE_INT = 0x04, // sign-extended; one to four payload bytes
131 FF_DEX_VALUE_NULL = 0x1e, // no payload
132 FF_DEX_VALUE_BOOLEAN = 0x1f, // no payload; the boolean is in the header's size nibble
133} FFDexValueType;
134
135// encoded_value: one header byte holding ((size - 1) << 5) | type, then that many payload bytes.
136//
137// The `static_values` array is not a list of ints: `IInterface.DESCRIPTOR` is a `static final
138// String` and sits in it, and a real Stub class mixes ints, strings, nulls and booleans. So a value
139// whose tag is not VALUE_INT is skipped -- its payload is stepped over to keep the walk aligned with
140// the field list -- and only `isInt` reports whether the *wanted* field ended up being one. Failing
141// on the first non-int instead would abort on `DESCRIPTOR`, before the transaction constants that
142// follow it are ever reached. Measured on a device: `IWifiManager$Stub` carries 347 static fields
143// whose values are mostly VALUE_INT but include that string, and `getConnectionInfo` is 98 there.
144//
145// A payload wider than four bytes is not an int either, and the byte count is what keeps a size
146// field read out of a corrupt file from shifting past the end. Reading through 64 bits keeps every
147// shift in range while counting down; `end` is what keeps a truncated payload from running off the
148// end of the mapping.
149static bool dexEncodedValue(const uint8_t** p, const uint8_t* end, int32_t* result, bool* isInt) {
150 if (*p >= end) {
151 return false;
152 }
153 const uint8_t header = *(*p)++;
154 const uint32_t type = (uint32_t) (header & 0x1f);
155
156 // The two tags whose value is the header byte itself. Returning here is what keeps the walk in
157 // step; `isInt` is false because neither is an int.
158 if (type == FF_DEX_VALUE_NULL || type == FF_DEX_VALUE_BOOLEAN) {
159 *result = 0;
160 *isInt = false;
161 return true;
162 }
163
164 const uint32_t size = (uint32_t) (header >> 5) + 1;
165 if (size > 8) {
166 return false;
167 }
168
169 uint64_t value = 0;
170 for (uint32_t i = 0; i < size; ++i) {
171 if (*p >= end) {
172 return false;
173 }
174 if (i < sizeof(value)) {
175 value |= (uint64_t) (*(*p)++) << (i * 8);
176 } else {
177 (void) *(*p)++;
178 }
179 }
180
181 *isInt = type == FF_DEX_VALUE_INT && size <= sizeof(uint32_t);
182 if (*isInt) {
183 // VALUE_INT is sign-extended from its own width, not from 32 bits: a one-byte -1 is written
184 // as `21 ff`, one byte of 0xff, and has to come back as -1 rather than 255.
185 const uint32_t bits = size * 8;
186 if ((value & (1ull << (bits - 1))) != 0) {
187 value |= ~((1ull << bits) - 1);
188 }
189 }
190 *result = (int32_t) (uint32_t) value;
191 return true;
192}
193
194// string_data_item: a uleb128 length in UTF-16 code units, then MUTF-8 bytes and a NUL terminator.
195// The descriptors and field names looked up here are ASCII, where MUTF-8 and UTF-8 agree, so the
196// bytes can be used as they are.
197static const char* dexString(const uint8_t* dex, const uint8_t* end, uint32_t index) {
198 const uint8_t* ids = dex + dexU32(dex + FF_DEX_OFF_STRING_IDS);
199 // `string_ids_size` is not read: the check is that the entry `index` names lies inside the
200 // mapping, which is what the read below needs, and the table is the only thing that can say it
201 // without trusting a second field out of the same file.
202 if (!dexTableInRange(dex, end, ids, (uint64_t) index + 1, 4)) {
203 return nullptr;
204 }
205 const uint8_t* p = dex + dexU32(ids + (size_t) index * 4);
206 if (p < dex || p >= end) {
207 return nullptr;
208 }
209 (void) dexUleb128(&p, end);
210 if (p >= end) {
211 return nullptr;
212 }
213 return memchr(p, '\0', (size_t) (end - p)) != nullptr ? (const char*) p : nullptr;
214}
215
216// One dex entry, validated. Every offset in the header comes out of the file, so each table is range
217// checked before the walk uses it.
218//
219// `fieldIds` and `methodIds` are the two tables a class's own lists are resolved through: a
220// class_data_item names its members by index into them, and the `name_idx` of the entry is what says
221// which member it is. Holding them here rather than re-reading the header offset per class also
222// turns the per-member bounds check into a count comparison, which has to happen before the index is
223// multiplied out anyway -- on a 32-bit build `index * 8` wraps for a large enough index and the
224// range check that follows passes again.
225//
226// `string_ids` is deliberately not held here: `dexString` checks the one entry it reads, and a table
227// nothing walks in order does not need a second check.
228typedef struct FFDexTables {
229 const uint8_t* dex;
230 const uint8_t* end;
231 const uint8_t* types;
232 uint32_t typeCount;
233 const uint8_t* fieldIds;
234 uint32_t fieldIdCount;
235 const uint8_t* methodIds;
236 uint32_t methodIdCount;
237 const uint8_t* classes;
238 uint32_t classCount;
239} FFDexTables;
240
241static const char* dexOpen(const uint8_t* dex, size_t size, FFDexTables* tables) {
242 if (size < FF_DEX_HEADER_SIZE || dexU32(dex + FF_DEX_OFF_ENDIAN_TAG) != FF_DEX_ENDIAN_TAG) {
243 return "Not a dex file";
244 }
245 const uint32_t fileSize = dexU32(dex + FF_DEX_OFF_FILE_SIZE);
246 if (fileSize > size || fileSize < FF_DEX_HEADER_SIZE) {
247 return "The dex file size is out of range";
248 }
249 const uint8_t* end = dex + fileSize;
250
251 const uint8_t* types = dex + dexU32(dex + FF_DEX_OFF_TYPE_IDS);
252 const uint32_t typeCount = dexU32(dex + FF_DEX_OFF_TYPE_IDS_SIZE);
253 if (!dexTableInRange(dex, end, types, typeCount, 4)) {
254 return "The dex type table is out of range";
255 }
256
257 const uint8_t* fieldIds = dex + dexU32(dex + FF_DEX_OFF_FIELD_IDS);
258 const uint32_t fieldIdCount = dexU32(dex + FF_DEX_OFF_FIELD_IDS_SIZE);
259 if (!dexTableInRange(dex, end, fieldIds, fieldIdCount, FF_DEX_FIELD_ID_SIZE)) {
260 return "The dex field table is out of range";
261 }
262
263 const uint8_t* methodIds = dex + dexU32(dex + FF_DEX_OFF_METHOD_IDS);
264 const uint32_t methodIdCount = dexU32(dex + FF_DEX_OFF_METHOD_IDS_SIZE);
265 if (!dexTableInRange(dex, end, methodIds, methodIdCount, FF_DEX_METHOD_ID_SIZE)) {
266 return "The dex method table is out of range";
267 }
268
269 const uint8_t* classes = dex + dexU32(dex + FF_DEX_OFF_CLASS_DEFS);
270 const uint32_t classCount = dexU32(dex + FF_DEX_OFF_CLASS_DEFS_SIZE);
271 if (!dexTableInRange(dex, end, classes, classCount, FF_DEX_CLASS_DEF_SIZE)) {
272 return "The dex class table is out of range";
273 }
274
275 tables->dex = dex;
276 tables->end = end;
277 tables->types = types;
278 tables->typeCount = typeCount;
279 tables->fieldIds = fieldIds;
280 tables->fieldIdCount = fieldIdCount;
281 tables->methodIds = methodIds;
282 tables->methodIdCount = methodIdCount;
283 tables->classes = classes;
284 tables->classCount = classCount;
285 return nullptr;
286}
287
288// The descriptor a type index names, e.g. "I", "[F" or "Landroid/os/Parcel;".
289static const char* dexTypeString(const FFDexTables* tables, uint32_t typeIndex) {
290 if (typeIndex >= tables->typeCount) {
291 return nullptr;
292 }
293 return dexString(tables->dex, tables->end, dexU32(tables->types + (size_t) typeIndex * 4));
294}
295
296// One pass over the type table, resolving the type index of every class that still has a request
297// open. This pass is what a lookup costs: `framework.jar`'s classes.dex lists 8428 descriptors, each
298// one a `string_data_item` read from a different part of a 51 MB mapping. Matching every request
299// against the same pass is what makes a batch cheaper than the sum of its fields -- the descriptor is
300// read once however many classes are being looked for, and the pass ends as soon as the last request
301// has an index rather than at the end of the table.
302//
303// `typeIndexes` is parallel to `descriptors` and rebuilt here rather than kept across entries: a
304// type index is a property of the entry's own table, and the next entry numbers its types
305// differently.
306static void dexFindTypes(const FFDexTables* tables, const char* const* descriptors, const uint8_t* settled, uint32_t* typeIndexes, uint32_t count) {
307 uint32_t remaining = 0;
308 for (uint32_t r = 0; r < count; ++r) {
309 typeIndexes[r] = UINT32_MAX;
310 if (!settled[r]) {
311 ++remaining;
312 }
313 }
314
315 for (uint32_t i = 0; i < tables->typeCount && remaining > 0; ++i) {
316 const char* descriptor = dexString(tables->dex, tables->end, dexU32(tables->types + (size_t) i * 4));
317 if (descriptor == nullptr) {
318 continue;
319 }
320 for (uint32_t r = 0; r < count; ++r) {
321 if (settled[r] || typeIndexes[r] != UINT32_MAX || strcmp(descriptor, descriptors[r]) != 0) {
322 continue;
323 }
324 typeIndexes[r] = i;
325 --remaining;
326 }
327 }
328}
329
330// The lists of a class_data_item, each positioned at its first entry.
331//
332// A class_data_item is `[uleb static_fields_size][uleb instance_fields_size][uleb direct_methods_size]
333// [uleb virtual_methods_size]` followed by the four lists in that order, so the start of each list is
334// only reachable by stepping over the one in front of it. That is done once here for the three
335// readers that each want a different list: the static field reader pairs the first with the class's
336// static value array, the write-sequence reader walks the methods, and the field-existence reader
337// walks the second.
338//
339// A field entry is `[uleb field_idx_diff][uleb access_flags]` and a method entry is the same plus a
340// trailing `[uleb code_off]`, which is the offset of the code_item holding its instructions -- or 0
341// for a method with no body, an abstract or native one.
342//
343// Each of the four lists is delta-encoded from zero on its own, so the counts are kept apart rather
344// than summed: a class routinely has a direct method and a virtual one under the same index, and one
345// accumulator carried across the two method lists reads the second list's names out of the wrong end
346// of the method table. The field lists are read the same way, which is why the reader of each one
347// starts its index at zero rather than continuing from the list in front of it.
348typedef struct FFDexClassData {
349 const uint8_t* staticFields;
350 const uint8_t* instanceFields;
351 const uint8_t* methods;
352 uint32_t staticFieldCount;
353 uint32_t instanceFieldCount;
354 uint32_t directMethodCount;
355 uint32_t virtualMethodCount;
356} FFDexClassData;
357
358// Steps over `count` field entries. A list that ends before its own count is a file that is not what
359// it claims, not a short list: the count and the entries both come out of the same file.
360static bool dexSkipFields(const uint8_t** p, const uint8_t* end, uint32_t count) {
361 for (uint32_t i = 0; i < count; ++i) {
362 if (*p >= end) {
363 return false;
364 }
365 (void) dexUleb128(p, end); // field_idx_diff
366 (void) dexUleb128(p, end); // access_flags
367 }
368 return true;
369}
370
371static const char* dexReadClassData(const FFDexTables* tables, const uint8_t* classDef, FFDexClassData* data) {
372 const uint8_t* dex = tables->dex;
373 const uint8_t* end = tables->end;
374 const uint32_t classDataOff = dexU32(classDef + FF_DEX_OFF_CLASS_DEF_DATA);
375 if (classDataOff == 0) {
376 // A class with no class_data_item declares nothing of its own -- its members are all
377 // inherited. That is four empty lists, not a file that cannot be read, and the counts below
378 // are what carry the answer.
379 data->staticFields = nullptr;
380 data->instanceFields = nullptr;
381 data->methods = nullptr;
382 data->staticFieldCount = 0;
383 data->instanceFieldCount = 0;
384 data->directMethodCount = 0;
385 data->virtualMethodCount = 0;
386 return nullptr;
387 }
388
389 const uint8_t* p = dex + classDataOff;
390 // One byte, so that the first uleb128 has something to read.
391 if (!dexInRange(dex, end, p, 1)) {
392 return "The dex class data is out of range";
393 }
394
395 data->staticFieldCount = dexUleb128(&p, end);
396 data->instanceFieldCount = dexUleb128(&p, end);
397 data->directMethodCount = dexUleb128(&p, end);
398 data->virtualMethodCount = dexUleb128(&p, end);
399
400 data->staticFields = p;
401 if (!dexSkipFields(&p, end, data->staticFieldCount)) {
402 return "The dex class data is truncated";
403 }
404 data->instanceFields = p;
405 if (!dexSkipFields(&p, end, data->instanceFieldCount)) {
406 return "The dex class data is truncated";
407 }
408 data->methods = p;
409 return nullptr;
410}
411
412// The class_def_item of the class that `typeIndex` names, or nullptr when this dex only references
413// the class.
414//
415// Having a type index is not the same as being defined here: a dex lists every type it references in
416// its type table, so a class that a later entry of the jar defines still has a type index in this
417// one, with no class_def_item behind it. Only a class_def_item makes the answer this dex's, and
418// without one the caller moves on to the next entry.
419static const uint8_t* dexFindClassDef(const FFDexTables* tables, uint32_t typeIndex) {
420 for (uint32_t i = 0; i < tables->classCount; ++i) {
421 const uint8_t* classDef = tables->classes + (size_t) i * FF_DEX_CLASS_DEF_SIZE;
422 if (dexU32(classDef) == typeIndex) {
423 return classDef;
424 }
425 }
426 return nullptr;
427}
428
429// Walks the static field list of the class that `typeIndex` names and the class's static value array
430// in step, writing the value of every request for that class whose field name matches. Both lists are
431// ordered by field index and cover exactly the same fields -- when they do not, the pairing is not
432// trustworthy and nothing is written.
433//
434// `defined` says whether this dex *defines* the class, which the caller needs: a request the class
435// cannot answer has to be left open when the class belongs to a later entry of the jar and closed
436// when it does not.
437//
438// A request this class cannot answer -- a field it does not declare, or one it declares as something
439// other than an int -- is closed here rather than reported: the class is this dex's, so no later
440// entry of the jar could give it a different answer, and one field the caller can live without must
441// not hold back the rest of the batch. It is closed with the sentinel, and what this returns is only
442// ever a dex that cannot be read, which is the one thing no later entry can fix.
443static const char* dexClassStaticInts(const FFDexTables* tables, uint32_t typeIndex, const FFDexStaticIntRequest* requests, const uint32_t* typeIndexes, uint8_t* settled, uint32_t count, bool* defined) {
444 const uint8_t* classDef = dexFindClassDef(tables, typeIndex);
445 *defined = classDef != nullptr;
446 if (classDef == nullptr) {
447 return nullptr;
448 }
449
450 const uint8_t* dex = tables->dex;
451 const uint8_t* end = tables->end;
452
453 FFDexClassData classData;
454 const char* error = dexReadClassData(tables, classDef, &classData);
455 if (error != nullptr) {
456 return error;
457 }
458
459 // The static value array is parallel to the static field list and covers exactly the same fields,
460 // which is what makes walking the two in step below meaningful. It is absent in two cases -- a
461 // class with no static field, and a class none of whose static fields has a constant value -- and
462 // the header writes 0 for it in both. The read is skipped rather than made against whatever byte
463 // a zero offset points at, which is the dex magic and decodes as a four byte int.
464 const uint8_t* fields = classData.staticFields;
465 const uint8_t* values = dex;
466 bool hasValues = false;
467 if (classData.staticFieldCount > 0) {
468 const uint32_t staticValuesOff = dexU32(classDef + FF_DEX_OFF_CLASS_DEF_STATIC_VALUES);
469 if (staticValuesOff != 0) {
470 values = dex + staticValuesOff;
471 if (!dexInRange(dex, end, values, 1)) {
472 return "The dex class data is out of range";
473 }
474 if (classData.staticFieldCount != dexUleb128(&values, end)) {
475 return "The dex static fields and values do not pair up";
476 }
477 hasValues = true;
478 }
479 }
480
481 uint32_t fieldIndex = 0;
482 for (uint32_t j = 0; j < classData.staticFieldCount; ++j) {
483 // The two arrays are walked in step, so running out of either one is a truncation.
484 if (fields >= end || (hasValues && values >= end)) {
485 return "The dex static field list is truncated";
486 }
487
488 const uint32_t fieldIndexDiff = dexUleb128(&fields, end); // field_idx_diff
489 if (fieldIndexDiff > UINT32_MAX - fieldIndex) {
490 return "The dex field index is out of range";
491 }
492 fieldIndex += fieldIndexDiff;
493 (void) dexUleb128(&fields, end); // access_flags
494 int32_t value = 0;
495 // Left false when there is no value array, which closes the field with the sentinel below:
496 // a class with no static value for the field has no answer for it.
497 bool isInt = false;
498 if (hasValues && !dexEncodedValue(&values, end, &value, &isInt)) {
499 return "The dex static value list is truncated";
500 }
501
502 if (fieldIndex >= tables->fieldIdCount) {
503 return "The dex field table is out of range";
504 }
505 const char* name = dexString(dex, end, dexU32(tables->fieldIds + (size_t) fieldIndex * FF_DEX_FIELD_ID_SIZE + FF_DEX_OFF_FIELD_ID_NAME));
506 if (name == nullptr) {
507 continue;
508 }
509 for (uint32_t r = 0; r < count; ++r) {
510 if (settled[r] || typeIndexes[r] != typeIndex || strcmp(name, requests[r].fieldName) != 0) {
511 continue;
512 }
513 if (!isInt) {
514 // The field exists but is not an int, so its value is not the constant asked for.
515 // Closed the way a field the class does not declare is, because it is this dex's
516 // answer too. The check is here rather than on the first non-int in the list because
517 // the list legitimately holds strings (`DESCRIPTOR`) and booleans.
518 *requests[r].result = FF_DEX_STATIC_INT_UNRESOLVED;
519 settled[r] = 1;
520 continue;
521 }
522 *requests[r].result = value;
523 settled[r] = 1;
524 }
525 }
526
527 // The class is defined here, so a request of its own that went unanswered is one whose field the
528 // class does not declare as a static field. Closed here for the same reason as above.
529 for (uint32_t r = 0; r < count; ++r) {
530 if (!settled[r] && typeIndexes[r] == typeIndex) {
531 *requests[r].result = FF_DEX_STATIC_INT_UNRESOLVED;
532 settled[r] = 1;
533 }
534 }
535 return nullptr;
536}
537
538// ---------------------------------------------------------------------------------------------
539// Walking a method's instructions
540// ---------------------------------------------------------------------------------------------
541
542// The width of every instruction, in code units. This is ART's `Instruction::SizeInCodeUnits`, and
543// the walk below cannot stay on the instruction grid without it -- a walk that leaves the grid still
544// produces a plausible-looking list of fields, which is what makes this worth a table rather than a
545// guess. Unused and odex-only opcodes are 1 rather than 0, so that a byte which is not an instruction
546// at all moves the walk on instead of leaving it where it is.
547static const uint8_t dexOpcodeSize[256] = {
548 /* 00 */ 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1,
549 /* 10 */ 1, 1, 1, 2, 3, 2, 2, 3, 5, 2, 2, 3, 2, 1, 1, 2,
550 /* 20 */ 2, 1, 2, 2, 3, 3, 3, 1, 1, 2, 3, 3, 3, 2, 2, 2,
551 /* 30 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
552 /* 40 */ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
553 /* 50 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
554 /* 60 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3,
555 /* 70 */ 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1,
556 /* 80 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
557 /* 90 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
558 /* a0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
559 /* b0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
560 /* c0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
561 /* d0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
562 /* e0 */ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
563 /* f0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 3, 3, 2, 2,
564};
565
566// The code_item at `codeOff`, with its instruction array range checked. nullptr is one that cannot
567// be read: an offset outside the mapping, or an instruction count that runs past the end.
568static const uint8_t* dexReadCode(const FFDexTables* tables, uint32_t codeOff) {
569 const uint8_t* code = tables->dex + codeOff;
570 if (!dexInRange(tables->dex, tables->end, code, FF_DEX_OFF_CODE_INSNS)) {
571 return nullptr;
572 }
573 const uint32_t insnsSize = dexU32(code + FF_DEX_OFF_CODE_INSNS_SIZE);
574 if (!dexTableInRange(tables->dex, tables->end, code + FF_DEX_OFF_CODE_INSNS, insnsSize, 2)) {
575 return nullptr;
576 }
577 return code;
578}
579
580// Records `name` and `type` as the next field of a write sequence, unless the name is already in it.
581//
582// An array field is read twice: once for its length, which is the count written ahead of the elements,
583// and again inside the loop that writes them. A class cannot declare two instance fields under one
584// name, so a repeat is always that reload, and the first read is where the field belongs in the
585// sequence.
586//
587// A name or descriptor longer than the caller's buffer is refused rather than truncated: half a name
588// matches nothing, which is indistinguishable from the field not being in the class at all. Refusing
589// one field leaves the whole sequence unwritten, because a caller walking a sequence with a hole in
590// it would read every field behind the hole from the wrong place.
591static bool dexParcelFieldAdd(FFDexParcelField* fields, uint32_t* count, uint32_t capacity, const char* name, const char* type) {
592 for (uint32_t i = 0; i < *count; ++i) {
593 if (strcmp(fields[i].name, name) == 0) {
594 return true;
595 }
596 }
597 if (*count >= capacity) {
598 return false;
599 }
600 const size_t nameSize = strlen(name) + 1;
601 const size_t typeSize = strlen(type) + 1;
602 if (nameSize > FF_DEX_PARCEL_FIELD_NAME_MAX || typeSize > FF_DEX_PARCEL_FIELD_TYPE_MAX) {
603 return false;
604 }
605 memcpy(fields[*count].name, name, nameSize);
606 memcpy(fields[*count].type, type, typeSize);
607 ++*count;
608 return true;
609}
610
611// Walks the instruction grid of a code_item and records every instance field the method reads, in the
612// order it reads them -- which is the order `writeToParcel` puts them on the wire.
613//
614// The grid is followed by opcode width, so the walk only ever lands on an instruction start, and it
615// stops at the first payload pseudo-instruction. A `switch` or a `fill-array-data` leaves one behind
616// every reachable instruction; its contents are data rather than instructions, and stepping into it
617// desynchronises the grid for good.
618//
619// `iget*` and `iput*` share a format and put the field index in the code unit behind the opcode in
620// both, which is what lets one test cover the whole range. A `writeToParcel` does not store to a
621// field, so the `iput` half is never taken -- it is in the range because splitting it would be a
622// claim about the method that the opcode does not make.
623static const char* dexWalkParcelFields(const FFDexTables* tables, const uint8_t* code, FFDexParcelField* fields, uint32_t capacity, uint32_t* count) {
624 *count = 0;
625 const uint8_t* dex = tables->dex;
626 const uint8_t* end = tables->end;
627 const uint32_t insnsSize = dexU32(code + FF_DEX_OFF_CODE_INSNS_SIZE);
628 const uint8_t* insns = code + FF_DEX_OFF_CODE_INSNS;
629
630 for (uint32_t i = 0; i < insnsSize;) {
631 const uint16_t unit = dexU16(insns + (size_t) i * 2);
632 // The three payload pseudo-instructions put their ident in the high byte and zero in the low
633 // one. `nop` is the one instruction whose low byte is zero as well, and it is told apart by
634 // the whole code unit being zero. Testing the high byte alone is what gets this wrong: a
635 // `sparse-switch` over register 2 encodes as 0x022c, which is an instruction, not a payload.
636 if ((unit & 0xFF) == 0 && unit != 0) {
637 break;
638 }
639 const uint32_t opcode = unit & 0xFF;
640 if (opcode >= FF_DEX_OP_FIELD_FIRST && opcode <= FF_DEX_OP_FIELD_LAST) {
641 if (i + 1 >= insnsSize) {
642 break;
643 }
644 const uint32_t fieldIndex = dexU16(insns + ((size_t) i + 1) * 2);
645 if (fieldIndex >= tables->fieldIdCount) {
646 return "The dex field table is out of range";
647 }
648 const uint8_t* fieldId = tables->fieldIds + (size_t) fieldIndex * FF_DEX_FIELD_ID_SIZE;
649 const char* name = dexString(dex, end, dexU32(fieldId + FF_DEX_OFF_FIELD_ID_NAME));
650 const char* type = dexTypeString(tables, dexU16(fieldId + FF_DEX_OFF_FIELD_ID_TYPE));
651 if (name == nullptr || type == nullptr) {
652 return "The dex field is not resolvable";
653 }
654 if (!dexParcelFieldAdd(fields, count, capacity, name, type)) {
655 FF_DEBUG("\"%s\" (%s) does not fit a sequence of %u fields", name, type, capacity);
656 *count = 0;
657 return nullptr;
658 }
659 }
660 i += dexOpcodeSize[opcode];
661 }
662 return nullptr;
663}
664
665// Walks the instance field list of one `class_data_item` and writes `true` for every name it holds.
666// The list is the caller's, so this answers one request's worth of names or several.
667//
668// This is the question a Parcelable whose layout is not field-driven needs: `DisplayCutout` reads
669// everything through compiler-synthesised accessors, so the set of fields its class declares is the
670// only thing that says how long its body is. It is asked as part of a write-sequence request rather
671// than by a call of its own -- the list is already positioned by the `class_data_item` the sequence
672// comes out of, and a separate call would repeat the whole walk to reach it.
673static const char* dexMatchInstanceFields(const FFDexTables* tables, const uint8_t* fields, uint32_t fieldCount, const char* const* names, bool* results, uint32_t nameCount) {
674 const uint8_t* dex = tables->dex;
675 const uint8_t* end = tables->end;
676
677 uint32_t fieldIndex = 0;
678 for (uint32_t j = 0; j < fieldCount; ++j) {
679 if (fields >= end) {
680 return "The dex class data is truncated";
681 }
682 const uint32_t fieldIndexDiff = dexUleb128(&fields, end); // field_idx_diff
683 if (fieldIndexDiff > UINT32_MAX - fieldIndex) {
684 return "The dex field index is out of range";
685 }
686 fieldIndex += fieldIndexDiff;
687 (void) dexUleb128(&fields, end); // access_flags
688
689 if (fieldIndex >= tables->fieldIdCount) {
690 return "The dex field table is out of range";
691 }
692 const char* name = dexString(dex, end, dexU32(tables->fieldIds + (size_t) fieldIndex * FF_DEX_FIELD_ID_SIZE + FF_DEX_OFF_FIELD_ID_NAME));
693 if (name == nullptr) {
694 continue;
695 }
696 for (uint32_t i = 0; i < nameCount; ++i) {
697 if (!results[i] && strcmp(name, names[i]) == 0) {
698 results[i] = true;
699 }
700 }
701 }
702 return nullptr;
703}
704
705// Walks the method list of the class that `typeIndex` names, and for every request whose method name
706// it holds walks that method's instructions. `defined` is what `dexClassStaticInts` reports, for the
707// same reason.
708//
709// A request the class does not answer is closed with a count of 0 -- the count a caller reads as
710// "this build does not write that class", which is the truth: the class is this dex's, so no later
711// entry of the jar has the method either.
712static const char* dexClassParcelFields(const FFDexTables* tables, uint32_t typeIndex, const FFDexParcelRequest* requests, const uint32_t* typeIndexes, uint8_t* settled, uint32_t count, bool* defined) {
713 const uint8_t* classDef = dexFindClassDef(tables, typeIndex);
714 *defined = classDef != nullptr;
715 if (classDef == nullptr) {
716 return nullptr;
717 }
718
719 const uint8_t* dex = tables->dex;
720 const uint8_t* end = tables->end;
721
722 FFDexClassData classData;
723 const char* error = dexReadClassData(tables, classDef, &classData);
724 if (error != nullptr) {
725 return error;
726 }
727
728 // The instance fields first, out of the list the `class_data_item` has already positioned. A
729 // request that asked for them is answered here whether or not it also asked for a sequence, and
730 // one that asked for neither is settled by the loop at the end like any other.
731 for (uint32_t r = 0; r < count; ++r) {
732 if (settled[r] || typeIndexes[r] != typeIndex || requests[r].instanceFieldCount == 0) {
733 continue;
734 }
735 error = dexMatchInstanceFields(
736 tables, classData.instanceFields, classData.instanceFieldCount,
737 requests[r].instanceFieldNames, requests[r].instanceFieldResults, requests[r].instanceFieldCount
738 );
739 if (error != nullptr) {
740 return error;
741 }
742 }
743
744 const uint8_t* methods = classData.methods;
745 // Two runs, each delta-encoded from zero on its own -- so the index is reset per run rather than
746 // carried across, and a direct method and a virtual one under the same index both resolve.
747 for (uint32_t list = 0; list < 2; ++list) {
748 const uint32_t listCount = list == 0 ? classData.directMethodCount : classData.virtualMethodCount;
749 uint32_t methodIndex = 0;
750 for (uint32_t j = 0; j < listCount; ++j) {
751 if (methods >= end) {
752 return "The dex class data is truncated";
753 }
754 const uint32_t methodIndexDiff = dexUleb128(&methods, end); // method_idx_diff
755 if (methodIndexDiff > UINT32_MAX - methodIndex) {
756 return "The dex method index is out of range";
757 }
758 methodIndex += methodIndexDiff;
759 (void) dexUleb128(&methods, end); // access_flags
760 const uint32_t codeOff = dexUleb128(&methods, end);
761
762 if (methodIndex >= tables->methodIdCount) {
763 return "The dex method table is out of range";
764 }
765 const char* name = dexString(dex, end, dexU32(tables->methodIds + (size_t) methodIndex * FF_DEX_METHOD_ID_SIZE + FF_DEX_OFF_METHOD_ID_NAME));
766 if (name == nullptr) {
767 continue;
768 }
769
770 for (uint32_t r = 0; r < count; ++r) {
771 // A request that left the sequence out is one that only wanted the instance fields,
772 // which are already written; it has no method name to match against.
773 if (settled[r] || typeIndexes[r] != typeIndex || requests[r].methodName == nullptr
774 || strcmp(name, requests[r].methodName) != 0) {
775 continue;
776 }
777 // A method with no body -- abstract, or native -- writes nothing, and the count stays 0.
778 const uint8_t* code = codeOff == 0 ? nullptr : dexReadCode(tables, codeOff);
779 if (codeOff != 0 && code == nullptr) {
780 return "The dex code is out of range";
781 }
782 if (code != nullptr) {
783 error = dexWalkParcelFields(tables, code, requests[r].fields, requests[r].capacity, requests[r].count);
784 if (error != nullptr) {
785 return error;
786 }
787 }
788 settled[r] = 1;
789 }
790 }
791 }
792
793 // The class is defined here, so a request of its own that went unanswered is one whose method the
794 // class does not declare. The count it already holds is the 0 that says so.
795 for (uint32_t r = 0; r < count; ++r) {
796 if (!settled[r] && typeIndexes[r] == typeIndex) {
797 settled[r] = 1;
798 }
799 }
800 return nullptr;
801}
802
803// ---------------------------------------------------------------------------------------------
804// Locating classes.dex
805// ---------------------------------------------------------------------------------------------
806
807typedef struct FFDexMapping {
808 uint8_t* mapped; // the jar, as mapped; nullptr once released
809 size_t mappedSize;
810} FFDexMapping;
811
812static void wrapDexMapping(FFDexMapping* mapping) {
813 assert(mapping);
814 if (mapping->mapped != nullptr) {
815 munmap(mapping->mapped, mapping->mappedSize);
816 }
817}
818
819// Maps the jar read-only. The pages the walk touches are the only ones faulted in, which is what
820// keeps a 52 MB framework.jar off the heap and out of the cost of a lookup. The mapping outlives the
821// descriptor, so the descriptor is closed before this returns.
822static const char* dexMapJar(const char* jarPath, FFDexMapping* mapping) {
823 FF_AUTO_CLOSE_FD int fd = open(jarPath, O_RDONLY | O_CLOEXEC);
824 if (fd < 0) {
825 FF_DEBUG("open(%s) failed: %s", jarPath, strerror(errno));
826 return "open(jar) failed";
827 }
828
829 struct stat st = {};
830 const int statStatus = fstat(fd, &st);
831 if (statStatus != 0 || st.st_size <= 0) {
832 FF_DEBUG("fstat(%s) reported %s (%lld bytes)", jarPath,
833 statStatus != 0 ? strerror(errno) : "an empty file", (long long) st.st_size);
834 return "fstat(jar) failed";
835 }
836 mapping->mappedSize = (size_t) st.st_size;
837 mapping->mapped = mmap(nullptr, mapping->mappedSize, PROT_READ, MAP_PRIVATE, fd, 0);
838 if (mapping->mapped == MAP_FAILED) {
839 FF_DEBUG("mmap(%s, %zu bytes) failed: %s", jarPath, mapping->mappedSize, strerror(errno));
840 mapping->mapped = nullptr;
841 return "mmap(jar) failed";
842 }
843 return nullptr;
844}
845
846// Locates `classesN.dex` in the jar's central directory. The walk that finds an entry is the same
847// one the app label reader needs for an APK's resource table, so it lives in common/android/zip.h
848// and this is the dex-specific half of the question: which name to ask for.
849static const char* findDexEntry(const uint8_t* jar, size_t jarSize, const char* entry, const uint8_t** data, size_t* dataSize, uint32_t* uncompressedSize, uint16_t* method) {
850 FFAndroidZipEntry found = {};
851 const char* error = ffAndroidZipFindEntry(jar, jarSize, entry, &found);
852 if (error != nullptr) {
853 return error;
854 }
855 *data = found.payload;
856 *dataSize = found.payloadSize;
857 *uncompressedSize = found.uncompressedSize;
858 *method = found.method;
859 return nullptr;
860}
861
862// Fallback for a jar whose entry is STORED but whose header has no sizes: the dex magic is then a
863// literal run of bytes in the file, and the header that follows it validates or it does not. It
864// only ever locates the *first* dex in the jar, so it is a fallback for `classes.dex` alone.
865static const uint8_t* findDexMagic(const uint8_t* jar, size_t jarSize, size_t* dexSize) {
866 for (size_t i = 0; i + FF_DEX_HEADER_SIZE <= jarSize; ++i) {
867 if (memcmp(jar + i, FF_DEX_MAGIC, sizeof(FF_DEX_MAGIC) - 1) != 0) {
868 continue;
869 }
870 const uint8_t* dex = jar + i;
871 const uint32_t fileSize = dexU32(dex + FF_DEX_OFF_FILE_SIZE);
872 if (dexU32(dex + FF_DEX_OFF_ENDIAN_TAG) != FF_DEX_ENDIAN_TAG) {
873 continue;
874 }
875 if (fileSize < FF_DEX_HEADER_SIZE || fileSize > jarSize - i) {
876 continue;
877 }
878 *dexSize = fileSize;
879 return dex;
880 }
881 return nullptr;
882}
883
884#ifdef FF_HAVE_ZLIB
885static const char* inflateDex(const uint8_t* data, size_t dataSize, uint32_t uncompressedSize, uint8_t** out) {
886 const char* error = ffZlibLoad(FF_ZLIB_INFLATE);
887 if (error != nullptr) {
888 FF_DEBUG("The dex cannot be inflated: %s", error);
889 return error;
890 }
891
892 // Released by the cleanup on every path out below; ownership moves to the caller by clearing
893 // the pointer, which is also why no failure path has to free it by hand.
894 FF_AUTO_FREE uint8_t* buffer = malloc(uncompressedSize);
895 if (buffer == nullptr) {
896 FF_DEBUG("malloc(%u) for the inflated dex failed", uncompressedSize);
897 return "malloc failed";
898 }
899
900 // `uncompress` is not usable here: a zip entry holds a raw deflate stream, without the two byte
901 // zlib header that entry point insists on. A negative window size tells inflate to skip the
902 // header, which is what the zip format expects.
903 z_stream stream = {};
904 stream.next_in = (Bytef*) data;
905 stream.avail_in = (uInt) dataSize;
906 stream.next_out = buffer;
907 stream.avail_out = (uInt) uncompressedSize;
908
909 const int initStatus = inflateInit2(&stream, -MAX_WBITS);
910 if (initStatus != Z_OK) {
911 FF_DEBUG("inflateInit2() failed: zlib status %d", initStatus);
912 return "inflateInit2 failed";
913 }
914 const int status = inflate(&stream, Z_FINISH);
915 inflateEnd(&stream);
916 if (status != Z_STREAM_END || stream.total_out != (uLong) uncompressedSize) {
917 FF_DEBUG("inflate() returned %d, produced %lu of %u bytes",
918 status, stream.total_out, uncompressedSize);
919 return "Inflating the dex failed";
920 }
921
922 *out = buffer;
923 buffer = nullptr; // the caller owns it from here
924 return nullptr;
925}
926#endif
927
928// The dex bytes of one jar entry, and the validated tables of the dex they hold.
929typedef struct FFDexEntry {
930 const uint8_t* data;
931 size_t size;
932 FFDexTables tables;
933} FFDexEntry;
934
935// Locates `classesN.dex`, inflates it when the entry is deflated, and validates the header.
936//
937// `present` reports whether the jar holds the entry at all. A jar spreads its classes over as many
938// entries as it needs and then simply runs out, so an entry that is not there ends the walk rather
939// than failing it -- except for the first, which every jar has and which is where the magic scan
940// stands in for a directory that cannot be read. `inflated` receives the buffer the caller has to
941// release when the entry needed one, and is left alone otherwise.
942static const char* dexOpenEntry(const FFDexMapping* mapping, uint32_t index, bool* present, uint8_t** inflated, FFDexEntry* entry) {
943 // Wide enough for `classes999.dex`, which is the longest name `FF_DEX_MAX_ENTRIES` can ask for.
944 char name[sizeof("classes999.dex")];
945 if (index == 1) {
946 memcpy(name, FF_DEX_ENTRY, sizeof(FF_DEX_ENTRY));
947 } else {
948 (void) snprintf(name, sizeof(name), "classes%u.dex", index);
949 }
950 *present = true;
951
952 const uint8_t* data = nullptr;
953 size_t dataSize = 0;
954 uint32_t uncompressedSize = 0;
955 uint16_t method = FF_ZIP_METHOD_STORED;
956 if (findDexEntry(mapping->mapped, mapping->mappedSize, name, &data, &dataSize, &uncompressedSize, &method) != nullptr) {
957 if (index > 1) {
958 // The magic scan only ever finds the first dex, so it cannot stand in for a later entry:
959 // running past the end of the entries that exist ends the walk.
960 *present = false;
961 return nullptr;
962 }
963 data = findDexMagic(mapping->mapped, mapping->mappedSize, &dataSize);
964 if (data == nullptr) {
965 FF_DEBUG("Neither %s nor a dex magic signature is in the %zu byte jar", name, mapping->mappedSize);
966 return "No dex in the jar";
967 }
968 } else if (method == FF_ZIP_METHOD_DEFLATED) {
969 #ifdef FF_HAVE_ZLIB
970 const char* error = inflateDex(data, dataSize, uncompressedSize, inflated);
971 if (error != nullptr) {
972 return error;
973 }
974 data = *inflated;
975 dataSize = uncompressedSize;
976 #else
977 (void) inflated; // the parameter is only written on the inflating path
978 return "The jar deflates its dex entries and fastfetch was built without zlib";
979 #endif
980 } else if (method != FF_ZIP_METHOD_STORED) {
981 FF_DEBUG("%s uses compression method %u, only %u (stored) and %u (deflated) are handled",
982 name, method, FF_ZIP_METHOD_STORED, FF_ZIP_METHOD_DEFLATED);
983 return "A dex entry uses an unsupported compression method";
984 }
985 // A STORED entry needs no further work: `dataSize` already holds the `compressedSize` that
986 // `findDexEntry` checked against the mapping, and for a STORED entry the payload is the file
987 // itself. The header's `uncompressedSize` is deliberately not used for it -- nothing bounds that
988 // value, so a corrupt one reaches past the end of the mapping, which is exactly what the dex
989 // header would then be validated against.
990
991 entry->data = data;
992 entry->size = dataSize;
993 return dexOpen(entry->data, entry->size, &entry->tables);
994}
995
996const char* ffDexStaticInts(const char* jarPath, const FFDexStaticIntRequest* requests, uint32_t count) {
997 // Every request is written the sentinel before anything can fail, so that a caller reads a result
998 // rather than whatever its own stack held there, however this returns. Nothing below has to
999 // remember to do it on its way out.
1000 for (uint32_t r = 0; r < count; ++r) {
1001 *requests[r].result = FF_DEX_STATIC_INT_UNRESOLVED;
1002 }
1003 if (count == 0) {
1004 return nullptr;
1005 }
1006
1007 [[gnu::cleanup(wrapDexMapping)]] FFDexMapping mapping = {};
1008 const char* error = dexMapJar(jarPath, &mapping);
1009 if (error != nullptr) {
1010 return error;
1011 }
1012
1013 // One byte per request saying whether it is closed -- answered, or given up on -- the type index
1014 // it was found under in the entry being walked, and the descriptor that index was found for. All
1015 // three are sized from `count` rather than from a fixed bound, and all three are released by
1016 // their cleanup however this function returns.
1017 FF_AUTO_FREE uint8_t* settled = calloc(count, 1);
1018 FF_AUTO_FREE uint32_t* typeIndexes = malloc((size_t) count * sizeof(uint32_t));
1019 FF_AUTO_FREE const char** descriptors = malloc((size_t) count * sizeof(const char*));
1020 if (settled == nullptr || typeIndexes == nullptr || descriptors == nullptr) {
1021 FF_DEBUG("Allocating the tables for %u static int requests failed", count);
1022 return "malloc failed";
1023 }
1024 for (uint32_t r = 0; r < count; ++r) {
1025 descriptors[r] = requests[r].classDescriptor;
1026 }
1027
1028 // A jar spreads its classes over `classes.dex`, `classes2.dex`, `classes3.dex`, ... and the
1029 // class being looked for is in whichever one the build put it in: `IAudioService$Stub` is in the
1030 // second dex of framework.jar, while `IWifiManager$Stub` is in the first of framework-wifi.jar.
1031 // The entries are therefore tried in order, and the first one that defines the class answers.
1032 // The count is a bound on the walk, not a claim about the jar -- AOSP has never shipped more
1033 // than a handful, and a class that is in none of them is left unanswered either way.
1034 //
1035 // The walk ends as soon as the last request is closed, so an entry that holds every class asked
1036 // for -- which is what the modules here ask for, one class per interface -- costs one entry read
1037 // and one pass over its type table.
1038 uint32_t pending = count;
1039 for (uint32_t index = 1; index <= FF_DEX_MAX_ENTRIES && pending > 0; ++index) {
1040 // The decompressed dex, when the entry needed one. The cleanup releases it at the end of
1041 // the iteration, so every entry gets a buffer of its own and no way out of the loop -- an
1042 // early return included -- can leak one.
1043 FF_AUTO_FREE uint8_t* inflated = nullptr;
1044 FFDexEntry entry = {};
1045 bool present = false;
1046 error = dexOpenEntry(&mapping, index, &present, &inflated, &entry);
1047 if (error != nullptr) {
1048 // The dex cannot be read at all, which no later entry can fix.
1049 return error;
1050 }
1051 if (!present) {
1052 break;
1053 }
1054
1055 dexFindTypes(&entry.tables, descriptors, settled, typeIndexes, count);
1056
1057 // Every class this entry defines is walked once, however many of its fields were asked for.
1058 // A request whose class is not in this entry's type table keeps `UINT32_MAX` and is left for
1059 // the next entry; one whose class is only referenced here is left the same way by the walk
1060 // below, which is what `defined` reports.
1061 for (uint32_t r = 0; r < count; ++r) {
1062 if (settled[r] || typeIndexes[r] == UINT32_MAX) {
1063 continue;
1064 }
1065 const uint32_t typeIndex = typeIndexes[r];
1066 bool defined = false;
1067 error = dexClassStaticInts(&entry.tables, typeIndex, requests, typeIndexes, settled, count, &defined);
1068 if (error != nullptr) {
1069 // The dex cannot be read, which no later entry can fix.
1070 return error;
1071 }
1072 if (!defined) {
1073 // Only referenced here, so the class is left for the next entry -- and the requests
1074 // that share it are marked as walked, since one lookup of a class answers all of
1075 // them and the class table should not be scanned once per field.
1076 for (uint32_t s = r; s < count; ++s) {
1077 if (typeIndexes[s] == typeIndex) {
1078 typeIndexes[s] = UINT32_MAX;
1079 }
1080 }
1081 }
1082 }
1083
1084 pending = 0;
1085 for (uint32_t r = 0; r < count; ++r) {
1086 if (!settled[r]) {
1087 ++pending;
1088 }
1089 }
1090 }
1091
1092 // What is still open is a class no entry of the jar defines. That is an answer like any other --
1093 // the results already hold the sentinel, written before the walk began -- so the only thing left
1094 // is to say so for a debug build, where the sentinel on its own does not tell "this build has no
1095 // such method" apart from "the reader went wrong".
1096 for (uint32_t r = 0; r < count; ++r) {
1097 if (*requests[r].result == FF_DEX_STATIC_INT_UNRESOLVED) {
1098 FF_DEBUG("\"%s\" is not a static int field of \"%s\"", requests[r].fieldName, requests[r].classDescriptor);
1099 }
1100 }
1101 return nullptr;
1102}
1103
1104const char* ffDexParcelFields(const char* jarPath, const FFDexParcelRequest* requests, uint32_t count) {
1105 // Every request is written its answers before anything can fail, so that a caller reads an answer
1106 // rather than whatever its own stack held there, however this returns. The instance fields go
1107 // first: `false` is what both "the class does not declare it" and "the jar cannot be read" mean,
1108 // and the walk below only ever turns one of them true.
1109 for (uint32_t r = 0; r < count; ++r) {
1110 if (requests[r].methodName != nullptr) {
1111 *requests[r].count = 0;
1112 }
1113 for (uint32_t i = 0; i < requests[r].instanceFieldCount; ++i) {
1114 requests[r].instanceFieldResults[i] = false;
1115 }
1116 }
1117 if (count == 0) {
1118 return nullptr;
1119 }
1120
1121 [[gnu::cleanup(wrapDexMapping)]] FFDexMapping mapping = {};
1122 const char* error = dexMapJar(jarPath, &mapping);
1123 if (error != nullptr) {
1124 return error;
1125 }
1126
1127 FF_AUTO_FREE uint8_t* settled = calloc(count, 1);
1128 FF_AUTO_FREE uint32_t* typeIndexes = malloc((size_t) count * sizeof(uint32_t));
1129 FF_AUTO_FREE const char** descriptors = malloc((size_t) count * sizeof(const char*));
1130 if (settled == nullptr || typeIndexes == nullptr || descriptors == nullptr) {
1131 FF_DEBUG("Allocating the tables for %u parcel field requests failed", count);
1132 return "malloc failed";
1133 }
1134 for (uint32_t r = 0; r < count; ++r) {
1135 descriptors[r] = requests[r].classDescriptor;
1136 }
1137
1138 uint32_t pending = count;
1139 for (uint32_t index = 1; index <= FF_DEX_MAX_ENTRIES && pending > 0; ++index) {
1140 FF_AUTO_FREE uint8_t* inflated = nullptr;
1141 FFDexEntry entry = {};
1142 bool present = false;
1143 error = dexOpenEntry(&mapping, index, &present, &inflated, &entry);
1144 if (error != nullptr) {
1145 // The dex cannot be read at all, which no later entry can fix.
1146 return error;
1147 }
1148 if (!present) {
1149 break;
1150 }
1151
1152 dexFindTypes(&entry.tables, descriptors, settled, typeIndexes, count);
1153
1154 for (uint32_t r = 0; r < count; ++r) {
1155 if (settled[r] || typeIndexes[r] == UINT32_MAX) {
1156 continue;
1157 }
1158 const uint32_t typeIndex = typeIndexes[r];
1159 bool defined = false;
1160 error = dexClassParcelFields(&entry.tables, typeIndex, requests, typeIndexes, settled, count, &defined);
1161 if (error != nullptr) {
1162 return error;
1163 }
1164 if (!defined) {
1165 for (uint32_t s = r; s < count; ++s) {
1166 if (typeIndexes[s] == typeIndex) {
1167 typeIndexes[s] = UINT32_MAX;
1168 }
1169 }
1170 }
1171 }
1172
1173 pending = 0;
1174 for (uint32_t r = 0; r < count; ++r) {
1175 if (!settled[r]) {
1176 ++pending;
1177 }
1178 }
1179 }
1180
1181 // A request still holding 0 is one whose class no entry of the jar defines, or whose class does
1182 // not declare the method. Both are the same answer -- this build does not write that class -- and
1183 // for a debug build it is worth saying which of the two it was, since the count on its own does
1184 // not tell "this build has no such method" apart from "the reader went wrong". The same goes for
1185 // an instance field left `false`.
1186 for (uint32_t r = 0; r < count; ++r) {
1187 if (requests[r].methodName != nullptr && *requests[r].count == 0) {
1188 FF_DEBUG("The write sequence of \"%s.%s\" is not in the jar", requests[r].classDescriptor, requests[r].methodName);
1189 }
1190 for (uint32_t i = 0; i < requests[r].instanceFieldCount; ++i) {
1191 if (!requests[r].instanceFieldResults[i]) {
1192 FF_DEBUG("\"%s\" is not an instance field of \"%s\"", requests[r].instanceFieldNames[i], requests[r].classDescriptor);
1193 }
1194 }
1195 }
1196 return nullptr;
1197}