xiaozhuai / odourless

Free Palestine🇵🇸🇵🇸🇵🇸Odourless is a tool for preventing .DS_Store creation.
MIT License
103 stars 10 forks source link

Incompatible with TotalFinder 1.14.1 #11

Open frogworth opened 2 years ago

frogworth commented 2 years ago

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!

akemin-dayo commented 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:

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.

xiaozhuai commented 2 years ago

@akemin-dayo Thanks for your suggestion! I will try it.

xiaozhuai commented 2 years ago

@frogworth Try this universal version Odourless-universal-1.2.0.zip

akemin-dayo commented 2 years ago

I'm not frogworth, but this binary has the same Killed: 9 issue.

Try not including an arm64e slice for odourless and odourless-daemon.

xiaozhuai commented 2 years ago

@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

Odourless-universal-1.2.0.zip

akemin-dayo commented 2 years ago

@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

xiaozhuai commented 2 years ago
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.

akemin-dayo commented 2 years ago

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.)

xiaozhuai commented 2 years ago

@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?

xiaozhuai commented 2 years ago

@akemin-dayo Sorry to bother you again. I don't have a arm64 macos. Please try this one. Odourless-universal-1.2.0.zip

frogworth commented 2 years ago

Hi @xiaozhuai, I did try that one but it also won't launch at all unfortunately.