https://github.com/zekunyan/ttgremakemethodsignatureforselector
Remake methodSignatureForSelector. Just for research. :)
https://github.com/zekunyan/ttgremakemethodsignatureforselector
assembly core hopper-disassembler ios objective-c
Last synced: 14 days ago
JSON representation
Remake methodSignatureForSelector. Just for research. :)
- Host: GitHub
- URL: https://github.com/zekunyan/ttgremakemethodsignatureforselector
- Owner: zekunyan
- Created: 2017-04-09T15:46:33.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2017-04-10T02:37:19.000Z (about 8 years ago)
- Last Synced: 2025-04-03T09:05:08.104Z (about 2 months ago)
- Topics: assembly, core, hopper-disassembler, ios, objective-c
- Language: Objective-C
- Size: 75.2 KB
- Stars: 11
- Watchers: 2
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# TTGRemakeMethodSignatureForSelector
Remake `methodSignatureForSelector:`,just for research.
如果你在天朝:
团队博客:[http://icbu.info/diy_methodsignatureforselector/](http://icbu.info/diy_methodsignatureforselector/)
土土哥的技术Blog: [http://tutuge.me/2017/04/08/diy-methodSignatureForSelector/](http://tutuge.me/2017/04/08/diy-methodSignatureForSelector/)## Core code
ttg_MethodDescription
```
struct objc_method_description ttg_MethodDescription(Class class, SEL sel) {
// Result
struct objc_method_description description = (struct objc_method_description){NULL, NULL};
// Loop class
Class currentClass = class;
while (currentClass && description.name == NULL) {
// Get protocol list
unsigned int count = 0;
__unsafe_unretained Protocol **protocols = class_copyProtocolList(currentClass, &count);
// Check each protocol
for (unsigned int i = 0; i < count; i++) {
// Required method
description = protocol_getMethodDescription(protocols[i], sel, YES, class_isMetaClass(currentClass) ^ 1);
if (description.name != NULL) {
break;
}
// Optional method
description = protocol_getMethodDescription(protocols[i], sel, NO, class_isMetaClass(currentClass) ^ 1);
if (description.name != NULL) {
break;
}
}
// release
free(protocols);
// Found in protocol
if (description.name != NULL) {
return description;
}
// Get superClass and continue
currentClass = class_getSuperclass(currentClass);
}
// Get implemented instance method
Method method = class_getInstanceMethod(class, sel);
if (method) {
// Get description
return *method_getDescription(method);
} else {
// Return Null result
return (struct objc_method_description){NULL, NULL};
}
}
```NSObject Category
```
@implementation NSObject (TTGRemakeMethodSignatureForSelector)- (NSMethodSignature *)ttg_methodSignatureForSelector:(SEL)sel {
struct objc_method_description description = ttg_MethodDescription([self class], sel); // Get from class
if (sel && description.types != NULL) {
return [NSMethodSignature signatureWithObjCTypes:description.types];
} else {
return nil;
}
}+ (NSMethodSignature *)ttg_methodSignatureForSelector:(SEL)sel {
struct objc_method_description description = ttg_MethodDescription(object_getClass(self), sel); // Get from metaClass
if (sel && description.types != NULL) {
return [NSMethodSignature signatureWithObjCTypes:description.types];
} else {
return nil;
}
}@end
```## CoreFoundation.framework implementation from Hopper Disassemabler
[NSObject methodSignatureForSelector:]
```
void * +[NSObject methodSignatureForSelector:](void * self, void * _cmd, void * arg2) {
rdi = self;
rbx = arg2;
if ((rbx != 0x0) && (___methodDescriptionForSelector(object_getClass(rdi), rbx) != 0x0)) {
rax = [NSMethodSignature signatureWithObjCTypes:rdx];
}
else {
rax = 0x0;
}
return rax;
}
```___methodDescriptionForSelector:

```
int ___methodDescriptionForSelector(int arg0, int arg1) {
var_40 = arg1;
var_38 = arg0;
if (arg0 == 0x0) goto loc_918d6;loc_917e2:
r15 = var_38;
goto loc_917f0;loc_917f0:
r12 = class_copyProtocolList(r15, 0x0);
var_50 = r15;
if (0x0 == 0x0) goto loc_918a0;loc_91814:
r13 = 0x0;
var_48 = r12;
goto loc_91820;loc_91820:
rbx = var_40;
rdi = r15;
r15 = protocol_getMethodDescription(*(r12 + r13 * 0x8), rbx, 0x1, (class_isMetaClass(r15) ^ 0x1) & 0xff);
r14 = 0x1;
if (r15 != 0x0) goto loc_918b4;loc_91853:
r15 = protocol_getMethodDescription(*(r12 + r13 * 0x8), rbx, 0x0, (class_isMetaClass(rdi) ^ 0x1) & 0xff);
r14 = 0x0;
if (r15 != 0x0) goto loc_918b0;loc_91879:
r13 = r13 + 0x1;
r15 = var_50;
r12 = var_48;
if (r13 < 0x0) goto loc_91820;loc_9188c:
r15 = 0x0;
goto loc_918b4;loc_918b4:
free(r12);
if (r15 != 0x0) goto loc_918ff;loc_918c1:
r15 = class_getSuperclass(var_50);
if (r15 != 0x0) goto loc_917f0;loc_918d6:
rax = class_getInstanceMethod(var_38, var_40);
if (rax != 0x0) {
rax = method_getDescription(rax);
r15 = *rax;
r14 = *(rax + 0x8);
}
else {
r15 = 0x0;
r14 = 0x0;
}
goto loc_918ff;loc_918ff:
rax = r15;
return rax;loc_918b0:
r12 = var_48;
goto loc_918b4;loc_918a0:
if (r12 == 0x0) goto loc_918c1;loc_918a5:
r14 = 0x0;
r15 = 0x0;
goto loc_918b4;
}
```