Skip to content

Instantly share code, notes, and snippets.

@0cyn
Last active March 18, 2022 05:58
Show Gist options
  • Select an option

  • Save 0cyn/9ae09b13332daa5d094d883847bb2856 to your computer and use it in GitHub Desktop.

Select an option

Save 0cyn/9ae09b13332daa5d094d883847bb2856 to your computer and use it in GitHub Desktop.
---
name: rtdump
icmd: sbreload
package: blog.katwalk.rtdump
version: 1.0.0
description: runtime load and dump raw metadata of classes
author: kritanta
rtdump:
type: cli
files:
- rtdump.m
#include <dlfcn.h>
#import <objc/runtime.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
#include <Foundation/Foundation.h>
void printClassNames(char *path) {
int amountClasses = objc_getClassList(NULL, 0);
// printf("Amount of classes: %d", amountClasses);
Class *classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * amountClasses);
amountClasses = objc_getClassList(classes, amountClasses);
NSMutableDictionary *classMap = [NSMutableDictionary new];
NSString *bundlePath = [NSString stringWithUTF8String:path];
// NSLog(@"%@", bundlePath);
for (int i = 0; i < amountClasses; i++) {
Class class = classes[i];
Class metaClass = objc_getMetaClass(class_getName(class));
Class superClass = class_getSuperclass(class);
// NSLog(@"%@", [NSBundle bundleForClass:class]);
if ([NSBundle bundleForClass:class] != [NSBundle bundleWithPath:bundlePath]) { // restriction that pass classes from main bundle
continue;
}
NSMutableDictionary *singularClassDict = [NSMutableDictionary new];
NSString *className = [NSString stringWithUTF8String:class_getName(class)];
NSString *superClassName = [NSString stringWithUTF8String:class_getName(superClass)];
singularClassDict[@"Name"] = className;
singularClassDict[@"Superclass"] = superClassName;
NSMutableArray *instanceProperties = [NSMutableArray new];
uint count;
objc_property_t* properties = class_copyPropertyList(class, &count);
for (int i = 0; i < count ; i++) {
const char* propertyName = property_getName(properties[i]);
const char* propertyAttr = property_getAttributes(properties[i]);
[instanceProperties addObject:[NSString stringWithFormat:@"%s %s", propertyAttr, propertyName]];
}
free(properties);
[singularClassDict setObject:instanceProperties forKey:@"props"];
unsigned int amountMethod = 0;
NSMutableArray *instanceMethods = [NSMutableArray new];
NSMutableArray *classMethods = [NSMutableArray new];
Method *methods = class_copyMethodList(class, &amountMethod);
for (unsigned int i = 0; i < amountMethod; i++) {
Method method = methods[i];
[instanceMethods addObject:[NSString stringWithFormat:@"%s %s", method_getTypeEncoding(method), sel_getName(method_getName(method))]];
}
Method *cmethods = class_copyMethodList(metaClass, &amountMethod);
for (unsigned int i = 0; i < amountMethod; i++) {
Method method = cmethods[i];
[classMethods addObject:[NSString stringWithFormat:@"%s %s", method_getTypeEncoding(method), sel_getName(method_getName(method))]];
}
singularClassDict[@"instance"] = instanceMethods;
singularClassDict[@"class"] = classMethods;
classMap[className] = singularClassDict;
}
free(classes);
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:classMap
options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
error:&error];
if (! jsonData) {
NSLog(@"Got an error: %@", error);
} else {
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
//NSLog(@"%@", jsonString);
printf("%s\n", jsonString.UTF8String);
}
}
int main(int argc, char *argv[]) {
char *fw = argv[1];
dlopen(fw, 0x4);
printClassNames(dirname(fw));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment