Обнаружение подмены UDID на iPhone во время выполнения
джейлбрейк айфоны действуют мне на нервы, поскольку он портит некоторые фундаментальные API на iOS, используя MobileSubstrate.
http://www.iphonedevwiki.net/index.php/MobileSubstrate
Я считаю, что многие приложения используют UDID в качестве средства аутентификации устройства и / или пользователя, поскольку он полуавтоматический и удобный, но вы должны знать об этой проблеме: UIDevice не так защищен от взлома, как должно быть. Существует приложение под названием 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];
}
Как вы можете видеть, метод uniqueIdentifier в классе UIDevice теперь возвращает fakeUDID для любых приложений.
Кажется, что Skype и некоторые другие приложения обнаруживают этот вид порчи, но я не знаю, как это сделать.
то, что я хотел сделать, это: когда зараженный UIDevice обнаружен при запуске, предупреждение и выход(0).
идеи?
2 ответов
нет действительно безопасного способа проверить, является ли UDID реальным. UDID получает через liblockdown, который связывается с lockdownd через безопасный канал для получения UDID:
+-----------+
| your code |
+-----------+
|
+----------+ +-------------+ +-----------+
| UIDevice |<----->| liblockdown |<=====>| lockdownd | (trusted data)
+----------+ +-------------+ +-----------+
untrusted user trusted user
когда устройство взломано, все 4 компонента могут быть заменены.
один из методов обнаружения присутствия UDID Faker-это проверка некоторых идентификаций (файлов, функций и т. д.) уникальный для него существует. Это очень специфическая и хрупкая контратака, как при методе обнаружения подвергается, подделка может просто изменить идентификацию, чтобы скрыть их существование.
например, 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;
конечно, обманщик может просто переименовать эти вещи.
более надежный метод заключается в том, как мобильная подложка завод. Введенный код должен быть расположен в dylib / bundle, который загружается в область памяти разные от программирования с использованием UIKit. Поэтому вам просто нужно проверить, является ли указатель функции -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-это очень высокий уровень взлома (т. е. его можно легко избежать). Он захватывает связь между UIDevice и liblockdown, предоставляя поддельный идентификатор.
+-----------+
| your code |
+-----------+
|
+----------+ +-------------+ +-----------+
| UIDevice |<--. | liblockdown |<=====>| lockdownd | (trusted data)
+----------+ | +-------------+ +-----------+
| +------------+
‘-->| UDID Faker |
+------------+
таким образом, вы можете переместить код запрос UDID ниже уровня liblockdown. Это можно использовать для приложений для взломанных платформ, но это невозможно для приложений AppStore, потому что liblockdown-это частный API. Кроме того, spoofer может захватить liblockdown (это очень легко, я надеюсь, что никто этого не сделает) или даже заменить lockdownd.
+-----------+
| your code |
+-----------+
|
+----------+ +-------------+ +-----------+
| UIDevice |<--. | liblockdown |<=====>| lockdownd | (trusted data)
+----------+ | +-------------+ +-----------+
| +------------+
‘-->| UDID Faker |
+------------+
(Я не собираюсь показывать, как использовать liblockdown здесь. Вы должны иметь возможность найти достаточную информацию с сайта, на который вы ссылаетесь.)