好友
阅读权限25
听众
最后登录1970-1-1
|
本帖最后由 ss22219 于 2018-3-5 16:46 编辑
上一章分析了b站登陆部分的逻辑,注册的请求也是一样的,有关代码可以在章节末尾链接中下载
登陆成功后会拿到一个access_key,可以在fiddler请求列表中找到:
{"requestId":"a4d431600fbf11e8acf4522233028424","timestamp":"1518417641334","code":0,"access_key":"cc7d0f9d40d06d010c0cc600c8d9f8be","uid":289451430}
点击游戏画面,让游戏登陆进去
查看Fiddler窗口,看见以下请求,最值得注意的就是developmentAuthCode
https://line3-s1-bili-fate.bilib ... ntomembercenter.php
access_token就是上面的access_key
现在我们要分析两个方向,一个是返回值的解码过程,一个是developmentAuthCode的生成过程
我们先来分析developmentAuthCode,直接在vs中搜索DevelopmentAuthCode
看到是一个常量,所以这个值是固定的,不需要解析
然后是返回内容的解析,返回内容是base64,直接以base64解码:
{"response":[{"resCode":"00","success":{"rguid":"30172359","rgusk":"498455f3582d89722601","rgtype":1,"dateVer":1518379200,"dataVer":163},"fail":{},"nid":"login_to_membercenter","usk":"498455f3582d89722601"}],"cache":{"updated":{},"replaced":{},"serverTime":1518417642}}
并没有加密内容
这里值得注意的就是"rguid","rgusk","usk"三个返回值
搜索logintomembercenter,因为链接就是这个,直接搜索这个名字效果最好
发现有一个类叫LoginToMemberCenterRequest,右击查看所有引用
发现有许多引用,因为我们是b站登陆后执行的,所以优先看BLGameSdk和BSCallbackListerner这两个类的引用
我这里看得是BSCallbackListerner,可以看到添入了很多请求参数,找找回调函数
LoginToMemberCenterRequest 类中有个requestCompleted方法
可以看到是直接把这三个值保存到全局PlayerPrefs中,相当于全局变量一样
[C#] 纯文本查看 复制代码 PlayerPrefs.SetString("rguid", success["rguid"].ToString());
PlayerPrefs.SetString("usk", responseData.usk);
PlayerPrefs.SetString("rgusk", success["rgusk"].ToString());
既然有SetString,肯定就有GetString
F12 SetString进去看见这个类果然有GetString方法
右击查看引用
发现NetworkManager的RequestLogin有使用到这个函数,这里最可疑
[C#] 纯文本查看 复制代码 request.addField("rguid", PlayerPrefs.GetString("rguid"));
request.addField("rgusk", PlayerPrefs.GetString("usk"));
NetworkManager的ReplaceBaseField也有用到
[C#] 纯文本查看 复制代码 PlayerPrefs.GetString("usk");
再查查找SetString("usk" 有什么地方使用了
rguid,rgusk只有一处调用
usk有3个地方使用到,猜测这个usk会一直改变
继续查看请求,下一条地址是
https://line3-s1-bili-fate.bilib ... e/60_1001/login.php
这个请求返回的依然是一个base64内容
看一下他的请求rgsid是固定值
rguid rgusk是上面 LoginToMemberCenter 请求返回的内容,其他参数有个lastAccessTime,这个是当前时间,t是个固定值
看看他返回内容是什么
可以看到这个json对象
response[0]{resCode: "00", success: {…}, fail: {…}, nid: "", usk: "754246b3a54e9009f8be"}
返回了一个usk数据,然后这个usk数据会 PlayerPrefs.SetString("usk", responseData.usk);
这个就很清晰了,再看看下一个请求
这个请求有个ac=action name=signuptop,意思是说请求名称叫signuptop?
有一个usk的请求参数,这个参数跟我们刚刚获取到的不一样,很明显,这个是服务器校验参数了
查看usk是如果生成的,猜测是根据服务器上一次返回的usk生成的,搜索所有的"usk"
找到这个代码
[C#] 纯文本查看 复制代码 string [url=home.php?mod=space&uid=452487]@String[/url] = PlayerPrefs.GetString("usk");
string data = CryptData.EncryptMD5Usk(@string);
request.replaceField("usk", data);
public static string EncryptMD5Usk(string usk)
{
string decryptFunnyKey = CryptData.GetDecryptFunnyKey();
string str = decryptFunnyKey + usk;
return CryptData.EncryptMD5(str);
}
这个就是usk的生成函数了,根据服务器返回的usk,加上funnyKey,然后EncryptMD5
EncryptMD5就是一个md5函数,主要是这个FunnyKey
[C#] 纯文本查看 复制代码 public static string GetDecryptFunnyKey()
{
string str = "+eTq/PgKHhpvmMWboN+Flb3okskn3SD325tVSqPf5nCjqAtdR6BN7Q==";
return CryptData.FunnyKeyDecrypt(str);
}
好家伙,还有一层
我尝试在C# Interactive窗口直接获取这个值
视图->其他窗口->C# Interactive
运行结果是 F02C093101C3E4F5813E46605842B74A
继续拿这个跟上面返回的usk运算:
MD5("F02C093101C3E4F5813E46605842B74A" + "754246b3a54e9009f8be")
0ad09c7453763ae3ee7f113110e84840
与上面的完全一致,那么之后的usk都是这么生成了
整个过程
1.b站登陆拿到access_key,填入到LoginToMemberCenter请求中的access_token
base64解码返回内容 获取到"rguid","rgusk","usk"三个返回值
2."rguid","rgusk"填入到rongame_beta/rgfate/60_1001/login.php请求中
base64解码返回内容 获取到usk
3.EncryptMD5Usk(usk) 填入usk 请求ac.php系列接口,这个接口都是ac=action&name=xxxx,每次都会返回一个usk
base64解码返回内容 获取到usk
利用上一次服务器返回的usk来生成下一个usk,即可完成服务器验证
========================================================
至此,关于FGO的游戏请求加密分析已经完成
往下我不知道讲什么内容好了,有两个想说的
一个是战斗数据的分析与修改
另外一个是fgo的解包
大家觉得哪个比较好,如果没什么疑问,这个系列就可能就此结束了
有关操作代码可以在我之前发表的FGO管理系统内找到
https://www.52pojie.cn/thread-686596-1-1.html
下一章:
https://www.52pojie.cn/thread-698928-1-1.html
上一章:
https://www.52pojie.cn/thread-698513-1-1.html |
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|