From fw at deneb.enyo.de Sat Aug 16 21:07:51 2014 From: fw at deneb.enyo.de (Florian Weimer) Date: Sat, 16 Aug 2014 23:07:51 +0200 Subject: Fingerprinting .jnilib files Message-ID: <87iols2leg.fsf@mid.deneb.enyo.de> Maybe this is a bit off-topic here, but I'm not sure where else I could ask. Apprently, for Darwin, there are tons of JNI libraries out there which are probably Mach-O files in disguise, but start with the 0xCAFEBABE magic number. Not surprisingly, various class file parser choke on them. Is there are a way, based on the file header, to tell these .jnilib files from genuine Java class files? From landonf at plausible.coop Tue Aug 19 03:24:19 2014 From: landonf at plausible.coop (Landon J Fuller) Date: Mon, 18 Aug 2014 21:24:19 -0600 Subject: Fingerprinting .jnilib files In-Reply-To: <87iols2leg.fsf@mid.deneb.enyo.de> References: <87iols2leg.fsf@mid.deneb.enyo.de> Message-ID: <85A1D512-6C23-4C2E-9258-23EFC84E3511@plausible.coop> On Aug 16, 2014, at 3:07 PM, Florian Weimer wrote: > Maybe this is a bit off-topic here, but I'm not sure where else I > could ask. > > Apprently, for Darwin, there are tons of JNI libraries out there which > are probably Mach-O files in disguise, but start with the 0xCAFEBABE > magic number. Not surprisingly, various class file parser choke on > them. Is there are a way, based on the file header, to tell these > .jnilib files from genuine Java class files? Mach-O's fat_header just happens to use same magic number :-) A very simple heuristic would be to check the nfat_arch value: struct fat_header { uint32_t magic; uint32_t nfat_arch; // big endian }; vs: struct class_file { uint32_t magic; uint16_t minor_version; uint16_t major_version; } The *smallest* possible class file version is 46.0 (Java 1.2), which, if interpreted as a big endian uint32_t nfat_arch, would simply be `46'. The *earliest* possible class file version is 45.3 (Java 1.1) -- nfat_arch would be 196653. So: - If you see a binary with an nfat_arch value of < 46, it's a Mach-O binary, not a class file. - If you see a binary with an nfat_arch of >= 46, you either found the most portable Mach-O executable ever produced, or it's a Java class file. If you want a more certain answer, just parse the fat_arch and Mach-O headers; it's a pretty sure bet that, given a Java class file, you won't see the correct Mach-O header magic numbers, and that many of the fat sections will extend beyond the actual length of the file. -landonf -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 455 bytes Desc: Message signed with OpenPGP using GPGMail URL: