An Android APK written in C# — unpacked from assemblies.blob and decompiled back to C#.
The APK is checked for an AssemblyStore, for loose assemblies/*.dll, and for the libmonodroid.so runtime that marks a .NET Android app.
The store is parsed, each entry's LZ4 XALZ compression is undone, and the individual .NET assemblies are written out as real DLL files.
Every application assembly becomes a browsable C# project, next to the usual Java, resources and smali output for the Android wrapper.
Open a Xamarin or .NET MAUI app in an ordinary APK decompiler and the result is disappointing: a couple of generated activity classes, a MonoPackageManager, some binding stubs, and nothing that resembles the app. That is not a decompilation failure. A Xamarin app is written in C#, and its Dalvik bytecode exists only to load the .NET runtime and hand control to managed code.
The actual program is stored somewhere a Java decompiler never looks. Older builds put individual .dll files in the APK's assemblies/ folder. Everything since then merges them into a single AssemblyStore — one binary container holding every assembly the app ships, each one usually LZ4-compressed. Neither layout is DEX, so JADX and its peers walk straight past it.
xamarin/assemblies/ — every .NET assembly recovered from the APK, decompressed and written as a normal DLL you can download and open in any .NET tool.xamarin/sources/ — one browsable C# project per application assembly: classes, methods, XAML-generated code, constants and resource identifiers.xamarin/README.txt — which store format was found, which architectures were present, how many assemblies were unpacked and which were decompiled.sources/, resources/, smali/ — the normal Android output for the Java wrapper, manifest and resources, kept intact beside the C#.Xamarin has changed how it packages managed code several times, and uploads span all of it:
assemblies/*.dll, as shipped by classic Xamarin.Android and Xamarin.Forms. Plain PE files in the oldest builds, XALZ-compressed in later ones.assemblies/assemblies.blob with a sibling assemblies.manifest naming the entries, plus per-architecture blobs such as assemblies.arm64_v8a.blob. Used through .NET 8 MAUI.lib/<abi>/libassemblies.<abi>.blob.so or lib/<abi>/libassembly-store.so. From .NET 9 the store is wrapped in a stub shared library so Android's installer keeps it uncompressed; the assembly names are embedded in the store itself, so there is no manifest any more.All of them are detected from the APK's contents rather than from file names, and the store is unpacked in-process — no Python helper, no external unpacker.
If you have already pulled a .dll out of a Xamarin APK by hand, you can upload it on its own. Those files usually still start with the four bytes XALZ rather than MZ, and most .NET decompilers reject them with a message about missing managed metadata. Here the compression header is recognised and undone first, so the assembly decompiles normally.
Xamarin and .NET MAUI are heavily used for enterprise, banking and line-of-business Android apps, which makes these APKs a common subject of security review. Recovering the C# is the difference between reading generated glue code and reading the app's actual authentication, storage and network logic.
System.*, Microsoft.*, Mono.* and Xamarin.* are stock, public and enormous. They stay in assemblies/ so references resolve, and any one of them can be uploaded separately.libaot-*.so machine code; the managed assemblies are still recovered, but the AOT images are not C#.It contains lib/<abi>/libmonodroid.so, and either an assemblies/ folder or a libassemblies.*.blob.so under lib/. You do not have to check — just upload the APK and the C# folder appears if it is one.
Yes. The Android wrapper is decompiled exactly as any other APK; the C# is added in a separate xamarin/ folder beside it.
No. The output is for reading and analysis. It reconstructs source from compiled assemblies, without the project files, assets pipeline or signing material of the original solution.
The C# assemblies are recovered the same way. Razor components compiled into those assemblies appear as their generated C# classes.
No. The APK is read as an archive and the assemblies are parsed as data in a time-limited worker. Nothing from the upload is executed.