MENU

vPilot加密配置项处理全解析

July 12, 2014 • 程序阅读设置

VATSIM的新连线客户端vPilot出来挺久了,我一直都没去看,Hans倒是当天就开始研究了。vPilot有一个问题,就是它是VATSIM-Only的设定,除了VATSIM的那一票服务器外其他的都不能连。在它的配置文件中,有一项是这样的:pZ9u441bE4a2NCGgqMxKNvwAIy0qEA+AwXB8c3sV90c=。它看起来是用Base64编码的字符串,但是使用Base64去解码没有效果。紧随其后的,是名为CachedServer的标签,但是它的值也和NetworkStatusURL是一样无法解码的。

我今天怀着必胜的信念尝试解决这个问题。因为没有什么顾虑,此处我将披露所有技术细节。在开始前,我可以先说明最初的思路是错误的,但是这不要紧,这些分析方法不一定不适用于所有情况。当然,也算一次有意义的尝试。

刚开始我的方案和Hans的方案是基本一致的:想办法去解开这个加密的字符串。之前我做过一个小范围使用的Bob89加解密算法(此处不透露细节),于是我在这里编写了几个小程序对其进行了如下处理:①将每个字符的ASCII加上/减去若干整数;②翻转字符串;③小范围解码测试。不幸的是,以上尝试均以失败告终。

我在想,是不是考虑的方向错了,我不应该从解密这个字符串入手,而是从已知的字符串入手进行加密还原。考虑这样的一个事实:服务器地址是通过网络获取的,否则不存在cache的问题。那么首先想到的应该是删掉CachedServer信息然后开上抓包程序启动vPilot进行信息的抓取。抓包过程还是很顺利的,有不少加密的信息无法获取,但是明文都能抓全。一条条分析,我找出了vPilot的API根:vpilotapi.metacraft.com。看上去是一个激动人心的成就,但是事实告诉我这里的API并不负责服务器地址的获取。茫忙数据包大海中苦苦搜寻,得来了一个有意义的包:正文部分包含了服务器信息。没错这就是我所需要的,我根据IP一层一层回溯上去,找到了本机与对方IP的第一次请求:域名是status.vatsim.net,资源是status.txt。接着往下面找,服务器信息来源于info.vroute.net/vatsim-servers.txt。而status.txt中是有vatsim-servers.txt的,显然status.txt是列表的来源。这样的分析是没错的,我想。但是再怎么尝试也不知道如何得到一个像那样加密了的字符串。

我不情愿地打开了ILSpy。我不想再次反编译vPilot,它被混淆了,分析它不仅痛苦,而且没什么意义。这次的反编译还是带来了一些好消息:在Metacraft.Vatsim.vPilot.Core命名空间中有一个vPilotConfig类,它有一个属性,名叫NetworkStatusURL。再往下看,有一些被混淆了的方法,但是值得庆幸的是属性名称没有被混淆,这真是令人高兴。有一个方法进入了我的视线:

// Metacraft.Vatsim.vPilot.Core.vPilotConfig
private void a()
{
    string a_ = this.c().ToString();
    string[] array = this.CachedServers.ToArray();
    this.CachedServers.Clear();
    string[] array2 = array;
    for (int i = 0; i < array2.Length; i++)
    {
        string a_2 = array2[i];
        this.CachedServers.Add(vPilotConfig.a(a_2, a_));
    }
    this.NetworkStatusURL = vPilotConfig.a(this.NetworkStatusURL, a_);
    try
    {
        this.NetworkPassword = vPilotConfig.a(this.NetworkPassword, a_);
    }
    catch (CryptographicException)
    {

    }
    catch (FormatException)
    {

    }
}

NetworkStatusUrl出现了!我们再来看看a方法的另一个重载:

// Metacraft.Vatsim.vPilot.Core.vPilotConfig
private static string a(string A_0, string A_1)
{
    UTF8Encoding uTF8Encoding = new UTF8Encoding();
    MD5CryptoServiceProvider mD5CryptoServiceProvider = new MD5CryptoServiceProvider();
    byte[] key = mD5CryptoServiceProvider.ComputeHash(uTF8Encoding.GetBytes(A_1));
    TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider();
    tripleDESCryptoServiceProvider.Key = key;
    tripleDESCryptoServiceProvider.Mode = CipherMode.ECB;
    tripleDESCryptoServiceProvider.Padding = PaddingMode.PKCS7;
    byte[] array = Convert.FromBase64String(A_0);
    byte[] bytes;
    try
    {
        ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateDecryptor();
        bytes = cryptoTransform.TransformFinalBlock(array, 0, array.Length);
    }
    finally
    {
        tripleDESCryptoServiceProvider.Clear();
        mD5CryptoServiceProvider.Clear();
    }
    return uTF8Encoding.GetString(bytes);
}

其中,a(void)里面的a_变量调用了c方法。c方法只有一条语句:return new Guid(1433775113u, 62174, 18974, 128, 139, 227, 57, 142, 23, 248, 191);。这样一来就好办了,这些部分完全可以拼在一起用以证实我的猜想。没错,http://status.vatsim.net/加密出来结果就是配置文件中所看到的pZ9u441bE4a2NCGgqMxKNvwAIy0qEA+AwXB8c3sV90c=了。

接下来的任务是什么,已经是十分明朗的:仅需自己做一个URL替换掉原来的,便可以自己定义服务器列表了。所以第一个任务是写个程序来加密URL。简要分析一下这里的加解密方法:基础算法是Triple DES,密钥是通过特定参数生成的Guid的MD5散列值。事实上之前的分析并没有出错,这个串的确是Base64编码的产物,只不过它的明文不是一个普通的字符串罢了。写个加密程序不费事,不用多久就能完成。

改完了NetworkStatusURL,要做的就是把对应的URL资源做好了。先在修改的URL目录里放一个status.txt文件,里面需要有一个行:url1={xxx.txt}。再建立一个对应的xxx.txt,其中按诸如ASIA:106.186.24.200:Tokyo, JAPAN:ASIA:1:的格式组织好服务器列表,然后启动vPilot即可。

如果你想连接大陆三大平台(A/F/S),请直接修改NetworkStatusURL6FXSmoBv/MERbMqqCvbTYeIgUd9gK+Aw,我已经制作好了。这样的服务器列表没有删减VATSIM服务器,仅是添加了三平台的服务器。此外,我写了一个小工具,它可以生成NetworkStatusURL,其中已打上了必要的提示。你可以通过它来创造自己需要的服务器列表。我没有对其混淆处理,想看看怎么实现的,直接反编译就好了。这里可以下载

Archives Tip
QR Code for this page
Tipping QR Code