Objective-CS

From iPhone Development Wiki
(Redirected from Clang-logos)

Overview

Objective-CS is an Objective-C extension for hooking class methods at runtime via MobileSubstrate.

A few notable features are:

  • Instance Variable (ivar) hooking is now as simple as using them normally. No more MSHookIvar.
  • It ships with clangd and thus offers modern language server features in common editors (autocomplete, etc)

It is an alternative to the logos preprocessor that is particularly notable for being implemented within LLVM itself. This allows it to implement some things Perl would very heavily struggle with.

The "Objective-CS" project appears to be an iteration upon the original clang-logos project.

It was theorized, specified, and implemented by Evan Swick in 2014-2015 as a fork of LLVM's clang compiler.

Development has been continued of the project via the llvm-objcs compiler and associated tooling listed below. As of Sep 4, 2023, it builds with the latest version of the `next` branch on Apple's LLVM fork

Documentation

Documentation for the Objective-CS specification is available via the `dragon` docs: https://dragon.cynder.me/en/latest/objcs.html

Specification

This github repo tracks the currently implemented specification for llvm-objcs. It is currently unchanged from the original specification proposed by eswick.

Getting Started

Installing

Compiled toolchains for Intel and Apple Silicon macOS machines are available at https://github.com/DragonBuild/llvm-objcs/releases/tag/llvm-objcs-0.1.0-llvm-17.0.0

dragon, if you use it, offers the `dragon lo setup` command which will install and configure the appropriate toolchain for your system.

For theos it is unclear to me how you would install this currently as IIRC it uses xcrun to find the toolchain if it finds that command? Need to check l8r

Usage

Objective-CS syntax is slightly different than original Logos.

For proper usage, header of the class you're hooking should be in an external file, separate from the file containing the hooks. This header typically comes from a class dumping website or tool.

// SBIconView.h

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

@end

The hooking code should go in a normal Objective-C file, with an extension of .m / .mm

#import "SBIconView.h"

// Declare a class category; this is where your new declarations go. 
// You can add them in the original header, too, but this convention is cleaner.
@interface SBIconView () 

// Add our property
@property (nonatomic, retain) UIView *indicatorView;

@new // Methods declared after @new are added to the class at runtime
- (void)myAwesomeNewInstanceMethod;

@end


@hook SBIconView

-(void)myAwesomeNewInstanceMethod
{
  NSLog(@"Hello from Objective-CS!");
}

-(void)configureForLabelAllowed:(BOOL)allowed
{
    @orig(NO);
    // All we have to do to 'hook' these ivars :)
    _allowsLabelArea = NO;
    _iconImageAlpha = 0.5;
    [self myAwesomeNewInstanceMethod];
}

@end