Repository navigation
fix(getclass): reach non-BMP class names by encoding the query as MUTF-8 - #46
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ApkHandler.get_class_dexencoded its query with.encode("utf-8"), but dexstring_data_itemis MUTF-8: a code point above the BMP is stored as a surrogate pair (CESU-8). For ASCII and BMP names the two encodings are byte-identical, so nothing showed — but an astral class name could never match, and the lookup reported "class not found" before decompilation ever ran.Measured against
_find_type_idxdirectly:Ll/\U00010000;(astral)Ll/\u06e1;(BMP)Lexample/Test;Encoding the query the way the dex stores it is the whole fix. No linear fallback is needed: CESU-8 preserves UTF-16 code-unit ordering, so the binary search over the type table stays valid.
Scope
Only names containing a code point above the BMP change behaviour — ASCII and BMP names encode identically both ways, so their byte-for-byte path is untouched. I compared both encodings against each other before switching.
The encoder is
mutf8(already a dependency, used bydex_builder), a compiled extension costing ~19ms to import. It is imported only for a name that actually needs it, so ordinary lookups pay nothing, and a successful astral lookup is net-zero anyway since decompilation loadsmutf8moments later on the same path.Verification
python tests/run_tests.py --require-decompiler→ 107 tests, OK.decompile_class(apk, "Ll/𐀀;")returns source, and every name from a class listing feeds back intodecompile_class.benchmark_startup.py, 9 samples; this machine reads 108–111ms with or without the change, over the 100ms Linux-CI budget either way).Tests
Nothing in the tree covers this path today.
tests/test_mutf8_strings.pyis the natural home — it already owns the MUTF-8 cases — e.g. a fixture whose descriptors are sorted by UTF-16 code units with an astral entry, assertingget_class_dexresolves it. Happy to add that to this PR, or as a follow-up if you'd rather keep the change minimal.