Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to stop the reorganization of the resource IDs in file ‘res/values/public.xml’ when I use command ’apktool b apkfile/’? #2062

Closed
yanglee0801 opened this issue Apr 22, 2019 · 24 comments

Comments

@yanglee0801
Copy link

I used ‘apktool d test.apk’ to decompile the apk, then add some smali code and resource. These resources are got from the decompilation of other apks with their own ‘public.xml’ files. I copied the relative IDs of these resource to present ‘public.xml’.
I have already solved the conflict of resource IDs. However, the resource IDs in ‘public.xml’ were reorganized after I use ‘apktool b test/’. How can I use previous inner resource IDs in file ‘public.xml’ and avoid the reorganization?

@yanglee0801
Copy link
Author

I used v2.4.1-cc194d-SNAPSHOT on macOS

@iBotPeaches
Copy link
Owner

Reorganized in terms of the IDs themselves or the order of them in public.xml?

@yanglee0801
Copy link
Author

Reorganized in terms of the IDs themselves or the order of them in public.xml?

I tryed,but failed. when i used "apktool b test/",the public.xml was reorganized.

@yanglee0801
Copy link
Author

Reorganized in terms of the IDs themselves or the order of them in public.xml?

Sorry for being late. May I have your email, or, could you please contact me by email ([email protected]) for some details?

@iBotPeaches
Copy link
Owner

Reorganized in terms of the IDs themselves or the order of them in public.xml?

I tryed,but failed. when i used "apktool b test/",the public.xml was reorganized.

This doesn't answer my question. I do not understand.

Order of the ids change? or the ids themselves?

@Lanchon
Copy link

Lanchon commented Apr 27, 2019

I have already solved the conflict of resource IDs.

you can't do that. resource IDs are (typically) burnt into the dex code and cannot be changed there. so you can't integrate dex code (or smali) from apks that use conflicting resource IDs.

if you want to modify an APK by adding "you own APK" to it, you can't do it this way. try using DexPatcher instead.

@yanglee0801
Copy link
Author

Reorganized in terms of the IDs themselves or the order of them in public.xml?

I tryed,but failed. when i used "apktool b test/",the public.xml was reorganized.

This doesn't answer my question. I do not understand.

Order of the ids change? or the ids themselves?

I have already solved the conflict of resource IDs.

you can't do that. resource IDs are (typically) burnt into the dex code and cannot be changed there. so you can't integrate dex code (or smali) from apks that use conflicting resource IDs.

if you want to modify an APK by adding "you own APK" to it, you can't do it this way. try using DexPatcher instead.

Reorganized in terms of the IDs themselves or the order of them in public.xml?

I tryed,but failed. when i used "apktool b test/",the public.xml was reorganized.

This doesn't answer my question. I do not understand.

Order of the ids change? or the ids themselves?

I changed aapt code in A APK, using 0x6d as beginning. So i believe there should not have conflict when I copy public.xl in Aapkfilr to Bapkfile.
I didn't add my apk to other apk, i want to add my smali ,resource and others into other apk.

i am not copy the public.xml file , i do the resource item like this

i am not adding my apk to other apk,i want to add my smali ,resource and others into other apk,
oh , i forget to say i do a SDK for other Developers, my own SDK always update, so i don't want developers need to update my SDK ,they can access only one empty SDK(only has interface) , than i got the APKs,and reverse APKs, used script to copy my SDKs smali , res and resource IDs into those APKs,and used apktool b file/ ,

is my way wrong?or i do the wrong operation?

@Lanchon
Copy link

Lanchon commented Apr 27, 2019

well that is not how android libs are supposed to work. have you considered a thin client library you give to devs and a separate implementation APK that you distribute?

the resource IDs in ‘public.xml’ were reorganized after I use ‘apktool b test/’. How can I use previous inner resource IDs in file ‘public.xml’ and avoid the reorganization?

again. what do you mean by reorganization? give a concrete example: show us example public.xml files.

@yanglee0801
Copy link
Author

well that is not how android libs are supposed to work. have you considered a thin client library you give to devs and a separate implementation APK that you distribute?

the resource IDs in ‘public.xml’ were reorganized after I use ‘apktool b test/’. How can I use previous inner resource IDs in file ‘public.xml’ and avoid the reorganization?

again. what do you mean by reorganization? give a concrete example: show us example public.xml files.

My sdk is work for games,games always use unity3d cocos or other engines,they do not used android stuio ,always eclipse or merge smali and res.they do not used gradle or maven. my sdk has google sdk,facebook sdk,line sdk and other sdk plugin, these sdk used R.layout.xx or R.id.xx to find res .when I Compile this,the R.id or R.layout will become 0x7f or 0xXX ids.

There is A apk's public.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <public type="anim" name="abc_fade_in" id="0x6d010000" />
    <public type="anim" name="abc_fade_out" id="0x6d010001" />
    <public type="anim" name="abc_grow_fade_in_from_bottom" id="0x6d010002" />
    <public type="anim" name="abc_popup_enter" id="0x6d010003" />
    <public type="anim" name="abc_popup_exit" id="0x6d010004" />
    <public type="anim" name="abc_shrink_fade_out_from_bottom" id="0x6d010005" />
    <public type="anim" name="abc_slide_in_bottom" id="0x6d010006" />
    <public type="anim" name="abc_slide_in_top" id="0x6d010007" />
    <public type="anim" name="abc_slide_out_bottom" id="0x6d010008" />
    <public type="anim" name="abc_slide_out_top" id="0x6d010009" />
    <public type="anim" name="loading_tip_guaimao" id="0x6d01000a" />
    <public type="anim" name="tooltip_enter" id="0x6d01000b" />
    <public type="anim" name="tooltip_exit" id="0x6d01000c" />
    <public type="attr" name="actionBarDivider" id="0x6d020000" />
    <public type="attr" name="actionBarItemBackground" id="0x6d020001" />
    <public type="attr" name="actionBarPopupTheme" id="0x6d020002" />
    <public type="attr" name="actionBarSize" id="0x6d020003" />
    <public type="attr" name="actionBarSplitStyle" id="0x6d020004" />
    <public type="attr" name="actionBarStyle" id="0x6d020005" />
    <public type="attr" name="actionBarTabBarStyle" id="0x6d020006" />

There is B apk's public.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <public type="id" name="button_login" id="0x7f010000" />
    <public type="id" name="sdk_imageView" id="0x7f010001" />
    <public type="layout" name="activity_main_empty" id="0x7f020000" />
    <public type="layout" name="sdk_splash" id="0x7f020001" />
    <public type="layout" name="sdk_splash2" id="0x7f020002" />
    <public type="mipmap" name="ic_launcher_empty" id="0x7f030000" />
    <public type="string" name="app_name" id="0x7f040000" />
    <public type="style" name="sdk_dialog" id="0x7f050000" />

Then I copy A to B. Now public.xml must be like this

<resources>
    <public type="id" name="button_login" id="0x7f010000" />
    <public type="id" name="sdk_imageView" id="0x7f010001" />
    <public type="layout" name="activity_main_empty" id="0x7f020000" />
    <public type="layout" name="sdk_splash" id="0x7f020001" />
    <public type="layout" name="sdk_splash2" id="0x7f020002" />
    <public type="mipmap" name="ic_launcher_empty" id="0x7f030000" />
    <public type="string" name="app_name" id="0x7f040000" />
    <public type="style" name="sdk_dialog" id="0x7f050000" />
    <public type="anim" name="abc_fade_in" id="0x6d010000" />
    <public type="anim" name="abc_fade_out" id="0x6d010001" />
    <public type="anim" name="abc_grow_fade_in_from_bottom" id="0x6d010002" />
    <public type="anim" name="abc_popup_enter" id="0x6d010003" />
    <public type="anim" name="abc_popup_exit" id="0x6d010004" />
    <public type="anim" name="abc_shrink_fade_out_from_bottom" id="0x6d010005" />
    <public type="anim" name="abc_slide_in_bottom" id="0x6d010006" />
    <public type="anim" name="abc_slide_in_top" id="0x6d010007" />
    <public type="anim" name="abc_slide_out_bottom" id="0x6d010008" />
    <public type="anim" name="abc_slide_out_top" id="0x6d010009" />
    <public type="anim" name="loading_tip_guaimao" id="0x6d01000a" />
    <public type="anim" name="tooltip_enter" id="0x6d01000b" />
    <public type="anim" name="tooltip_exit" id="0x6d01000c" />
    <public type="attr" name="actionBarDivider" id="0x6d020000" />
    <public type="attr" name="actionBarItemBackground" id="0x6d020001" />
    <public type="attr" name="actionBarPopupTheme" id="0x6d020002" />
    <public type="attr" name="actionBarSize" id="0x6d020003" />
    <public type="attr" name="actionBarSplitStyle" id="0x6d020004" />
    <public type="attr" name="actionBarStyle" id="0x6d020005" />
    <public type="attr" name="actionBarTabBarStyle" id="0x6d020006" />

But next ,I used apktool b B/ sign and run . BAPK got crash, tell me no resource found.then I used apktoo d B.apk to find the public.xml.it become like this

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <public type="anim" name="abc_fade_in" id="0x7f010000" />
    <public type="anim" name="abc_fade_out" id="0x7f010001" />
    <public type="anim" name="abc_grow_fade_in_from_bottom" id="0x7f010002" />
    <public type="anim" name="abc_popup_enter" id="0x7f010003" />
    <public type="anim" name="abc_popup_exit" id="0x7f010004" />
    <public type="anim" name="abc_shrink_fade_out_from_bottom" id="0x7f010005" />
    <public type="anim" name="abc_slide_in_bottom" id="0x7f010006" />
    <public type="anim" name="abc_slide_in_top" id="0x7f010007" />
    <public type="anim" name="abc_slide_out_bottom" id="0x7f010008" />
    <public type="anim" name="abc_slide_out_top" id="0x7f010009" />
    <public type="anim" name="loading_tip_guaimao" id="0x7f01000a" />
    <public type="anim" name="tooltip_enter" id="0x7f01000b" />
    <public type="anim" name="tooltip_exit" id="0x7f01000c" />
    <public type="attr" name="actionBarDivider" id="0x7f020000" />
    <public type="attr" name="actionBarItemBackground" id="0x7f020001" />
    <public type="attr" name="actionBarPopupTheme" id="0x7f020002" />
    <public type="attr" name="actionBarSize" id="0x7f020003" />
    <public type="attr" name="actionBarSplitStyle" id="0x7f020004" />
    <public type="attr" name="actionBarStyle" id="0x7f020005" />
    <public type="attr" name="actionBarTabBarStyle" id="0x7f020006" />

I find all of this ,can't find the ids begin of 0x6d .

@Lanchon
Copy link

Lanchon commented Apr 27, 2019

i see...

@iBotPeaches, it looks like AAPTx build (or apktool decode) is overwriting the high byte of IDs, which is sort of unexpected. i think an error should be reported instead, if possible.

@yanglee0801, ok so something is messing your IDs. however, i suspect that if the IDs were the way you want them, your solution wouldn't work anyway. so there is no point in fixing this ID handling "bug".

let me explain...

when you call getResources().getXxxxx(int resId), the framework looks for resources in a number of places. the framework, the apk, shared libraries, runtime resource overlays, etc. i think that, to speed things up, the framework will only look for a resource in a container if the container is legal for that ID.

for example, APK resource IDs should start with 0x7F, framework res IDs with 0x01, etc. so if framework resource 0x01020005 is requested, it will not be looked up in the APK. so any resources in the APK with IDs that don't start with 0x7F will be ignored and will never be found by the framework. (this is what i suspect anyway.)

so instead of numbering you lib IDs starting with 0x6d000000, you should try starting them with, say, 0x7fa50000. maybe that works.

does your SDK provide resources for the client? (ie: resources that have to be public?) or does it use its resources only internally from its code?

@yanglee0801
Copy link
Author

thank you for your suggest @Lanchon
if A project has a resource called R.layout.fg_login in AMainActivity , it's must has a layout name as fg_login in res/layout, when i build Aapk ,in AMainActivity smali this R.layout.fg_login,will change be 0x7f000001,
then B project has a resource called R.layout.main_activity in BMainActivity,when i build B apk,Actually android will make BMainActivity smali also userd 0x7f000001,
so,the two of public.xml will has same ids, In order to avoid this situation , i make A apks public.xml ids start with 0x6d .

i found a way to solve this problem,as i change those ids in public.xml ,i alse change thoes ids in smali,then they can got right resources. but this way was too cumbersome,i want to find a easy way.

do you understand what I mean?or i can send my project for you

@yanglee0801
Copy link
Author

i have something forget @Lanchon
i make the public.xml ids started with 0x6d , it's changed with aapt ,so,the A apk can normal recognition and normal operation.

@Lanchon
Copy link

Lanchon commented Apr 27, 2019

i alse change thoes ids in smali

you can't change them in code. you don't know if numbers are IDs or something else.

make A apks public.xml ids start with 0x6d .

make them start with 0x7f6d. can't you?
that way all resources start with 0x7f in the APK, which is required.

does your SDK provide resources for the client? (ie: resources that have to be public?) or does it use its resources only internally from its code?

you didn't respond

@Lanchon
Copy link

Lanchon commented Apr 27, 2019

there are many solutions to your problem, but not the one you want: all resource IDs in an APK must start with 0x7F. this is a limitation of Android (i think).

so you must choose a different solution.

@yanglee0801
Copy link
Author

i do not give anything res for other developers.A apks res was there developers's res.

sorry,i have no way to make resources start with 0x7f6d

you can't change them in code. you don't know if numbers are IDs or something else.

yeah,i make a mistake,i can not do that

My opinion is to make developers smali can read those res ids and my sdk read own. i also think about plugin,but plugin has too limit ,so i can not use it.

@Lanchon
Copy link

Lanchon commented Apr 27, 2019

sorry,i have no way to make resources start with 0x7f6d

you need all resources starting with 0x7f for APK to work on android.

if you can't make resources start with 0x7fXX, then you have to assign your IDs DURING POSTPROCESSING, after client gives you his APK.

you could do this manually, but it's complex and i have a tool for this that you can use: DexPatcher.

  1. give the client a java library with your API (empty or with old code). or the give client an android library with your API (empty or with old code, and with your public resources that they can use).

  2. client gives you the APK.

  3. you replace your API implementation (and resources) in the client's APK using dexpatcher.

how to do 3) ?

3a) use the 'patch-lib' sample:
https://github.com/DexPatcher/dexpatcher-gradle-samples/tree/v2/patch-lib

3b) put the client apk in the 'apklib' subproject.

3c) put your new API implementation in the 'patch' subproject, plus package annotation(s) using @DexRemove that remove your empty/old API package(s).

(see: https://puredanger.github.io/tech.puredanger.com/2007/02/28/package-annotations/)

3d) the 'patch' subproject can also replace resources from your empty/old API (which are public and client can use) and add new resources (which are private of your implementation).

3e) you can build the 'patch' as a separate project and import it as an android library instead of a subproject. then you can use the same compiled 'patch' for all APKs you want to patch.

3f) in the 'app' project you need to customize build.gradle and the manifest for each client APK (which you can automate).

3g) ./gradlew assembleRelease :)

NOTE: you must define the dexpatcher.dir=<support-tool-dir> property in file 'local.properties'. see the dexpatcher docs.

@yanglee0801
Copy link
Author

@Lanchon
thank you for your tool
i will try it with your DexPatcher , if i have other questions, can i ask you for help?

@yanglee0801
Copy link
Author

@Lanchon
i build your project but it's wrong

Could not find com.github.lanchon.dexpatcher:dexpatcher-gradle:2.0.0-alpha4.
Searched in the following locations:
  - https://dl.google.com/dl/android/maven2/com/github/lanchon/dexpatcher/dexpatcher-gradle/2.0.0-alpha4/dexpatcher-gradle-2.0.0-alpha4.pom
  - https://dl.google.com/dl/android/maven2/com/github/lanchon/dexpatcher/dexpatcher-gradle/2.0.0-alpha4/dexpatcher-gradle-2.0.0-alpha4.jar
  - https://jcenter.bintray.com/com/github/lanchon/dexpatcher/dexpatcher-gradle/2.0.0-alpha4/dexpatcher-gradle-2.0.0-alpha4.pom
  - https://jcenter.bintray.com/com/github/lanchon/dexpatcher/dexpatcher-gradle/2.0.0-alpha4/dexpatcher-gradle-2.0.0-alpha4.jar
  - https://plugins.gradle.org/m2/com/github/lanchon/dexpatcher/dexpatcher-gradle/2.0.0-alpha4/dexpatcher-gradle-2.0.0-alpha4.pom
  - https://plugins.gradle.org/m2/com/github/lanchon/dexpatcher/dexpatcher-gradle/2.0.0-alpha4/dexpatcher-gradle-2.0.0-alpha4.jar
  - file:/Users/lion/workSpace/lion_space/dexpatcher-gradle/build/libs/dexpatcher-gradle-2.0.0-alpha4.jar
  - file:/Users/lion/workSpace/lion_space/dexpatcher-gradle/build/libs/dexpatcher-gradle.jar
Required by:
    project :multi-dex

i try to open https://jcenter.bintray.com/com/github/lanchon/dexpatcher/dexpatcher-gradle/2.0.0-alpha4/dexpatcher-gradle-2.0.0-alpha4.pom

it's prompt:
404. That’s an error.

That’s all we know.

@Lanchon
Copy link

Lanchon commented Apr 27, 2019

https://github.com/DexPatcher/dexpatcher-gradle/releases

i didn't have time to do the alpha4 release. you can use alpha3 (revert the alpha3 to alpha4 commit in your downloaded sample) or wait a few minutes and i'll make it.

@Lanchon
Copy link

Lanchon commented Apr 27, 2019

@Lanchon
Copy link

Lanchon commented Apr 27, 2019

if i have other questions, can i ask you for help?

definitely, but you must read the docs first! open a ticket in dxp-gradle or dxp-tool (depends on your ticket) if you need help. this issue is for apktool.

@Lanchon
Copy link

Lanchon commented Apr 27, 2019

keep in mind that with this workflow (you replace your API implementation in client's code) the client CANNOT proguard the use of your API. all your client's use of your API will be non-obfuscated. making both codebases easier to reverse. (the empty API lib you give to clients should have proguard rules to keep your own API intact.)

@iBotPeaches
Copy link
Owner

Apktool does not have support for just blindly changing packageId throughout app. I think it would be possible if you leverage some custom aapt/aapt2 params, but none of this is supported out of box functionality. If you decoded an application with pkgId 0x08 - it should work though.

Keeping open for now because reading 24 comments and processing what actually is being reported is tough.

@iBotPeaches
Copy link
Owner

Read this thread. Apktool has a long running feature/roadmap for remapping IDs, but alternative tools are launching to help with this as shown above. Closing as we already have it in the roadmap.

https://github.com/iBotPeaches/Apktool/blob/master/ROADMAP.md#automatic-remapping-of-resourceid, but going to also link to this ticket for the discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants