本文为看雪论坛优秀文章
看雪论坛作者ID:零加一
00.抓包
其中的参数都是上一篇所见识到的。
00.0.印证
def DecodeData(Data,IsSend,ShowLog):
Len=0
index=0
Maxlen=len(Data)
b_msg=b''
Res=[]
while index<Maxlen:
ZmFlag=Data[index:index+2]
index+=6
Len=Data[index:index+4]
index+=4
Len=int().from_bytes(Len, byteorder='big', signed=True)
if index+Len<=Maxlen:
b_msg=Data[index:index+Len]
index+=Len
msg=msgpack.unpackb(b_msg,raw=False)
Res.append(msg)
if ShowLog:
print(msg)
Len=0
else:
break
return Res
01. 拆包
libtolua.so
libunity.so
当我满心欢喜使用Il2CppDumper对il2cpp进行提取后,啥有用信息都没得。此时fk游戏团队!
把il2cpp拉进ida加载Il2CppDumper给的签名(足足44mb),加载大概半个钟,啥有用信息都没得。再次fk游戏团队!
难道游戏逻辑靠lua?
在assets目录下有Lua_Android这么个文件夹引起了我的注意:
01.1 导出lua
首先清掉文件开头多出来的11个字节保存:
嚯,好家伙。看了一下,半喜半忧。
01.2 解密lua
密钥为:'m71'
.bss:036D6D18 StringLiteral_14090 % 4 ; DATA XREF: LuaEncryption$$Encrypt+5C↑o
.bss:036D6D18 ; LuaEncryption$$Encrypt+68↑o ...
.bss:036D6D18 ; m71
01.2.1 解密luac
但是解出来的是luac,还得用工具把他反编译成lua。
01.2.1 反编译luac
使用luajit-decompiler对解密的luac进行批量反编译。
下载地址:https://gitlab.com/znixian/luajit-decompiler
python ./main.py --recursive ./xy_luac --dir_out ./xy_lua_d --catch_asserts -e luac
完成后,大部分都能反编译成功。
02. 分析
通过加密的包里cr字符串的定位可以很幸运的找到了加密的地方:
local key = MISC_MGR.lst()
function lst()
return _last_sync_time
end
function sync_server_time(time)
_last_sync_time = tostring(time) .. "000000"
logger:info("SYNC server time %f", time)
_time_diff = time - UnityEngine.Time.realtimeSinceStartup
end
return function (rid, server_id, time, start_server_time)
logger:info("玩家(%s)登录成功,时间=%d", rid, time)
REMOTE_MGR.set_local_server_id(server_id)
MISC_MGR.sync_server_time(time)
MISC_MGR.set_start_server_time(start_server_time)
LTSDK_MGR.login_report()
AUTHSERVER_MGR.disconnect()
LTSDK_MGR.sync_last_request()
WINDOW_MGR.hide_wait()
['sync_server_time', [1614052775]]
msg = "cr" .. cry.encrypt(key, msg, 16, 1)
function encrypt(n, s, h, r, d)
assert(n ~= nil, "Empty password.")
assert(n ~= nil, "Empty data.")
local r = r or CBCMODE
local h = h or AES128
local l = {
string.byte(n, 1, #n)
}
local u = util.padByteString(s)
if r == ECBMODE then
return ciphermode.encryptString(l, u, ciphermode.encryptECB, d)
elseif r == CBCMODE then
return ciphermode.encryptString(l, u, ciphermode.encryptCBC, d)
elseif r == OFBMODE then
return ciphermode.encryptString(l, u, ciphermode.encryptOFB, d)
elseif r == CFBMODE then
return ciphermode.encryptString(l, u, ciphermode.encryptCFB, d)
elseif r == CTRMODE then
return ciphermode.encryptString(l, u, ciphermode.encryptCTR, d)
else
error("Unknown mode", 2)
end
end
AES128 = 16
AES192 = 24
AES256 = 32
ECBMODE = 1
CBCMODE = 2
OFBMODE = 3
CFBMODE = 4
CTRMODE = 4
aes = e(function (n, ...)
local s = util.putByte
local h = util.getByte
local r = "rounds"
local d = "type"
...
03. 筑基
看雪ID:零加一
https://bbs.pediy.com/user-home-749276.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!
本文始发于微信公众号(看雪学院):游戏协议大道-筑基篇
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论