Open frogworth opened 2 years ago
Hi, I'm one of the developers of TotalFinder.
So, I just tested this — the issue actually has nothing to do with TotalFinder (as I get the injection error even with TotalFinder disabled and/or fully removed), but rather the fact that Odourless in its current state doesn't actually work correctly on Apple Silicon.
Basically, Finder (and all other Apple platform binaries) are arm64e
, but all of Odourless's arm64e
executable binaries (except maybe the dylib) are broken and get SIGKILL'd instantly, resulting in them failing to launch at all.
Now, if you were to download the arm64
version of Odourless instead, this on the other hand does launch, but it fails to inject into Finder due to an architecture mismatch between Finder (arm64e
) and libodourless-inject.dylib
(arm64
), hence the "Incompatible Mach-O image" message.
Simply transplanting the arm64e
dylib into the arm64
app bundle also does not work.
I'm unfamiliar with how your code injection solution works, @xiaozhuai, but I would generaly recommend this:
arm64
libodourless-inject.dylib
as arm64e
, because this gets injected into Finder (which is always an arm64e
process on Apple Silicon)Also, is there a reason why you are not building as a fat ("Universal") Mach-O binary? I think it'd be less confusing for users if you did so.
@akemin-dayo Thanks for your suggestion! I will try it.
@frogworth Try this universal version Odourless-universal-1.2.0.zip
I'm not frogworth, but this binary has the same Killed: 9
issue.
Try not including an arm64e
slice for odourless
and odourless-daemon
.
@akemin-dayo Thanks for your feedback! Please try this new version.
$ file Odourless.app/Contents/MacOS/odourless
Odourless.app/Contents/MacOS/odourless: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64Mach-O 64-bit executable x86_64] [arm64]
Odourless.app/Contents/MacOS/odourless (for architecture x86_64): Mach-O 64-bit executable x86_64
Odourless.app/Contents/MacOS/odourless (for architecture arm64): Mach-O 64-bit executable arm64
$ file Odourless.app/Contents/Resources/bin/odourless-daemon
Odourless.app/Contents/Resources/bin/odourless-daemon: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64Mach-O 64-bit executable x86_64] [arm64]
Odourless.app/Contents/Resources/bin/odourless-daemon (for architecture x86_64): Mach-O 64-bit executable x86_64
Odourless.app/Contents/Resources/bin/odourless-daemon (for architecture arm64): Mach-O 64-bit executable arm64
$ file Odourless.app/Contents/Resources/lib/libodourless-inject.dylib
Odourless.app/Contents/Resources/lib/libodourless-inject.dylib: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit dynamically linked shared library x86_64Mach-O 64-bit dynamically linked shared library x86_64] [arm64e]
Odourless.app/Contents/Resources/lib/libodourless-inject.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
Odourless.app/Contents/Resources/lib/libodourless-inject.dylib (for architecture arm64e): Mach-O 64-bit dynamically linked shared library arm64e
@xiaozhuai This build launches fine, but dylib injection fails with this error:
I: finder pid: 63007
E: inject failed, Malformed dependency ordinal
Seems like it's being thrown by frida-gum's gum_darwin_mapper_get_dependency_by_ordinal()
function here: https://github.com/frida/frida-gum/blob/66faa2032c2d6b9f80aa382fa8ff44ff28a8822f/gum/backend-darwin/gumdarwinmapper.c#L1709
switch (ordinal)
{
case GUM_DARWIN_BIND_SELF:
result = gum_darwin_mapper_get_dependency_by_name (self,
self->module->name, error);
break;
case GUM_DARWIN_BIND_MAIN_EXECUTABLE:
case GUM_DARWIN_BIND_FLAT_LOOKUP:
case GUM_DARWIN_BIND_WEAK_LOOKUP:
goto invalid_ordinal;
default:
{
gint i = ordinal - 1;
if (i >= 0 && i < self->dependencies->len)
result = g_ptr_array_index (self->dependencies, i);
else
goto invalid_ordinal;
break;
}
}
Seems like I can't build a flat dynamic lib for injection.
I read it wrong, it's flat not fat...
Anyway, I will split libodourless-inject.dylib into 2 arch.
That's a really strange failure mode — iOS tweak dylibs are pretty much always fat binaries, and those have no issue being injected (even if it's just a simple DYLD_INSERT_LIBRARIES
)… TotalFinder is also shipped as a fat binary (though the injection method is very different compared to Odourless).
I suppose this may be some sort of deficiency with Frida specifically…? (I have no experience with Frida, so I can't really be certain.)
@akemin-dayo Thank you very much for your help. I'll go deep for this problem. Maybe switch to another injection library. What injection library do you suggest?
@akemin-dayo Sorry to bother you again. I don't have a arm64 macos. Please try this one. Odourless-universal-1.2.0.zip
Hi @xiaozhuai, I did try that one but it also won't launch at all unfortunately.
Hi xiaozhuai, I'm not sure if you know, but a brilliant person has managed to make TotalFinder compatible with Apple Silicon. https://discuss.binaryage.com/t/update-discussion-totalfinder-1-14-1-now-with-apple-silicon-support/8364
Unfortunately, Odourless and TotalFinder do not play nice together. If TotalFinder is running, the Odourless daemon says: E: inject failed, Incompatible Mach-O image
Hoping there's a way to have both tools working at once!