A Zygisk Module to dump il2cpp/unity games based on MetadataRegistration & CodeRegistration offsets.
Warning
This module breaks SELinux policy of untrusted_app by allowing write on unix_stream_socket class to zygote.
This beceause it's used to transact vectors of dump from game to an external folder in /data/adb/il2dump/*/dump.cs.
- Flash this module and reboot.
- Create directory named as the package name of the targeted game in
/data/adb/il2dump/. - Create & fill a
preset.propfile in the directory. - Run the game and observe logs using command
logcat | grep 'Il2Dump'for any errors.
Yourdump.cswill be generated under the directory.
Ifdump.csalready exists, the module will automatically ignore future dumps & close itself until deleted.
All configuration files & folders will take effect immediately.
format:
library=libil2cpp.so #s_GlobalMetadata=ABCD0D0 #s_GlobalMetadataHeader=ABCD0D0 s_Il2CppCodeRegistration=ABCD0B0 s_Il2CppMetadataRegistration=ABCD0B8To identify required offsets for working with libil2cpp or libunity, you can inspect the official Unity source implementation, precisely at MetadataCache.cpp, you can look for useful patterns or strings to identify these structures in the binary using reverse engineering tools like IDA, Ghidra, ...
void MetadataCache::Register(const Il2CppCodeRegistration* const codeRegistration, const Il2CppMetadataRegistration* const metadataRegistration, const Il2CppCodeGenOptions* const codeGenOptions) { s_Il2CppCodeRegistration = codeRegistration; /* Il2CppCodeRegistration */ s_Il2CppMetadataRegistration = metadataRegistration; /* Il2CppMetadataRegistration */ s_Il2CppCodeGenOptions = codeGenOptions; for (int32_t j = 0; j < metadataRegistration->genericClassesCount; j++) if (metadataRegistration->genericClasses[j]->typeDefinitionIndex != kTypeIndexInvalid) metadata::GenericMetadata::RegisterGenericClass(metadataRegistration->genericClasses[j]); for (int32_t i = 0; i < metadataRegistration->genericInstsCount; i++) s_GenericInstSet.insert(metadataRegistration->genericInsts[i]); s_InteropData.assign_external(codeRegistration->interopData, codeRegistration->interopDataCount); } static void* s_GlobalMetadata; static const Il2CppGlobalMetadataHeader* s_GlobalMetadataHeader; void MetadataCache::Initialize() { s_GlobalMetadata = vm::MetadataLoader::LoadMetadataFile("global-metadata.dat"); /* GlobalMetadata */ s_GlobalMetadataHeader = (const Il2CppGlobalMetadataHeader*)s_GlobalMetadata; /* GlobalMetadataHeader */ /* ... */ }Tip
s_GlobalMetadata can be obtained automatically by Il2Dump (if not inputted manually), whereas s_GlobalMetadataHeader is set to default (as s_GlobalMetadata) when not specified.
- Zygisk Il2CppDumper
- Arcy