最近在国外陷入了歌荒。
虽然一直用代理也没问题,但是还是想有更便捷的方式。于是想到了逆向。
最初发现在网易云音乐(以下简称云音乐)的请求头中加上 X-REAL-IP
并指向国内即可海外解锁,于是一直使用 nginx 反代实现。但是最近云音乐 API 有 https 化的倾向,以及维护服务器很麻烦,于是有了以下思路:
- 逆向云音乐 APP,找到 http 请求模块
- 统一加上 header
砸壳
由于 AppStore 上的 ipa 是加密过的,直接反编译得不到任何有价值的结果。
-
方法一
去下载砸过壳的 ipa。这个国内各大破解市场都有。 -
方法二
使用越狱的 iDevice 砸壳。-
Clutch
Clutch 是一个一键砸壳工具,适用于大部分应用的砸壳。但是在处理云音乐的二进制时会出现问题。为避免跑题,此处不深究,我们使用另一个工具。 -
dumpdecrypted
具体步骤见 这篇教程
-
Clutch
得到解密的二进制文件
总之,经过一系列的操作后,这时你应该有了解密的二进制文件。可以使用 otool
查看是否解密成功。
otool -l Payload/neteasemusic.app/neteaseMusic | grep crypt
将得到
cmd LC_ENCRYPTION_INFO_64
cmdsize 24
cryptoff 16384
cryptsize 20791296
cryptid 0
cryptid 0
即代表未加密。
应用重签名
越狱设备不需要
我决定先进行这一步。虽然这应该是最后一步,但要是不成功的话前面都白搭。
首先你需要:
- 开发者证书
- Provisioning 文件
将刚才得到的解密的 ipa 用 AppResign 重新签名
重新签名安装到设备中
ideviceinstaller -i netease-sign.ipa
在写这篇文章时,依然需要按照这个 Issue 解决无法安装的问题。
iPhone 7 在安装后会出现 Segmentation fault 的错误,但是应用已经装上。
结论就是:
使用开发者证书重签名 AppStore 的应用完全可行。
开始逆向
这里也有多种选择:
这里我选择 Hopper Disassembler。
打开二进制等待解析完毕后搜索 HttpRequest
我们注意到这个 NMHttpRequest
类很可能就是我们要找的。并且这里还有一个 setHeader
方法,接受一个参数,八九不离十了。
思路:
- 重写
NMHttpRequest
类的 init 方法 - 在其中调用
setHeader
加上我们要的 header
这样就能保证云音乐在初始化 API 请求的时候都会带上 X-REAL-IP
。
Method Swizzling
这里我们要利用到 Objective-C 的一个黑魔法 Method Swizzling
。
这篇文章 详细介绍了这个黑魔法。在这里我们只需要理解,我们将使用 Method Swizzling
来实现前面说到的“重写 NMHttpRequest
类的 init 方法”。
代码片段
+ (void)hookNeteaseMusic {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method originalMethod = class_getInstanceMethod(objc_getClass("NMHttpRequest"), @selector(initWithUrlString:));
Method swizzledMethod = class_getInstanceMethod([self class], @selector(hook_initWithUrlString:));
if(originalMethod && swizzledMethod) {
method_exchangeImplementations(originalMethod, swizzledMethod);
NSLog(@"Inject successful");
} else {
NSLog(@"Inject faild");
}
});
}
- (id *)hook_initWithUrlString:(id)url {
NSLog(@"=== hook_initWithUrlString === %@", url);
id* request = [self hook_initWithUrlString:url];
if (![url containsString:@"https"]) {
NSString* ip = [NSString stringWithFormat:@"47.93.50.%d", (arc4random() % 255) + 1];
NSDictionary* header = [[NSDictionary alloc] initWithObjectsAndKeys:ip, @"X-REAL-IP", nil];
[self setHeader:header];
[header release];
}
return request;
}
于是我们重写了 NMHttpRequest
的初始化方法,调用原初始化方法初始化了 request,再调用 setHeader
给 request 添加了 header,然后返回修改后的 request。
编译并打包
- 安装
iOSOpenDev
并在 Xcode 中新建一个 CaptainHook 项目。 - 导入上面的代码
- 编译生成动态链接库 dylib
- 使用yololib工具对对二进制文件进行dylib的注入
- 将 dylib 放到 neteasemusic.app 目录
- 使用 zip 打包 Payload 文件夹,修改扩展名为 ipa
- 重新签名并安装
这部分由于时间原因,暂时不详细写了,今后会补上。
测试
测试成功
我说了不算,大家自行测试。
总之以上提供了一种非越狱环境的应用 Tweak 思路,大家请自行发挥。
完整代码
网友评论