in net/JetBrains.FormatRipper/src/MachO/MachOFile.cs [98:156]
public static unsafe bool Is(Stream stream)
{
static bool Check(MH magic) => magic is MH.MH_MAGIC or MH.MH_MAGIC_64 or MH.MH_CIGAM or MH.MH_CIGAM_64;
stream.Position = 0;
uint rawMagic;
StreamUtil.ReadBytes(stream, (byte*)&rawMagic, sizeof(uint));
var magic = (MH)MemoryUtil.GetLeU4(rawMagic);
if (magic is MH.FAT_MAGIC or MH.FAT_MAGIC_64 or MH.FAT_CIGAM or MH.FAT_CIGAM_64)
{
var isFatLittleEndian = magic is MH.FAT_MAGIC or MH.FAT_MAGIC_64;
var needSwap = BitConverter.IsLittleEndian != isFatLittleEndian;
uint GetU4(uint v) => needSwap ? MemoryUtil.SwapU4(v) : v;
ulong GetU8(ulong v) => needSwap ? MemoryUtil.SwapU8(v) : v;
fat_header fh;
StreamUtil.ReadBytes(stream, (byte*)&fh, sizeof(fat_header));
var nFatArch = GetU4(fh.nfat_arch);
if (magic is MH.FAT_CIGAM_64 or MH.FAT_MAGIC_64)
{
var fatNodes = new fat_arch_64[checked((int)nFatArch)];
fixed (fat_arch_64* ptr = fatNodes)
StreamUtil.ReadBytes(stream, (byte*)ptr, checked((int)nFatArch * sizeof(fat_arch_64)));
for (var n = 0; n < nFatArch; n++)
{
stream.Position = checked((long)GetU8(fatNodes[n].offset));
uint rawSubMagic;
StreamUtil.ReadBytes(stream, (byte*)&rawSubMagic, sizeof(uint));
var subMagic = (MH)MemoryUtil.GetLeU4(rawSubMagic);
if (!Check(subMagic))
return false;
}
}
else
{
var fatNodes = new fat_arch[checked((int)nFatArch)];
fixed (fat_arch* ptr = fatNodes)
StreamUtil.ReadBytes(stream, (byte*)ptr, checked((int)nFatArch * sizeof(fat_arch)));
for (var n = 0; n < nFatArch; n++)
{
stream.Position = GetU4(fatNodes[n].offset);
uint rawSubMagic;
StreamUtil.ReadBytes(stream, (byte*)&rawSubMagic, sizeof(uint));
var subMagic = (MH)MemoryUtil.GetLeU4(rawSubMagic);
if (!Check(subMagic))
return false;
}
}
return true;
}
return Check(magic);
}