Le méfait est-il géré?
Voici une capture d'écran de mon Xcode 9 avec Deccy à 13pt:
Je crois que ce qui précède est ce que vous voulez. Voici stock Xcode affichant le même fichier:
Mais comment?
J'ai sondé plus profond d'une manière non invasive pour ce faire, et a échoué. Aussi loin que je peux dire, le rendu de texte chemin d'accès dans Xcode 9 très délibérément tourne sur le lissage des polices.
Avant d'aller plus loin, veuillez déposer une demande de fonctionnalité avec Apple. Il ne prend que quelques minutes, et c'est votre meilleur espoir pour une réponse qui peut être discutée, en face de ceux avec le son de la sécurité des instincts et tendues cardiovasculature:
https://bugreport.apple.com/
J'ai écrit un Xcode plugin. Vous pourriez avoir entendu parler que Xcode 9 utilise la signature du code de restrictions d'interdire le chargement des plugins. C'est vrai, mais quelques francs-tireurs de la presse, et ce soir nous montons avec eux.
La première étape
Il est un outil, update_xcode_plugins. Vous pouvez l'utiliser pour la bande de la signature de code à partir de votre copie de Xcode, et avec elle, le bundle de chargement de restriction:
$ gem install update_xcode_plugins
$ update_xcode_plugins --unsign
Si vous changez d'avis, vous pouvez le faire revenir pour (une copie de sauvegarde, je pense?) de signé Xcode:
$ update_xcode_plugins --restore
Étape deux
Il est un autre outil, Alcatraz. C'est un gestionnaire de plugin pour Xcode. J'ai choisi de l'installer car il fournit un plugin qui fournit un modèle de projet pour les plugins. J'ai suivi ces instructions pour installer Alcatraz, qui se résument à ceci:
$ git clone https://github.com/alcatraz/Alcatraz.git
$ cd Alcatraz
$ xcodebuild
J'ai lancé Xcode, cliqué sur la boîte de dialogue d'avertissement de moi sur le nouveau plug-in, et a ensuite utilisé le nouvellement ajouté Fenêtre > Gestionnaire de paquets pour installer Xcode Plugin" modèle.
Étape trois
J'ai fait un projet avec ce modèle.
Comme je l'ai écris ceci, le "Xcode Plugin" modèle " n'a pas été mis à jour à l'appui de Xcode 9. Pas de soucis. J'ai exécuté cette commande pour saisir Xcode 9 de la compatibilité de l'UUID:
$ defaults read /Applications/Xcode.app/Contents/Info DVTPlugInCompatibilityUUID
J'ai visité mon nouveau projet de l'Info.plist et a ajouté que l'UUID de l' DVTPlugInCompatibilityUUIDs
tableau.
Ensuite, j'ai relié SourceEditor.framework
dans mon projet. C'était un processus en deux étapes:
-
Visite de la cible Paramètres de construction. Ajoutez à cela le Cadre des Chemins de Recherche:
/Applications/Xcode.app/Contents/SharedFrameworks/
Visite de la cible Phases de construction. Ajouter un nouveau Lien "Binaire Avec les Bibliothèques" de phase. A frappé le plus. Naviguez vers le répertoire ci-dessus (vous pouvez appuyez simplement sur le / la clé et puis coller le chemin d'accès) et choisissez SourceEditor.framework
. Il devrait apparaître dans la liste. Le projet doit encore construire des.
Ensuite, j'ai fait mon plugin .mm
le fichier ressemble à ceci (j'ai supprimé l' .h
le fichier, c'est inutile pour ce PoC):
#import <AppKit/AppKit.h>
#include <dlfcn.h>
extern void CGContextSetAllowsFontAntialiasing(CGContextRef, BOOL);
static void hooked_sourceEditorSetFontSmoothingStyle(CGContextRef ctx) {
CGContextSetAllowsFontAntialiasing(ctx, NO);
}
@interface NoAA : NSObject
@end
@implementation NoAA
+ (void)pluginDidLoad:(NSBundle *)plugin
{
NSArray *allowedLoaders = [plugin objectForInfoDictionaryKey:@"me.delisa.XcodePluginBase.AllowedLoaders"];
if (![allowedLoaders containsObject:[[NSBundle mainBundle] bundleIdentifier]])
return;
Class cls = NSClassFromString(@"SourceEditorScrollView");
NSBundle* bundle = [NSBundle bundleForClass:cls];
void *handle = dlopen(bundle.executablePath.fileSystemRepresentation, RTLD_NOW);
if (!handle)
return;
uint8_t* set_font_smoothing_fn = dlsym(handle, "sourceEditorSetFontSmoothingStyle");
if (!set_font_smoothing_fn)
goto fin;
void* set_font_smoothing_fn_page = (void*)((long)set_font_smoothing_fn & -PAGE_SIZE);
if (mprotect(set_font_smoothing_fn_page, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC))
goto fin;
set_font_smoothing_fn[0] = 0xe9; // jmp
uint32_t* jmp_arg = (uint32_t*)(set_font_smoothing_fn + 1);
*jmp_arg = (uint32_t)((long)hooked_sourceEditorSetFontSmoothingStyle - (long)(jmp_arg + 1));
mprotect(set_font_smoothing_fn_page, PAGE_SIZE, PROT_READ | PROT_EXEC);
fin:
dlclose(handle);
}
@end
...Je pense que l' goto
s ajouter du caractère. Fondamentalement, il ne définit une fonction qui prend un CGContextRef
et éteint le texte de l'anticrénelage pour elle. Ensuite, il écrase le début d'une fonction à l'intérieur de la SourceEditor cadre qui, d'ordinaire, configure les paramètres d'anticrénelage - n'a pas besoin de plus pour passer à notre fonction à la place. Il fait tout cela dans un incroyablement dangereux, donc si quelque chose va mal, Xcode peut poliment crash.
Générer et exécuter le projet, qui installe automatiquement le plugin. Accepter l'ajout de votre plugin, et c'est tout.
Que faire maintenant?
Si quoi que ce soit ici ne fonctionne pas parce que j'ai foiré, laissez-moi savoir. Je suis pas la planification de rouler cette dans une Alcatraz plugin moi-même, mais vous ou quelqu'un d'autre doit le faire avec le crédit (après le dépôt d'une demande de fonctionnalité avec Apple).
Happy hacking!