During a recent engagement I came across an Android application which, after extracting and decompiling the Java code (using dex2-jar and jd-gui) I noticed the logic was calling a native function, by reviewing the code a little more I figured out the native function was defined in a DLL file located in an assemblies folder. The folder also included a bunch of Xamarin, Microsoft and Mono DLL binaries, which is what you would expect to find in Xamarin applications.
Xamarin “is an open-source platform for building modern and performant applications for iOS, Android, and Windows with .NET” or at least that’s what Microsoft says. It basically is a framework that allows code developed in .Net to run in the most popular platforms out there.
Since reviewing and understanding the code of the application is a most in these kind of engagements, the next step was to reverse engineer those DLL files, for this you would think a tool like ILSpy would easily take care of the task, right?
The problem
Here is where things start to get interesting, we can use ILSpy after installing the extension in Visual Studio Code, below is the result I got when trying to decompile one of the DLLs (as example we will use Mono.Android.dll):
By doing some digging we can see this comment on a pull request within the Xamarin github repository where compression of assemblies was changed to LZ4 for efficiency reasons. By hexdumping the DLL with the following command:
hexdump -C Mono.Android.dll
We confirm the presence of LZ4 compression via the XALZ header:
This means that the LZ4 compressed DLL looks something like this:
The solution
That means we will need to extract and unpack the payload length to find out the length of the payload and then LZ4 decompress the payload to obtain a file that can be decompiled (via ILSpy for instance). For this we can use the lz4.block python library and do something like the below:
lz4.block.decompress(payload, uncompressed_size=length)
You can find the full script in the below github link:
https://github.com/securitygrind/lz4_decompress/blob/main/lz4_decompress.py
After running the script with the below command:
./lz4_decompress.py Mono.Android.dll
We take the resulting DLL (Mono.Android_out.dll) and try again with ILSpy, we can now see that the assembly is decompiled and we can inspect the contents of the DLL:
can you show some iOS pentest
Hey,
Thanks for your comment, at this point I don’t have the required setup for iOS pentesting.
Regards,
Cristian
How can I view the contents of xml files (resource files)? There seems also to be a compression but not with lz4? Many thanks
Hi John,
Not sure I follow, I think you can still run the apk through apktool in order to get access to the resource files (as well as the AndroidManifest.xml). The process described above is applicable only to DLL files.
Regards,
Cristian
hi
can you please explain how to install lz4 with pip?
i installed it but is still get error while executing the script:
error importing lz4.block
Hi Alex,
Think I installed it the regular way: pip install lz4, but not sure why the error importing it though.
Regards,
Cristian
Hi, Thanks for your well written article.
I have an APK with the new assembly blob, I can extract it using decompress-assemblies command line tool in xamarin-android, but when I try to create an apk with the decompressed DLLs back, I get this exception:
06-20 16:28:37.720 17292 17292 F DEBUG : Abort message: ‘../../../jni/embedded-assemblies.hh:155 (ensure_valid_assembly_stores): Invalid or incomplete assembly store data’
I have went to the file, and found it returns when application_config.have_assembly_store is 0
Do you have any idea how to change the application_config for the APK? I think it’s inside libxamarin-app.so.
Or would it be easier to recompress the assemblies and generate assemblies.blob file, but unfortunately I didn’t find a tool to do that…
Hi,
Thanks for reaching out, I’m only partly familiar with what you are describing here, still I would thing that the best approach would be to re-compress de assemblies.
In this post there is a script that decompresses DLLs so that they can be reversed engineered (with ILSpy for instance), I would think you can use the same python library to re-compress the required DLLs, but you’ll also have to resign the apk after it has been rebuilt.
Regards,
Cristian
Scurvier did you found a solution? I found one on stackoverflow…
You have to run a class file in visual studio, with this class file you can convert back the dll to the lz4 compression.
But I don’t know much about programming and I can not get it to work.
Maybe you can? Or someone here? Step 4 is it where I fail.
Thank in advance!
Link to the solution:
https://stackoverflow.com/questions/72689284/compress-xamarin-android-apk-assemblies
I need a way to do this as well. I need to compress it back to lz4 and then blob. I can’t find a way to do it.
Hi, have you ever come across a Xamarin app with no assemblies directory and no .dll files at all?
May I how to decrypt the xaba header dll files in xamarin app and I see one case like from asset folder I see many dll.so files and how to decrypt those cases, Please help me out with the solution