Hook ObjC的不定参数方法

怎么Hook ObjC的不定参数方法,比如NSDictionary的+ [NSDictionary dictionaryWithObjectsAndKeys:]

于是稍微研究了一下,其实和普通的ObjC的Hook差不多的。

#include <Foundation/Foundation.h>
#include <Cocoa/Cocoa.h>
#include <objc/objc.h>
#include <objc/runtime.h>
#include <stdarg.h>

/*!
 *  @brief  用于替换不定参数方法的实现
 *
 *  @param self self
 *  @param op   selector
 *  @param obj1 first param
 *  @param ...  other params
 *
 *  @return for this case, returns an instance of NSDictionary
 */
id dictionaryWithObjectsAndKeys(id self, SEL op,id obj1, ...);
id dictionaryWithObjectsAndKeys(id self, SEL op,id obj1, ...)
{

    /*!
     *  @brief  用于保存Key和Value
     */

    NSMutableArray *keys = [[NSMutableArray alloc] init];
    NSMutableArray *values = [[NSMutableArray alloc] init];

    /*!
     *  @brief  使用stdarg提供的函数获取参数
     */

    va_list args;
    va_start(args, obj1);
    id obj = obj1;
    int flag = 0;
    while (obj != nil) {

    /*!
     *  @brief  因为这里演示的是NSDictionary的dictionaryWithObjectsAndKeys方法
     * 所以判断一下现在获取的是Key还是Value
     */

        if (flag % 2 == 0) {
            [keys addObject:obj];
            printf("[Hook] Key: %sn",[obj description].UTF8String);
        } else {
            [values addObject:obj];
            printf("[Hook] Value: %sn",[obj description].UTF8String);
        }
        obj = va_arg(args, id);
        flag++;
    }
    va_end(args);

    /*!
     *  @brief  自己实现一下等价的功能, 对于不定参数方法有时不一定方便调用%orig;
     */

    NSMutableDictionary * result = [[NSMutableDictionary alloc] init];
    for (int index = 0; index < keys.count; index++)
        [result setValue:[values objectAtIndex:index] forKey:[keys objectAtIndex:index]];
    return result;
}

int main(int argc, const char * argv[])
{

    /*!
     *  @brief  替换原来NSDictionary的实现
     */

    method_setImplementation( class_getClassMethod( NSClassFromString( @"NSDictionary" ), NSSelectorFromString( @"dictionaryWithObjectsAndKeys:" ) ), (IMP)dictionaryWithObjectsAndKeys );

    NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys : @"Name", @"0xBBC", @"Info", @{@"Blog" : @"Blog.0xBBC.com"}, nil];
    NSLog(@"%@",dict);
    return 0;
}

results matching ""

    No results matching ""