0x1 背景
本人是个小菜比不小心把DeveloperDiskImage.dmg直接解压到/目录下,因为版本不对且覆盖了SystemVersion.plist后导致系统不稳定VPN废了,越狱废了,系统频繁重启,所以想办法重新越狱,本人已经重新越狱修复好,所以没截到图演示。
0x2 一些信息
真实系统版本:9.3.3(13G34)
当前识别版本:9.3.1(13E238)
无论是手机设置里的信息还是连接到PC上用助手查看版本都是被修改之后的
0x3 分析
这个文件路径为/System/Library/CoreServices/SystemVersion.plist
大概内容是
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ProductBuildVersion</key>
<string>13G34</string>
<key>ProductCopyright</key>
<string>1983-2016 Apple Inc.</string>
<key>ProductName</key>
<string>iPhone OS</string>
<key>ProductVersion</key>
<string>9.3.3</string>
</dict>
</plist>
---------------------------------------------------------------------------------------------------------------
由于这个路径在AFC2无法开启的情况下是访问不到的,所以重新直接改文件不现实,所以我就去试试Patch盘古越狱。
把盘古越狱下下来解包丢IDA看看这货咋识别
分析完后直接搜系统版 然后CTRL+x查找引用
看到是硬编码
ProductVersion找到了我们接下来找ProductBuildVersion 搜下13G试试
也找到了但是他的是13G3不是13G34,小心点再看下现在13E
好像都是裁掉了一位不管了
回去找13G的引用自己对应自己的手机是几就几
气稽败坏,这是逼我直接Patch
我直接打开Hex把9.3.3改成了9.3.1 把9.3.3改成9.3.1,(CFSTRING一般需要改CFString里的Length,但是这里是相同的所以不用改)
同理把
ProductBuildVersion对应的字符串也改了(这是CSTRING没有结构我自己直接改了)
直接Patch后理论上 可行了 重签名后丢手机打开 嗯识别还是9.3.1但是理论上没问题了结果一点越狱重启了 越狱扑街,感觉是不是哪里体位不对
所以换个姿势不静态patch 直接HOOK API改这样不会漏
翻了下9.3.3的引用函数 可以看出他是通过 currentDevice获取SystemVersion
百度了下使用方法是
[
[UIDevice currentDevice]
systemVersion],先记录下来
问题来了
[UIDevice currentDevice]里没有
ProductBuildVersion的获取 也没找到
ProductBuildVersion引用函数咋办
同样也是在9.3.3的引用函数里我看到一串%s_%s_off_pg 这是格式化字符串
可是找那些参数没找到赋值F5出问题了在翻下 看到了个_CFCopySystemVersionDictionary()
这个是读SystemVersion.plist的API比currentDevice底层,直接HOOK他SetValue就能把
ProductVersion ,
ProductBuildVersion 给改了,mark下
0x4 写tweak
由于没越狱 不能用cydia substrate,所以改用fishhook
代码出自
jmpews 大腿 由于我没mac所以厚着脸皮求大腿帮忙
dalao也是很敬业的把两个东西一个Captain和fishHOOK都写了一遍
/*======= patch systemVersion with method swizzling =======*/
#import <CaptainHook/CaptainHook.h>
CHDeclareClass(UIDevice);
CHDeclareClass(NSString);
// template
CHConstructor {
CHLoadLateClass(NSString);
}
CHMethod(0, NSString *, UIDevice, systemVersion)
{
// NSString *realSystemVersion = CHSuper(0, UIDevice, systemVersion);
NSString *fakeSystemVersion=@"9.3.3";
return fakeSystemVersion;
}
__attribute__((constructor)) static void EntryCaptainHook()
{
NSLog(@"hello patch!");
CHLoadLateClass(UIDevice);
CHClassHook(0, UIDevice, systemVersion);
}
/*======= patch systemVersion with fishhook(GOT table hook) =======*/
#include <fishhook/fishhook.h>
#include <CoreFoundation/CoreFoundation.h>
#include <dlfcn.h>
#include <mach-o/dyld.h>
CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
CFDictionaryRef (*orig_CFCopySystemVersionDictionary)(void);
#define CONST_STRING_DECL(S, V) const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V);
CONST_STRING_DECL(_kCFSystemVersionBuildVersionKey, "ProductBuildVersion")
CONST_STRING_DECL(_FakeProductBuildVersion, "13G34")
CONST_STRING_DECL(_kCFSystemVersionProductVersionKey, "ProductVersion")
CONST_STRING_DECL(_FakeProductVersion, "9.3.3")
CFDictionaryRef fake_CFCopySystemVersionDictionary(void) {
CFDictionaryRef tmp_dict = orig_CFCopySystemVersionDictionary();
CFDictionarySetValue((CFMutableDictionaryRef)tmp_dict, _kCFSystemVersionBuildVersionKey, _FakeProductBuildVersion);
CFDictionarySetValue((CFMutableDictionaryRef)tmp_dict, _kCFSystemVersionProductVersionKey, _FakeProductVersion);
return tmp_dict;
}
__attribute__((constructor)) static void EntryFishHook()
{
intptr_t (*pub_dyld_get_image_slide)(const struct mach_header *mh);
pub_dyld_get_image_slide = dlsym((void *)dlopen(0, RTLD_LAZY), "_dyld_get_image_slide");
const struct mach_header *header = _dyld_get_image_header(0);
intptr_t slide = pub_dyld_get_image_slide(header);
rebind_symbols_image((void *)header, slide, (struct rebinding[1]){{"_CFCopySystemVersionDictionary", fake_CFCopySystemVersionDictionary, (void *)&orig_CFCopySystemVersionDictionary}}, 1);
}
编译成dylib先签名然后用yolib或者其他工具给
LoadCommands
插入加载节点然后重签名安装(切记先给dylib签名不然会闪退)
因为本人已测试成功所以就不截图了
安装后版本识别成了9.3.3
ProductBuildVersion没法看就暂时不管了先试试水
黑屏之后成功越狱赶紧去把
/System/Library/CoreServices/SystemVersion.plist里的信息该回去然后重启手机
重启手机会出现白屏(不是白苹果)然后下方出现一坨很难看到的滑动升级,这是由于版本号变更重启系统重新加载造成的,滑动升级等进度条完后会自动重启手机,此时打开手机一看版本变回9.3.3了,连接到PC的软件看也是9.3.3,下了一个没Patch版的盘古越狱依然也没问题。
附上tweak源码给大家自行玩耍,Patch后的包20多M就不上传了,再次感谢
jmpews大腿抽出时间帮我写tweak
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)