briankendall / forceFullDesktopBar

Utility for macOS that modifies the Dock process so that the desktop bar in Mission Control is always full size and showing previews
184 stars 10 forks source link

Does not support arm64 macs #12

Closed briankendall closed 3 years ago

briankendall commented 3 years ago

Will need mach_inject to be updated to include support for arm64. (I am probably not the developer to make that change!)

w0lfschild commented 3 years ago

You can use Frida.re as an alternative. Frida is also way better maintained and documented. Example below:

command to run

frida Dock -q -l /path/to/script.js

script.js

var mybun = ObjC.classes.NSBundle.bundleWithPath_("/path/to/code/to/load.bundle"); 
mybun.load();

Making it automatically run at load as a launchagent would be something along the lines of.

<dict>
    <key>Label</key>
    <string>com.cool.beans</string>
    <key>LimitLoadToSessionType</key>
    <string>Aqua</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/frida</string>
        <string>Dock</string>
        <string>-q</string>  
        <string>-l</string>
        <string>/path/to/script.js</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <false/>
    <key>Disabled</key>
    <false/>
</dict>

On an M1 (or newer) mac the user needs to turn on the arm64e ABI after disabling SIP.

sudo nvram boot-args=-arm64e_preview_abi (requires reboot to apply)

Your plugin also needs to be compiled with an arm64e slice to load into the Dock. Most apple apps on the M1 run as arm64e and if you're making a plugin for a system app or process it needs to include an arm64e slice going forward.

briankendall commented 3 years ago

@w0lfschild Thanks for this! I had no idea frita existed, and this looks like what we need to get this working on M1.

ataridude commented 3 years ago

I have been trying to figure out how to use frida here. Is there a howto somewhere that I haven't found yet? I don't see a compiled frida, and I have not been able to compile it. I really miss forceFullDesktopBar since upgrading to my M1 MBA, and I could use some pointers here. Thanks.

briankendall commented 3 years ago

I took a look at it too and was having a hard time figuring out how best to use it. It seems like frida is a more complicated tool than is needed for forceFullDesktopBar, or at the very least comes with more features than we need. All we need is to inject and execute some compiled code inside of another process, like mach_inject can do.

The part where you use a python script in order to execute javascript inside of another process was in particular quite confusing to me. Is it injecting an entire javascript runtime? Is there any way to just inject a compiled dynamic library?

Brin-o commented 3 years ago

Has any progress been made on this? I wish I could help as this is a minor pain that is very annoying on my new m1 based macbook.

briankendall commented 3 years ago

I've been looking into this some more and still haven't found a good way to inject code into the Dock on Apple Silicon. I found another injection function located here that seems to support arm64, but I haven't been able to get it to run any code inside of a target process.

And for the life of me I can't figure out how I'm supposed to use Frida. What I need it to do is inject compiled code from a dylib into a process and then execute the dylib's code in a newly created thread, just like mach_inject. I'm not sure if it's able to do that though. @w0lfschild Can you offer any tips towards that?

w0lfschild commented 3 years ago

I've been looking into this some more and still haven't found a good way to inject code into the Dock on Apple Silicon. I found another injection function located here that seems to support arm64, but I haven't been able to get it to run any code inside of a target process.

And for the life of me I can't figure out how I'm supposed to use Frida. What I need it to do is inject compiled code from a dylib into a process and then execute the dylib's code in a newly created thread, just like mach_inject. I'm not sure if it's able to do that though. @w0lfschild Can you offer any tips towards that?

I thought I explained it pretty clearly originally:

  1. Compile your plugin with an arm64e slice --- note that this is arm64e not arm64
  2. Make sure your code is built with the extension .bundle
  3. Install Frida
  4. Open terminal and run these commands:
    Frida Dock
    var a = ObjC.classes.NSBundle.bundleWithPath_("/path/to/code/to/load.bundle"); 
    a.load();
  5. Your code will now be running in the Dock process

You can move the Frida commands to a javascript file and execute them with one line and add that as launchagent to get it run at login:

  1. Create a .js file
  2. Make the contents of the file
    var mybun = ObjC.classes.NSBundle.bundleWithPath_("/path/to/code/to/load.bundle"); 
    mybun.load();
  3. Run the .js file with Frida
    /usr/local/bin/frida Dock -q -l /path/to/script.js
briankendall commented 3 years ago

@w0lfschild Thanks, I was being a bit daft with not recompiling the dylib as a bundle. I was able to get it injected in x86_64 that way.

Next I'll need some way of including frida's injection code in with the app, since I'd prefer not to require the user to install frida separately in order to get it working.

briankendall commented 3 years ago

Looks like frida includes static libraries that can do what I want. They are however quite heavy weight since they're intended for running Javascript code, and all I need is something that'll inject an already compiled bundle into a process. If I can't find anything else I'll make use of it, but I'm still hoping I can find something lightweight and just intended for use in C / C++ code.

briankendall commented 3 years ago

Another rather unhappy update:

I've managed to get frida to inject code into the Dock on my M1 mac. However, I've hit another serious roadblock: the fishhook library does not work when the architecture is arm64e. It works with arm64, but not arm64e. The Dock, though, is arm64e and therefore requires arm64e code to be injected into it. The method forceFullDesktopBar uses relies on fishhook, so until that can get updated we're dead in the water. I've filed a bug report in fishhook's repo. If we're lucky someone will find a fix.

briankendall commented 3 years ago

A happy update!

I was able to also use Frida to replace fishhook, and released version 1.2 of forceFullDesktopBar with support for Apple Silicon macs!

skehlet commented 3 years ago

Working great on my arm MacBook Air! Thank you!

ataridude commented 3 years ago

Unfortunately this isn't working on my MacBook Air (M1, running 11.6). I rebooted thinking that might help, but no joy.

briankendall commented 3 years ago

@ataridude Did you run the installer that came with the release? If so, could you run the uninstaller, and then in either case try doing this:

  1. In a terminal window cd into the directory with forceFullDesktopBar and dockInjection.dylib in it
  2. Execute the following: sudo ./forceFullDesktopBar
  3. Copy / paste its output into a comment here
ataridude commented 3 years ago

I did run the install, and it said something about being in progress. Not sure where that came from since it's not in your install script.

I then ran the uninstaller and reinstalled it. Then I rebooted. Now I just ran the binary itself as you requested; here is the output:

% sudo ./forceFullDesktopBar 
Killed
Exit 137
%

I then ran the uninstaller again, then ran the binary again and got exactly that same output. The "Exit 137" is there because I have my shell print nonzero exit codes.

briankendall commented 3 years ago

@ataridude You need to open a terminal window and execute the following: sudo nvram boot-args=-arm64e_preview_abi ...then reboot your system. Let me know whether it works after that.

ataridude commented 3 years ago

@briankendall Thanks -- it was more than that, but I got it: I had never run csrutil disable on this laptop, so today I learned how to boot my M1 into recovery mode to do that -- then I ran the nvram command, rebooted, and installed forceFullDesktopBar. Success! This is great - thanks so much!