版权声明:本文为博主原创文章,未经博主允许可以转载,但转载时请附上原文地址: https://blog.csdn.net/youshaoduo/article/details/81702005
本文旨在获取重签名包里面对象的属性和方法,也就是说在引用不到该类的头文件的情况下,获取这些方法以及替换这些方法。至于这些类名可以通过IDA分析出来,也可以通过class-dump逆向出头文件(仅限objective-C工程)。
替换任意方法(感谢群内大佬Sun提供。。):
/**
替换任意方法(包括代理方法)
@param originalClass 原先的类
@param originalSel 原先的方法
@param replacedClass 新的类(这是最强大的地方:可以是任意的类,不需要是原先类的category或者子类)
@param replacedSel 新的方法
@param orginReplaceSel 如果实现了代理方法,那么这里要填上代理方法,如果没实现,这里填originalSel
*/
static void bgl_exchangeMethod(Class originalClass, SEL originalSel, Class replacedClass, SEL replacedSel, SEL orginReplaceSel){
// 原方法
Method originalMethod = class_getInstanceMethod(originalClass, originalSel);
Method replacedMethod = class_getInstanceMethod(replacedClass, replacedSel);
// 如果没有实现 delegate 方法,则手动动态添加
if (!originalMethod) {
Method orginReplaceMethod = class_getInstanceMethod(replacedClass, orginReplaceSel);
BOOL didAddOriginMethod = class_addMethod(originalClass, originalSel, method_getImplementation(orginReplaceMethod), method_getTypeEncoding(orginReplaceMethod));
if (didAddOriginMethod) {
NSLog(@"did Add Origin Replace Method");
}
return;
}
// 向实现 delegate 的类中添加新的方法
// 这里是向 originalClass 的 replaceSel(@selector(replace_webViewDidFinishLoad:)) 添加 replaceMethod
BOOL didAddMethod = class_addMethod(originalClass, replacedSel, method_getImplementation(replacedMethod), method_getTypeEncoding(replacedMethod));
if (didAddMethod) {
// 添加成功
NSLog(@"class_addMethod_success --> (%@)", NSStringFromSelector(replacedSel));
// 重新拿到添加被添加的 method,这里是关键(注意这里 originalClass, 不 replacedClass), 因为替换的方法已经添加到原类中了, 应该交换原类中的两个方法
Method newMethod = class_getInstanceMethod(originalClass, replacedSel);
// 实现交换
method_exchangeImplementations(originalMethod, newMethod);
}else{
// 添加失败,则说明已经 hook 过该类的 delegate 方法,防止多次交换。
NSLog(@"Already hook class --> (%@)",NSStringFromClass(originalClass));
}
}
获取一个类的所有属性以及类型:
+ (NSDictionary *)getIvarList:(NSObject *)obj {
NSMutableDictionary * a = [[NSMutableDictionary alloc] init];
unsigned int count = 0;
Ivar *members = class_copyIvarList([obj class], &count);
for (int i = 0; i < count; i++)
{
Ivar var = members[i];
const char *memberAddress = ivar_getName(var);
const char *memberType = ivar_getTypeEncoding(var);
[a setValue:[NSString stringWithUTF8String:memberType] forKey:[NSString stringWithUTF8String:memberAddress]];
//memberAddress属性名 memberType属性的类型
NSLog(@"%s %s", memberAddress, memberType);
}
return a;
}
获取一个对象的属性内容并修改(这里需要配合交换方法使用,因为必须获取到该对象,才能取出里面的内容,代码中的self都代表该对象):
Ivar ivar1 = class_getInstanceVariable([self class], "_reqParam");
if (object_getIvar(self, ivar1)) {
//取出_reqParam的内容。这个可以通过上面的方法看到名称和类型。
NSMutableDictionary * dic = (NSMutableDictionary *)object_getIvar(self, ivar1);
NSLog(@"NSMutableDictionaryIvar: %@", dic);
if ([dic valueForKey:@"factor"] && [dic valueForKey:@"newMobileId"] && [dic objectForKey:@"password"]) {
//把dic的内容修改一下
[dic setValue:@"10.0.2" forKey:@"mobileOS"];
}
object_setIvar(self, ivar1, dic);
}
获取所有方法:
+ (void)getMethods:(NSObject *)object {
unsigned int count = 0;
//所有在.m文件显式实现的方法都会被找到
Method *mets = class_copyMethodList([object class], &count);
for(int i=0;i<count;i++){
NSString *str = [NSString stringWithCString:method_getTypeEncoding(mets[i]) encoding:NSUTF8StringEncoding];
SEL sel = method_getName(mets[i]);
NSString *name = [NSString stringWithCString:sel_getName(sel) encoding:NSUTF8StringEncoding];
NSLog(@"方法名:%@\n属性:%@",name,str);
}
}