巧用不定参数来保护App

刚才写了如何Hook ObjC的不定参数方法,现在突然有了一个使用不定参数来保护App的想法。

设想这样一个情况,假定我们不对代码做混淆处理,App需要某个文件解密,使用的方法为:
- (void)decryptFileAt:(NSString *)arg1 Password:(NSString *)arg2;
 
现在这样class-dump一下子就能出来:
- (void) decryptFileAt:(id)arg1 Password:(id)arg2;
 
攻击者可以马上对arg1和arg2调用class方法,得出arg1和arg2都是NSString,并且直接拿到它们的值。
 
 
那要怎么用不定参数来保护App呢?
 
让我们把方法声明成这个样子:
- (void)decryptFileAt:(long long)arg1, ... NS_REQUIRES_NIL_TERMINATION;

这样攻击者在class-dump之后只能看见:
- (void)decryptFileAt:(long long)arg1;
 
 
那么我们要怎么拿到原来的参数呢?别急,下面就是具体实现。

- (void)decryptFileAt:(long long)arg1, ...
{
    /*!
     *  @brief  params数组用于保存参数
     */
    NSMutableArray *params = [[NSMutableArray alloc] init];
    va_list args;
    va_start(args, arg1);
    /*!
     *  @brief  强制将long long转为id类型
     *
     *  @return 第一个参数的值
     */
    id obj = reinterpret_cast<id>(arg1);
    /*!
     *  @brief  依次拿剩下的参数的值
     */
    while (obj != nil){
        [params addObject:obj];
        /*!
         *  @brief  va_arg的第二个参数是下一个不定参数的类型, 请根据实际情况处理
         *
         *  @param id   下一个不定参数的类型
         *
         *  @return 下一个不定参数
         */
        obj = va_arg(args, id);
    }
    /*!
     *  @brief  处理拿到的参数
     */
}

 
 
好的,那我们要怎么调用呢?
 

[[App alloc] decryptFileAt:reinterpret_cast<longlong>(@"/PATH/TO/FILE"), '!', "!important", @"PASSWORD", nil];

 
我们原本是需要2个参数就好的,现在怎么传了4个?

这是为了防止看出了这种手法的攻击者,现在他手上有4个参数,有两个是NSString,一个char和一个char *。如果他不作处理,直接addObject:到一个数组中的话,程序自然就crash了。

而我们自己拥有源代码,可以轻松的处理这些参数。当无用参数传得再多一点的时候,他就不得不去看汇编或者动态调试了,如果他看烦了的话,说不定就放弃了。在一定程度上可起到保护App的作用。

当然我们还可以改一下方法名,让它看上去与实际功能无关,更具有迷惑性,比如:

- (void)isOddNumber:(long long) arg1, ... NS_REQUIRES_NIL_TERMINATION;

但是如果你碰上了不搞出来不罢休的攻击者,那也没办法了,道高一尺,魔高一丈,有防必有攻,剩下的只是攻击者的时间和精力问题而已。

One thought on “巧用不定参数来保护App”

  1. 我觉得确实可以防住一部分class-dumper,但class-dumper的危害通常没那么大,所以防住这些人其实也没防住什么东西,但这个思路是极好的!

Leave a Reply

Your email address will not be published. Required fields are marked *

14 + twelve =