Git Product home page Git Product logo

libundirect's Introduction

libundirect

objc_direct is a feature introduced with Xcode 12 that, when specified, turns an Objective C method into an unexported C function after compilation.

This makes it completely impossible to call the method from inside a dylib thats injected into the process, as it is also impossible to know the method name unless you have an earlier version of the binary, in which the method you're looking for was compiled without objc_direct, at hand.

Apple has started using objc_direct in system applications, daemons and frameworks starting in iOS 14.0. Some examples for affected binaries: MobileSafari, SafariServices.framework, CoreFoundation.framework...

Before you can utilize libundirect, you will have to find the unexported function you're looking for via reverse engineering, this process won't be covered here. I have personally had success by searching for xrefs in an earlier binary without objc_direct, finding the methods that call your method in the new binary, hoping they are not also affected by objc_direct and finding the call to your method which will be a call to a sub_* C function now.

Examples:

example 1

example 2

Installation

Run install.sh, then you can import it using #import <libundirect.h>. Also make sure to add it to your makefile:

<YOUR_TWEAK>_LIBRARIES = undirect

Patchfinder

For the patchfinding process, it is important that you know the address of the unexported C function for at least one binary that you have, and that you have at least one other version of the binary where you don't know the address. This is important so you can make sure that the bytes stay the same accross different versions (as references to pointers usually change whenever the source code changes).

Now open the binary that you know the address of in a hex editor, jump to the address and start searching for unique bytes within the function. (E.g. copy a few bytes, search the binary for them, repeat until you only have one exact match inside your function for the whole binary). Once you have the bytes that may be unique, as mentioned earlier, now search for them in a different version of the binary and make sure you also only got one exact match. If you don't get a match in the other version, your bytes probably contain a sequence that changes between versions and you have to try out different bytes.

Once you have a unique byte sequence that stays the same between versions, the function libundirect_find can be used to locate your function. The start byte of the function also has to be supplied.

(Just because the byte sequence stays the same between versions it can still change in a future version if the specific instructions you're searching for are replaced with other instructions)

example 3

(Note: While this patchfinders main intend is to find objc_direct methods, it can also be used to find any undefined C function)

Rebinding methods

To provide backwards compatibility with older binaries, you can rebind the direct methods to the class using the libundirect_rebind function. Last argument is the type encoding of the method.

Hooking direct methods

After rebinding your method using libundirect_rebind, you now need to reroute all calls to MSHookMessageEx to libundirect_MSHookMessasgeEx, the easiest way to do it is by adding #import <libundirect_hookoverwrite.h> at the top of the file that has the hooks. libundirect_MSHookMessageEx detects whether the selector it is called with is a rebinded direct method and in that case it uses MSHookFunction instead, because direct methods are functions after being compiled and not methods.

If you don't need to use libundirect_rebind for backwards compatibility purposes, you can also directly call MSHookFunction yourself with the pointer returned by libundirect_find.

Reimplementing Methods

If you only need to call a method and not hook it, it might be possible to just reimplement a method. libundirect offers two macros to reimplement getters and setters.

Usage Example

Check out the Undirector.xmi file of Safari Plus. (Note that it gets the libundirect functions at runtime so that devices below iOS 14 do not need to have it installed. This assumption is only correct for system applications. If an AppStore application uses objc_direct, it will be used on all iOS versions supported by the application.)

libundirect's People

Contributors

opa334 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.