21

ジェイルブレイクされた iPhone は、MobileSubstrate を使用することで、iOS のいくつかの基本的な API を汚染するので、私の神経質になります。

http://www.iphonedevwiki.net/index.php/MobileSubstrate

UDID は半自動で便利なので、多くのアプリがデバイスやユーザーを認証する手段として使用していると思いますが、この問題に注意する必要があります。UDID Faker というアプリがあり、実行時に他人の UDID を簡単に偽装できます。

http://www.iphone-network.net/how-to-fake-udid-on-ios-4/

そのソースコードは次のとおりです。

//
//  UDIDFaker.m
//  UDIDFaker
//

#include "substrate.h"

#define ALog(...) NSLog(@"*** udidfaker: %@", [NSString stringWithFormat:__VA_ARGS__]);
#define kConfigPath @"/var/mobile/Library/Preferences/com.Reilly.UDIDFaker.plist"

@protocol Hook
- (NSString *)orig_uniqueIdentifier;
@end

NSString *fakeUDID = nil;

static NSString *$UIDevice$uniqueIdentifier(UIDevice<Hook> *self, SEL sel) {  

    if(fakeUDID != nil) {
                 ALog(@"fakeUDID %@", fakeUDID);
        /* if it's a set value, make sure it's sane, and return it; else return the default one */
                return ([fakeUDID length] == 40) ? fakeUDID : [self orig_uniqueIdentifier];

    }
    /* ... if it doesn't then return the original UDID */
    else {
        return [self orig_uniqueIdentifier];
    }
}

__attribute__((constructor)) static void udidfakerInitialize() {  

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        NSString *appsBundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
        ALog(@"Loading UDID Faker into %@", appsBundleIdentifier);


        NSDictionary *config = [NSDictionary dictionaryWithContentsOfFile: kConfigPath];
        fakeUDID = [config objectForKey: appsBundleIdentifier];
        [fakeUDID retain];

        if(fakeUDID != nil) {

                ALog(@"Hooking UDID Faker into %@", appsBundleIdentifier);
                MSHookMessage(objc_getClass("UIDevice"), @selector(uniqueIdentifier), (IMP)&$UIDevice$uniqueIdentifier, "orig_");
        }

    [pool release];
}

ご覧のとおり、UIDevice クラスの uniqueIdentifier メソッドは、すべてのアプリで fakeUDID を返すようになりました。

Skype やその他のアプリがこの種の汚染を検出しているようですが、その方法がわかりません。

私がやりたかったのは、起動時に汚染された UIDevice が検出された場合、警告して終了します(0)。

アイデア?

4

2 に答える 2

35

UDID が本物かどうかを確認する本当に安全な方法はありません。UDID は liblockdown を介して取得されます。liblockdown は、安全なチャネルを介して lockdownd と通信し、UDID を受信します。

+-----------+
| your code |
+-----------+
      |
+----------+       +-------------+       +-----------+
| UIDevice |<----->| liblockdown |<=====>| lockdownd |   (trusted data)
+----------+       +-------------+       +-----------+
         untrusted user                   trusted user

デバイスがジェイルブレイクされると、4 つのコンポーネントすべてを置き換えることができます。


UDID Faker の存在を検出する 1 つの方法は、それに固有の ID (ファイル、関数など) が存在するかどうかを確認することです。これは非常に具体的で脆弱な反撃です。検出方法が公開されると、スプーファーは ID を変更して存在を隠すことができるからです。

たとえば、UDID Faker は plist ファイルに依存しています/var/mobile/Library/Preferences/com.Reilly.UDIDFaker.plist。したがって、このファイルが存在するかどうかを確認できます。

NSString* fakerPrefPath = @"/var/mobile/Library/Preferences/com.Reilly.UDIDFaker.plist";
if ([[NSFileManager defaultManager] fileExistsAtPath:fakerPrefPath])) {
   // UDID faker exists, tell user the uninstall etc.
}

-[UIDevice orig_uniqueIdentifier]また、フェイカーをバイパスするために使用できるメソッドも定義します。

UIDevice* device = [UIDevice currentDevice];
if ([device respondsToSelector:@selector(orig_uniqueIdentifier)])
   return [device orig_uniqueIdentifier];
else
   return device.uniqueIdentifier;

もちろん、スプーファーは単にこれらの名前を変更することもできます。


より信頼性の高い方法は、Mobile Substrate の仕組みにあります。挿入されたコードは、UIKit とは異なるメモリ領域にロードされる dylib/bundle に配置する必要があります。したがって、-uniqueIdentifierメソッドの関数ポインタが許容範囲内にあるかどうかを確認するだけです。

// get range of code defined in UIKit 
uint32_t count = _dyld_image_count();
void* uikit_loc = 0;
for (uint32_t i = 0; i < count; ++ i) {
   if (!strcmp(_dyld_get_image_name(i), "/System/Library/Frameworks/UIKit.framework/UIKit")) {
     uikit_loc = _dyld_get_image_header(i);
     break;
   }
}

....

IMP funcptr = [UIDevice instanceMethodForSelector:@selector(uniqueIdentifier)];
if (funcptr < uikit_loc) {
   // tainted function
}

とにかく、UDID Faker は非常に高レベルのハックです (つまり、簡単に回避できます)。偽の ID を提供することで、UIDevice と liblockdown の間のリンクをハイジャックします。

+-----------+
| your code |
+-----------+
      |
+----------+       +-------------+       +-----------+
| UIDevice |<--.   | liblockdown |<=====>| lockdownd |   (trusted data)
+----------+   |   +-------------+       +-----------+
               |   +------------+
               ‘-->| UDID Faker |
                   +------------+

したがって、UDID を要求するコードを liblockdown レベルに移動できます。これは、ジェイルブレイクされたプラットフォーム用のアプリには使用できますが、liblockdown はプライベート API であるため、AppStore アプリには使用できません。その上、スプーファーは liblockdown をハイジャックする可能性があり (非常に簡単です。誰もやらないことを願っています)、lockdownd 自体を置き換えることさえできます。

                   +-----------+
                   | your code |
                   +-----------+
                         |
+----------+       +-------------+       +-----------+
| UIDevice |<--.   | liblockdown |<=====>| lockdownd |   (trusted data)
+----------+   |   +-------------+       +-----------+
               |   +------------+
               ‘-->| UDID Faker |
                   +------------+

(ここでは liblockdown の使用方法を示すつもりはありません。リンク先のサイトから十分な情報を見つけることができるはずです。)

于 2010-11-13T20:40:46.990 に答える
-3

重要なのは、JBデバイスを検出し、そのデバイスで実行されていないことです。

于 2012-09-05T10:24:14.220 に答える