Last active
December 16, 2015 00:29
-
-
Save atommclain/a957e39525209a3051d3 to your computer and use it in GitHub Desktop.
Objective-C method reflection question
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import <objc/runtime.h> | |
#define varString(varname) #varname | |
#define logPointerInfo(ptr1, ptr2) \ | |
NSLog(@"%s: %p, %s: %p equal: %@", varString(ptr1), ptr1, varString(ptr2), ptr2, (ptr1 - (intptr_t *)ptr2 == 0 ? @"YES" : @"NO")) | |
@interface ADTestObject : NSObject | |
@end | |
@implementation ADTestObject | |
- (void)test:(NSString *)stringOne secondString:(NSString *)stringTwo | |
thridString:(NSString *)stringThree | |
fourthString:(NSString *)stringFour | |
fifthString:(NSString *)stringFive | |
sixthString:(NSString *)stringSix | |
{ | |
// I am an expanded macro inside an unknown instance method | |
// NSLog(@"some how uncommenting this breaks the following code. Why come?"); | |
intptr_t *arg0; | |
__asm__ __volatile__( | |
"mov %%rdi,%0\n\t" | |
: "=r" (arg0)); | |
intptr_t *arg1; | |
__asm__ __volatile__( | |
"mov %%rsi,%0\n\t" | |
: "=r" (arg1)); | |
intptr_t *arg2; | |
__asm__ __volatile__( | |
"mov %%rdx,%0\n\t" | |
: "=r" (arg2)); | |
intptr_t *arg3; | |
__asm__ __volatile__( | |
"mov %%rcx,%0\n\t" | |
: "=r" (arg3)); | |
intptr_t *arg4; | |
__asm__ __volatile__( | |
"mov %%r8,%0\n\t" | |
: "=r" (arg4)); | |
intptr_t *arg5; | |
__asm__ __volatile__( | |
"mov %%r9,%0\n\t" | |
: "=r" (arg5)); | |
intptr_t *arg6; | |
__asm__ __volatile__( | |
"mov -(96)(%%rbp),%0\n\t" // I think I should be using RSI for this... | |
: "=r" (arg6)); | |
intptr_t *arg7; | |
__asm__ __volatile__( | |
"mov -(96+48)(%%rbp),%0\n\t" | |
: "=r" (arg7)); | |
NSLog(@"%s", __PRETTY_FUNCTION__); | |
logPointerInfo(arg0, self); | |
logPointerInfo(arg1, (void *)_cmd); // why does this need to be cast to void *? | |
logPointerInfo(arg2, stringOne); | |
logPointerInfo(arg3, stringTwo); | |
logPointerInfo(arg4, stringThree); | |
logPointerInfo(arg5, stringFour); | |
logPointerInfo(arg6, stringFive); | |
logPointerInfo(arg7, stringSix); | |
NSMethodSignature *sig = [[[(id)arg0 class] alloc] methodSignatureForSelector:(SEL)arg1]; | |
NSLog(@"frameLength : %lx", sig.frameLength); | |
NSLog(@"numberOfArgs: %lx", sig.numberOfArguments); | |
Method method = class_getInstanceMethod([self class], _cmd); | |
unsigned int numberOfArgs = method_getNumberOfArguments(method); | |
NSLog(@"Number of arguments %i", numberOfArgs); | |
if (numberOfArgs < 3) | |
{ | |
return; // method has no parameters ('self' and '_cmd' are sent to all methods) | |
} | |
for (unsigned int i = 2; i <= numberOfArgs; i++) | |
{ | |
char argType[256]; | |
method_getArgumentType(method, i, argType, 256); | |
NSString *argumentType = [NSString stringWithUTF8String:argType]; | |
if ([argumentType isEqualToString:@"@"]) | |
{ | |
// argument is object, do fancy printing here | |
} | |
} | |
} | |
- (void)test:(NSString *)stringOne secondString:(NSString *)stringTwo | |
thridString:(NSString *)stringThree | |
fourthString:(NSString *)stringFour | |
fifthString:(NSString *)stringFive | |
sixthString:(NSString *)stringSix | |
seventhString:(NSString *)stringSeven | |
{ | |
// I am an expanded macro inside an unknown instance method but now I'm broken just because this method takes an additional parameter | |
intptr_t *arg0; | |
__asm__ __volatile__( | |
"mov %%rdi,%0\n\t" | |
: "=r" (arg0)); | |
intptr_t *arg1; | |
__asm__ __volatile__( | |
"mov %%rsi,%0\n\t" | |
: "=r" (arg1)); | |
intptr_t *arg2; | |
__asm__ __volatile__( | |
"mov %%rdx,%0\n\t" | |
: "=r" (arg2)); | |
intptr_t *arg3; | |
__asm__ __volatile__( | |
"mov %%rcx,%0\n\t" | |
: "=r" (arg3)); | |
intptr_t *arg4; | |
__asm__ __volatile__( | |
"mov %%r8,%0\n\t" | |
: "=r" (arg4)); | |
intptr_t *arg5; | |
__asm__ __volatile__( | |
"mov %%r9,%0\n\t" | |
: "=r" (arg5)); | |
intptr_t *arg6; | |
__asm__ __volatile__( | |
"mov -(96)(%%rbp),%0\n\t" | |
: "=r" (arg6)); | |
intptr_t *arg7; | |
__asm__ __volatile__( | |
"mov -(96+48)(%%rbp),%0\n\t" | |
: "=r" (arg7)); | |
intptr_t *arg8; | |
__asm__ __volatile__( | |
"mov -(96+48)(%%rbp),%0\n\t" | |
: "=r" (arg8)); | |
NSLog(@"%s", __PRETTY_FUNCTION__); | |
logPointerInfo(arg0, self); | |
logPointerInfo(arg1, (void *)_cmd); // why does this need to be cast to void *? | |
logPointerInfo(arg2, stringOne); | |
logPointerInfo(arg3, stringTwo); | |
logPointerInfo(arg4, stringThree); | |
logPointerInfo(arg5, stringFour); | |
logPointerInfo(arg6, stringFive); | |
logPointerInfo(arg7, stringSix); | |
logPointerInfo(arg8, stringSeven); | |
// ...the rest of the code from above | |
} | |
@end | |
int main(int argc, char *argv[]) { | |
@autoreleasepool { | |
NSString *string = @"Hello world. The quick brown fox jumped over the lazy brown dog."; | |
NSArray *words = [string componentsSeparatedByString:@" "]; | |
ADTestObject *testObj = [[ADTestObject alloc] init]; | |
// This *brittle* method works as intended | |
[testObj test:words[0] secondString:words[1] thridString:words[2] fourthString:words[3] fifthString:words[4] sixthString:words[5]]; | |
// Adding an additional parameter breaks previous working code... :( | |
[testObj test:words[0] secondString:words[1] thridString:words[2] fourthString:words[3] fifthString:words[4] sixthString:words[5] seventhString:words[6]]; | |
} | |
} | |
// http://quickies.seriot.ch/?id=451 | |
// http://0xax.blogspot.com/2014/12/say-hello-to-x8664-assembly-part-7.html | |
// https://www.clarkcox.com/blog/2009/02/04/inspecting-obj-c-parameters-in-gdb/ | |
// http://www.raywenderlich.com/37181/ios-assembly-tutorial | |
// TODO: get extra values from $bp // sorta | |
//http://stackoverflow.com/questions/10890648/add-a-variable-to-the-stack-in-x86-assembly | |
//http://zenit.senecac.on.ca/wiki/index.php/X86_64_Register_and_Instruction_Quick_Start | |
//http://stackoverflow.com/questions/21030898/xcode-running-asm | |
//http://asm.sourceforge.net/articles/rmiyagi-inline-asm.txt | |
//https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html | |
//http://0xax.blogspot.com/2014/12/say-hello-to-x8664-assembly-part-7.html |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
compilation flags:
-std=c99 -framework Foundation