Skip to content

Xamarin Android: What does "Bundle assemblies into native code" really mean? #4527

New issue

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

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

Already on GitHub? # to your account

Closed
alienwareone opened this issue Apr 6, 2020 · 24 comments
Assignees

Comments

@alienwareone
Copy link

When this option is enabled, assemblies are bundled into a native shared library. This option keeps the code safe; it protects managed assemblies by embedding them in native binaries.

Note that the Bundle into Native Code option does not mean that the assemblies are compiled into native code. It is not possible to use AOT Compilation to compile assemblies into native code.

https://docs.microsoft.com/en-us/xamarin/android/deploy-test/release-prep/?tabs=windows#protect_app

I searched a lot about this topic but there seems a lot of confusion about what this option really does.

I tried to unpack the "libmonodroid_bundle_app.so" file with this project but it didn't work. https://github.com/AigioL/unpack.libmonodroid_bundle_app.so

I'm looking for basic obfuscation (renamed classes, methods, etc.) for my app.
It seems to me that this option compiles your assemblys to IL code, so your code could possibly be read.

So what can you see if you unpack the "libmonodroid_bundle_app.so" file (codewise)?

@dellis1972
Copy link
Contributor

Personally if you want obfuscation I would not use bundle assemblies. As you mentioned all it does really is embed the IL into a native assembly. Also this feature is likely to be removed in the future.

I'm not sure if this still works but it might help https://devblogs.microsoft.com/xamarin/protecting-xamarin-apps-dotfuscator/.

@alienwareone
Copy link
Author

Thanks for your answer @dellis1972

Unfortunately since I upgraded my project to AndroidX obfuscation doesn't work anymore, so I was looking for an alternative.

See:
#2120

Symbols were found but are not matching the assembly
   bei Mono.Cecil.ModuleDefinition.ReadSymbols(ISymbolReader reader, Boolean throwIfSymbolsAreNotMaching)
   bei Mono.Cecil.ModuleReader.ReadSymbols(ModuleDefinition module, ReaderParameters parameters)
   bei Mono.Cecil.ModuleReader.CreateModule(Image image, ReaderParameters parameters)
   bei Mono.Cecil.ModuleDefinition.ReadModule(String fileName, ReaderParameters parameters)
   bei Xamarin.AndroidX.Migration.CecilMigrator.Migrate(String source, String destination)
   bei Xamarin.AndroidX.Migration.CecilMigrator.Migrate(IEnumerable`1 assemblies)
   bei Xamarin.AndroidX.Migration.BuildTasks.CecilfyFiles.Execute()

@simon10says
Copy link

I'm also getting very confused about this, especially since XF4.5, several serious, showstopper, regression bugs (like xamarin/Xamarin.Forms#9900 and dotnet/android-libraries#64) has surfaced and Xamarin members have since strongly demote the use of BundleAssemblies

My decision to use BundleAssemblies was based on this, to:

  1. Provide at least some protection by embedding managed assemblies into native binaries
  2. Strip away the assemblies folders in my apk which the dlls could be so easily peek using dotPeek in plain text code
  3. Decrease the size of my apk (and yes, I know I can use app bundle)

So ... now ... with Xamarin members questioning us why use BundleAssemblies and demoting the use, and reading back the doc as stated above, what is the guideline now? Without BundleAssemblies, how does the code get the protection with BundleAssemblies (I know it's not 100% foolproof, but at least there is a layer of protection)? Is there anything else about BundleAssemblies which led Xamarin members surprise why we are using it?

Would really appreciate some detail rather than suggesting that it might be removed in .Net 5 which is some time away

@nhdanh
Copy link

nhdanh commented Apr 9, 2020

I'm also getting very confused about this, especially since XF4.5, several serious, showstopper, regression bugs (like xamarin/Xamarin.Forms#9900 and xamarin/AndroidX#64) has surfaced and Xamarin members have since strongly demote the use of BundleAssemblies

My decision to use BundleAssemblies was based on this, to:

  1. Provide at least some protection by embedding managed assemblies into native binaries
  2. Strip away the assemblies folders in my apk which the dlls could be so easily peek using dotPeek in plain text code
  3. Decrease the size of my apk (and yes, I know I can use app bundle)

So ... now ... with Xamarin members questioning us why use BundleAssemblies and demoting the use, and reading back the doc as stated above, what is the guideline now? Without BundleAssemblies, how does the code get the protection with BundleAssemblies (I know it's not 100% foolproof, but at least there is a layer of protection)? Is there anything else about BundleAssemblies which led Xamarin members surprise why we are using it?

Would really appreciate some detail rather than suggesting that it might be removed in .Net 5 which is some time away

Good, I agree with you

@pulmuone
Copy link

I'm also getting very confused about this, especially since XF4.5, several serious, showstopper, regression bugs (like xamarin/Xamarin.Forms#9900 and xamarin/AndroidX#64) has surfaced and Xamarin members have since strongly demote the use of BundleAssemblies

My decision to use BundleAssemblies was based on this, to:

  1. Provide at least some protection by embedding managed assemblies into native binaries
  2. Strip away the assemblies folders in my apk which the dlls could be so easily peek using dotPeek in plain text code
  3. Decrease the size of my apk (and yes, I know I can use app bundle)

So ... now ... with Xamarin members questioning us why use BundleAssemblies and demoting the use, and reading back the doc as stated above, what is the guideline now? Without BundleAssemblies, how does the code get the protection with BundleAssemblies (I know it's not 100% foolproof, but at least there is a layer of protection)? Is there anything else about BundleAssemblies which led Xamarin members surprise why we are using it?

Would really appreciate some detail rather than suggesting that it might be removed in .Net 5 which is some time away

Good, I agree with you.

@nhdanh
Copy link

nhdanh commented May 1, 2020

any new when XF 4.6 was release. I still get error on XF 4.6

@jonpryor
Copy link
Member

What does "Bundle assemblies into native code" really mean?

It means "take all of the assemblies, and instead of leaving them uncompressed as assemblies/*.dll within the .apk, gzip compress them into a libmonodroid_bundle_app.so file, using mkbundle to generate the code.

So what can you see if you unpack the "libmonodroid_bundle_app.so" file (codewise)?

All of the assemblies/*.dll files that are required for the app to run.

The assemblies themselves are unchanged (aside from linking/etc.).

This is "some" protection, to be fair, but it's not much.

@jonpryor
Copy link
Member

I have updated the Bundle Assemblies into Native Code documentation, which now reads:

This allows assemblies to be compressed, permitting smaller .apk files. Assembly compression also confers a minimal form of obfuscation; such obfuscation should not be relied upon.

@jonpryor
Copy link
Member

Commit d236af5 provides a different take on "minimal levels of obfuscation": it does not obfuscate, but it does:

  1. Compress assemblies, and
  2. Prefix compressed assemblies with a non-IL header.

As such, tools like ildasm won't be able to read them as-is. It is an "obscuration."

It is not a security solution. It's a way to get smaller .apk files without the startup overheads involved in $(BundleAssemblies)=True, while also avoiding the Xamarin.AndroidX.AppCompat.Resources.dll issue in dotnet/android-libraries#64.

@EDMIStephen
Copy link

Commit d236af5 provides a different take on "minimal levels of obfuscation": it does not obfuscate, but it does:

  1. Compress assemblies, and
  2. Prefix compressed assemblies with a non-IL header.

As such, tools like ildasm won't be able to read them as-is. It is an "obscuration."

It is not a security solution. It's a way to get smaller .apk files without the startup overheads involved in $(BundleAssemblies)=True, while also avoiding the Xamarin.AndroidX.AppCompat.Resources.dll issue in xamarin/AndroidX#64.

Someone might want to get in touch with the VS team to update their gui.
image

@simon10says
Copy link

Hi @jonpryor , I don't have much knowledge on this aspect and hope you could shine some light. When you said:

So what can you see if you unpack the "libmonodroid_bundle_app.so" file (codewise)?

All of the assemblies/*.dll files that are required for the app to run.

Do you mean I could simply unzip libmonodroid_bundle_app.so and I could retrieve all the assemblies/*.dll?

I tried it and all I see is:
image

I tried opening up most of the files inside and they are all in binary. And from my shallow knowledge on this, my understanding is that you could go a step further to reverse-engineer to machine code. So, how to unpack libmonodroid_bundle_app.so to get to the assemblies/*.dll files?

@EDMIStephen
Copy link

Hi @jonpryor , I don't have much knowledge on this aspect and hope you could shine some light. When you said:

So what can you see if you unpack the "libmonodroid_bundle_app.so" file (codewise)?

All of the assemblies/*.dll files that are required for the app to run.

Do you mean I could simply unzip libmonodroid_bundle_app.so and I could retrieve all the assemblies/*.dll?

I tried it and all I see is:
image

I tried opening up most of the files inside and they are all in binary. And from my shallow knowledge on this, my understanding is that you could go a step further to reverse-engineer to machine code. So, how to unpack libmonodroid_bundle_app.so to get to the assemblies/*.dll files?

https://github.com/tjg1/mono_unbundle

@EmilAlipiev
Copy link

you can see this SO post. App Bundles does same thing as Bundle into native assemblies.

https://stackoverflow.com/questions/62293367/xamarin-android-app-bundle-with-bundle-into-native-assemblies-increases-size-b

@simon10says
Copy link

@EDMIStephen , thanks for the link. I'll need more time to test it out; but a quick look at it, it seems easy to reverse-engineer libmonodroid_bundle_app.so to get the dlls.

My initial understanding of this is all wrong; I thought BundleAssemblies will compile the code into native code.

I've re-read this Xamarin Doc. Some sections in the doc has changed even the date at the very top still is at 2018. There is this line that says:

Note that the Bundle into Native Code option does not mean that the assemblies are compiled into native code. It is not possible to use AOT Compilation to compile assemblies into native code.

So, there is never a way in Xamarin to compile and pack apk in native code. Also to take note is that r8 or ProGuard does not do any obfuscation (in Xamarin).

So ... it seems like the only way to protect Xamarin app is with obfuscation. And now I understand why Xamarin members have been diminishing the usefulness of <BundleAssemblies>. But still ... with <BundleAssemblies>, I can eliminate those novice hacker.

Finally, any best practices to follow to make it harder against reverse-engineering (just in the area of Xamarin)? Is there an option to compile into native code instead of generating the dlls?

@simon10says
Copy link

@EmilAlipiev , thanks for the link to the SO post. I'll bring my further discussion in the SO post

@tranb3r
Copy link

tranb3r commented Jun 17, 2020

@simon10says
Yes, in xamarin, you can compile the .net code into native code, it's what AOT does.
However, the apk will always contain the original dlls (I believe this is needed for reflection), either in the assembly folder or bundled into a .so lib (which is smaller in size than the assembly folder, and is in a way some very basic obfuscation since you'll need a tool to unbundle it).
r8 or proguard does not modify .net code, but it does actually obfuscate the java code in xamarin apps.
For more obfuscation of .net code, you can use any .net obfuscation tool (dotfuscator, babel obfuscator...).

@nexxuno
Copy link

nexxuno commented Jun 17, 2020

Let me add an important detail: if you use hybrid AOT the code is stripped away from the .Net assemblies leaving only method stubs neede for relfection, thus achieving very good obfuscation.

@tranb3r
Copy link

tranb3r commented Jun 17, 2020

Let me add an important detail: if you use hybrid AOT the code is stripped away from the .Net assemblies leaving only method stubs neede for relfection, thus achieving very good obfuscation.

@nexxuno I didn't know that. Thanks for the tip, I'll definitely look into it :)

@simon10says
Copy link

@tranb3r , yes ... that's my understanding too. What I meant was finding a mean to compile into native code and does away the dlls that could be so easily reverse-engineered.

@nexxuno , it seems like using hybrid AOT does not stripped away code from the assemblies. I came upon this fresh post. I've also verified it with the following configuration and it does not strip away the code from the assemblies:

<AotAssemblies>true</AotAssemblies>
<AndroidAotMode>hybrid</AndroidAotMode>
<BundleAssemblies>false</BundleAssemblies>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
<AndroidLinkMode>Full</AndroidLinkMode>
<AndroidLinkTool>r8</AndroidLinkTool>
<AndroidDexTool>d8</AndroidDexTool>

This is my test project - App2.zip

@nexxuno
Copy link

nexxuno commented Jun 17, 2020

At the moment I can't test if it stopped working, like stated in your link. What I remember is that I used hybrid aot plus llvm and it was working.

@simon10says
Copy link

#4818 (comment)

pfff ... this is getting so tiring and frustrating to get it right

@EDMIStephen
Copy link

#4818 (comment)

pfff ... this is getting so tiring and frustrating to get it right

Yeah. I am having no luck with Hybrid AOT. It doesn't seem to be doing what it says it should.

@EDMIStephen
Copy link

g, like stated in your link. What I remember is that I used hybrid aot plus llvm and it was working.

Are you able to post which version of VS etc you are using. I am on the latest of everything and tried preview too and it isn't working.

In the other bug you mentioned it was not working for you.
#4115 (comment)

@nexxuno
Copy link

nexxuno commented Jun 17, 2020 via email

@ghost ghost locked as resolved and limited conversation to collaborators Jun 4, 2022
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
None yet
Projects
None yet
Development

No branches or pull requests