Objective-CS and the llvm-objcs Toolchin#
Dragon ships with builtin integration for the llvm-objcs toolchain and the Objective-CS hooking language.
It provides wrappers, utilities, and commands that help set up the toolchain and get autocomplete, editor support, etc working with clangd.
A companion extension for vscode exists at [LINKHERE]
Adding support to a project should be fairly drop-in. Projects using Objective-CS can still use logos, they will just need to be in separate files for autocomplete, etc to work.
Objective-CS#
Objective-CS is an extension of Objective-C designed to provide easier integration with hooking APIs than working in purely Objective-C.
By building our language directly within llvm as opposed to via a preprocessor (logos), we gain access to a large amount of existing tooling that already supports LLVM.
This allows autocomplete, inline error messages/help/suggestions, and the myriad other clangd features to work within Objective-CS files.
File Extension#
Currently, Objective-CS just adds support directly into Objective-C code, so you use the same .m or .mm extension as regular objc. Eventually it may be gated or aliased to .mx/.mmx.
Basic Syntax#
The following code block demos the full current featureset of Objective-CS
// Predeclaring the interface for what we're hoooking isn't required,
// but it allows us to:
// autocomplete hook selectors
// access ivars of the class we're hooking
// declare new methods we want to add
@interface SBIconView : UIView
{
BOOL _allowsLabelArea; // Declare ivars we want to "hook" (access) here
CGFloat _iconImageAlpha; // This replaces the need for swapping to ObjC++ and wrangling the MSHookIvar API.
}
-(void)configureForLabelAllowed:(BOOL)allowed;
@new
-(void)myAwesomeNewInstanceMethod;
@end
// If you've already imported a header for a given class (from a patched SDK that has proper headers),
// you can instead declare a category ( `@interface SBIconView ()` ) and still utilize these features.
// This accomplishes the same thing in terms of
// applying new methods, accessing ivars that maybe didn't exist in the header you imported, etc.
// --
@group iOS13Plus
@hook SBIconView
-(void)myAwesomeNewInstanceMethod
{
NSLog(@"Hello from Objective-CS!");
}
-(void)configureForLabelAllowed:(BOOL)allowed
{
@orig(NO);
_allowsLabelArea = NO;
_iconImageAlpha = 0.5;
[self myAwesomeNewInstanceMethod];
}
@end
@end
#ifndef kCFCoreFoundationVersionNumber_iOS_13_0
#define kCFCoreFoundationVersionNumber_iOS_13_0 1665.15
#endif
// This is a manually declared constructor. This is not required if you are not using groups.
// You *will* need to use one if you are using groups, as all groups must be initialized for their hooks to be applied.
// _eventually,_ something like @ctor (analogous to logos' %ctor) may be added.
__attribute__((constructor))
void initFunc(void)
{
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_13_0){
@init(iOS13Plus);
// initialize multiple groups: @init(myGroup, mySecondGroup, andSoOn);
}
}
Future#
Plans exist to add support for: * @hookf(FunctionName) * @ctor{} * @subclass
This is a hobby project with one developer, so there is no timeframe on these plans :)
llvm-objcs#
LLVM-objcs is a fork of Apple’s LLVM that supports compiling Objective-CS code.
It aims to support the same featureset as apple-llvm, however modules have been an undocumented pain to compile support for, so the currently distributed binaries do not yet support them (i.e. @import UIKit;. Just import headers normally for now).
Builds are available in arm64 and x86_64 form for macOS, <upcoming> linux, and iOS (iOS is arm64 only, silly)</upcoming>
Installing#
dragon lo setup will download and install the appropriate toolchain for your system.
It will also be automatically installed if a DragonMake project declares it as required, and it isn’t already installed.
Manually#
Download or build the appropriate toolchain and extract/install it in ~/.dragon/llvm-objcs. The directory structure should be as follows:
serket@prospit ~ % tree ~/.dragon/llvm-objcs -L 1
/Users/serket/.dragon/llvm-objcs
├── bin
├── include
├── lib
├── libexec
└── share
After that you’re good to go.
Future#
As this toolchain was built off of llvm-17, it does not support arm64e libraries injected into arm64e processes for pre-iOS 14 devices.
This is an issue with all toolchains post llvm-12, and workarounds are being looked into.