网易云音乐海外解锁

最近在国外陷入了歌荒。

虽然一直用代理也没问题,但是还是想有更便捷的方式。于是想到了逆向。
最初发现在网易云音乐(以下简称云音乐)的请求头中加上 X-REAL-IP 并指向国内即可海外解锁,于是一直使用 nginx 反代实现。但是最近云音乐 API 有 https 化的倾向,以及维护服务器很麻烦,于是有了以下思路:

  • 逆向云音乐 APP,找到 http 请求模块
  • 统一加上 header

砸壳

由于 AppStore 上的 ipa 是加密过的,直接反编译得不到任何有价值的结果。

  • 方法一
    去下载砸过壳的 ipa。这个国内各大破解市场都有。

  • 方法二
    使用越狱的 iDevice 砸壳。

    • Clutch
      Clutch 是一个一键砸壳工具,适用于大部分应用的砸壳。但是在处理云音乐的二进制时会出现问题。为避免跑题,此处不深究,我们使用另一个工具。
    • dumpdecrypted
      具体步骤见 这篇教程

得到解密的二进制文件

总之,经过一系列的操作后,这时你应该有了解密的二进制文件。可以使用 otool 查看是否解密成功。

 otool -l Payload/neteasemusic.app/neteaseMusic | grep crypt

将得到

          cmd LC_ENCRYPTION_INFO_64
      cmdsize 24
     cryptoff 16384
    cryptsize 20791296
      cryptid 0

cryptid 0 即代表未加密。

应用重签名

越狱设备不需要

我决定先进行这一步。虽然这应该是最后一步,但要是不成功的话前面都白搭。

首先你需要:

  1. 开发者证书
  2. Provisioning 文件

这里使用 这个教程 中提到的 AppResign

将刚才得到的解密的 ipa 用 AppResign 重新签名

网易云音乐海外解锁_第1张图片
重新签名

安装到设备中

ideviceinstaller -i netease-sign.ipa

在写这篇文章时,依然需要按照这个 Issue 解决无法安装的问题。

iPhone 7 在安装后会出现 Segmentation fault 的错误,但是应用已经装上。

结论就是:
使用开发者证书重签名 AppStore 的应用完全可行。

开始逆向

这里也有多种选择:

  • class-dump
  • Hopper Disassembler
  • 等等

这里我选择 Hopper Disassembler。
打开二进制等待解析完毕后搜索 HttpRequest

网易云音乐海外解锁_第2张图片
搜索 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 思路,大家请自行发挥。
完整代码

你可能感兴趣的:(网易云音乐海外解锁)