ioscycript

Accessing <objc/runtime.h> from Cycript


I wan't to be able to use associated objects and ISA swizzle, but I can't figure out how to import objc/runtime.h for use with Cycript. I have tried in both the console and in .js files but no luck.

Ideally I'd like to figure out how to include frameworks as well.


Solution

  • It seems like a subset of runtime.h is included by default in the Cycript environment. For example, class_copyMethodList and objc_getClass work without any added effort.

    var count = new new Type(@encode(int));
    var methods = class_copyMethodList(objc_getClass("NSObject"), count);
    

    However objc_setAssociatedObject is not referenced:

    objc_getAssociatedObject(someVar, "asdf")
    #ReferenceError: Can't find variable: objc_getAssociatedObject
    

    After a lot of searching, I realized the answer was right under my nose. limneos's weak_classdump uses the runtime to do it's dump and Cycript's tutorial shows how to grab C functions.

    The solution I ended up with is this:

    function setAssociatedObject(someObject, someValue, constVoidPointer) {
        SetAssociatedObject = @encode(void(id, const void*, id, unsigned long))(dlsym(RTLD_DEFAULT, "objc_setAssociatedObject"))
        SetAssociatedObject(someObject, constVoidPointer, someValue, 1)
    }
    
    function getAssociatedObject(someObject, constVoidPointer) {
        GetAssociatedObject = @encode(id(id, const void*))(dlsym(RTLD_DEFAULT, "objc_getAssociatedObject"))
        return GetAssociatedObject(someObject, constVoidPointer)
    }
    

    It is used like this:

    # create void pointer (probably should be a global variable for later retrieval)
    voidPtr = new new Type(@encode(const void))
    
    someVar = [[NSObject alloc] init]
    setAssociatedObject(someVar, @[@"hello", @"world"], voidPtr)
    getAssociatedObject(someVar, voidPtr)
    # spits out @["Hello", "World"]