上文的结尾说过,游戏数据交互是靠另一套协议来传输的。那么本篇章则开始分析该游戏协议。
感谢wmsuper
通过抓包发现,包的可读性变差了。但看着像是序列化后的json。
其中的参数都是上一篇所见识到的。
前面说到,这些数据像是序列化后的json。印证了一下,确实如此。
前六个字节为包头,随后四字节表示长度。
当我以为这就修道结束的时候,发现后面发送的包居然无法正常解析,显然是加密了。
但发现每个加密的包都会有'cr'两个字符是不变的。经过一些简单的测试都无法解密,那么就直接对程序进行拆包分析了。
将apk解压后查看lib目录发现信息如下
libil2cpp.so
libtolua.so
libunity.so
C#+u3d+lua,经典游戏开发套路。
当我满心欢喜使用Il2CppDumper对il2cpp进行提取后,啥有用信息都没得。此时fk游戏团队!
把il2cpp拉进ida加载Il2CppDumper给的签名(足足44mb),加载大概半个钟,啥有用信息都没得。再次fk游戏团队!
难道游戏逻辑靠lua?
在assets目录下有Lua_Android这么个文件夹引起了我的注意
里面unity3d结尾的都是unity打包的文件,不过头部都多了11个字节出来。
首先清掉文件开头多出来的11个字节保存
然后用AssetStudio加载对应的文件夹32bit_out
嚯,好家伙。看了一下,半喜半忧。
经过一番寻找,终于在il2cpp.so里找到了lua解密的函数。但没想到这么简单!!!
密钥为:'m71'
但是解出来的是luac,还得用工具把他反编译成lua
使用luajit-decompiler对解密的luac进行批量反编译
下载地址:https://gitlab.com/znixian/luajit-decompiler
完成后,大部分都能反编译成功
抓包的时候我们说过,进入游戏后发送的包是加密的。那么我们现在要做的就是找到加密的地方看看算法
通过加密的包里cr字符串的定位可以很幸运的找到了加密的地方
首先是key的来源,看起来是一个时间戳+"000000"来生成的
都没有明确的值来源,服务端要想解密要么本地发送密钥或者服务端下发密钥,这时就得看看有没有什么可疑的数据包了
在顺着第一个被加密的包往上找,终于让我找到了一个相关的
反序列化后数据为:
接着是加密的算法,时间戳+6个0刚好16位,难道是aes?
应该不会是魔改的aes吧?
经过测试,标准的aes_ecb加密。
最终展示如下,登录成功把已登录的挤掉线!
多的不敢写,怕封号。
筑基失败,当场飞升了。
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
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
.bss:
036D6D18
StringLiteral_14090
%
4
; DATA XREF: LuaEncryption$$Encrypt
+
5C
↑o
.bss:
036D6D18
; LuaEncryption$$Encrypt
+
68
↑o ...
.bss:
036D6D18
; m71
.bss:
036D6D18
StringLiteral_14090
%
4
; DATA XREF: LuaEncryption$$Encrypt
+
5C
↑o
.bss:
036D6D18
; LuaEncryption$$Encrypt
+
68
↑o ...
.bss:
036D6D18
; m71
python .
/
main.py
-
-
recursive .
/
xy_luac
-
-
dir_out .
/
xy_lua_d
-
-
catch_asserts
-
e luac
python .
/
main.py
-
-
recursive .
/
xy_luac
-
-
dir_out .
/
xy_lua_d
-
-
catch_asserts
-
e luac
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()
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
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-2-23 16:17
被零加一编辑
,原因: