Fix "android:* not found" errors#4137
Conversation
|
thanks and appreciate the detailed steps! What I hit prior to this was when I was exploring multi-package apks - defaulting everything to a new namespace led to different issues. I was trying to identify a method of "picking/inventing" a namespace name that we can consistently resolve knowing the pkgId (or name). That way across many files we can devise and invent the same prefix. @IgorEisberg may have a bit more modern knowledge at this than me to voice his thoughts. |
You can't, each binary XML is independent of others. Even if one doesn't define a prefix for a certain namespace, you can't rely on other XML files to fill the gap (i.e. "normalize" the namespaces).
I just kept the same behavior because I never stumbled upon all possible edge cases - didn't want to break anything, so I don't know much about stripped namespaces at the moment. |
|
I was thinking of the normalization based on the pkg name, since we do know which pkg each XML is from. So stuff like For this PR - I think we could expand test suite for this test and store the source sample app in https://github.com/iBotPeaches/TestApks |
|
Thanks for the feedback ! When the namespaces are wiped, the only real value you can hang on to is the pkgId, so maybe it would be possible to use that as a reference and create One issue is, because XML files are indeed independent, we can't be sure that all files either do or do not have namespaces. Maybe apktool could keep a global table of namespaces (and whether it would have to invent any) mapped to the corresponding pkgId ? |
|
@iBotPeaches What you're suggesting is really messy when using a PullParser -> Serializer copy flow. This quickly turns into a mess. |
I showed an example why relying on a "global pool of namespaces" is nonsensical and can never be trusted. |
|
Added my test APK and a test case to the suite (let me know if you would like more tests). As for the multi-package topic, if I understand correctly, this is not something Apktool does as of now (resolving non-sys non-auto namespaces if wiped). This PR does not aim to fix the multi-package resources, but hopefully at least makes a step in the right direction. When trying to solve the bug caused when trying to resolve the Also, the current implementation uses the attribute index as input to determine the correct namespace, but I can't figure out why that logic would work, and why the attribute index should have an impact on the chosen namespace. As far as I can tell this is a bug, but maybe there is some structure/logic that I'm not aware of? Let me know what you think, I'd be happy to help ! Thanks again for the input. |
iBotPeaches
left a comment
There was a problem hiding this comment.
Merge if you are happy @IgorEisberg
Frankly I don't know, you had that function for a reason and I haven't seen all possible edge cases, so it's up to you. It's up to you, I'm not confident enough here. |
|
I have collected APKs from AXML-related issues to potentially find edge cases. I tested decoding-rebuilding APKs available from issues #1157, #2615 and #2981 and did not encounter any problem there. The APK from issue #2531 however, did throw a Also, I have been doing some research on that
It's of course up to you guys, but since we have a test case for this flow, maybe it makes most sense to merge and make sure that if edge-cases pop up we create proper tests for those too and review the logic? While the APK in the test case is created as a PoC, I can link to publicly available APKs that show this behaviour if needed. |
|
Okay, I like the research provided and I wrote a lot of this so long ago when I was younger and dumber. I'll merge it tonight and update changelog. Thanks for the research and fix @Sleeeee |
Fix formatting issue in unreleased changes list.
This PR aims to fix the problem discussed in #3533. This effectively solves it for all the scenarios I've encountered/recreated, but please let me know if there are edge cases, I'd be happy to help.
To summarize, when resource namespaces are stripped, Apktool sometimes resolves the wrong namespace. The resolving passes the index of the attribute to
getNonDefaultNamespaceUri()which fetches a namespace from the pool. When namespaces are stripped from the resource XML files, app attributes can be wrongly decoded asandroid:in specific conditions.The suggested fix is, for app resources (
nameId.pkgId() == 0x7f), instead of callinggetNonDefaultNamespaceUri(), we can safely returnANDROID_RES_NS_AUTOto resolve the namespace.To recreate the issue, we can use this hello world app. The source code contains this resource at
res/drawable/trap.xml:Corresponding binary after building :
We can strip the namespace for
is_obfuscatedat offset0x17c:After replacing the file in the APK and realigning/resigning, it installs perfectly and does not break.
When decoding with apktool however, the attribute will be prefixed with
android::When rebuilding, we get the infamous error:
With this patch, resources will be correctly decoded and prevent apktool from crashing in those conditions :
fixes: #3533