IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> cocos2d-js 手游解密jsc和http数据aes加密解密分析① -> 正文阅读

[网络协议]cocos2d-js 手游解密jsc和http数据aes加密解密分析①

分析流程

1.查看游戏引擎类型

2.安装游戏

3.抓包分析

4.ida分析so文件

5.获取密钥解密

6.分析解密后源码

7.验证分析结果


解密工具:jsc解密1.44.zip-其它文档类资源-CSDN下载cocos-jsc解密加密程序,需知道key,这些可以通过ida或Frida获取,支持最新更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/qq_21051503/70268217


?测试App:快乐鱼附_安卓和苹果.zip-其它文档类资源-CSDN下载快乐鱼附件更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/qq_21051503/70274213


下载好游戏这个游戏是cocos2d-js游戏,加密的文件是jsc后缀。

?安装上App抓包看看,打开游戏,就有可以请求包,获取游戏配置信息,但是数据加密了。

>>>>>>>>>>>>>>>>>>>那就开始干活 v_v

?

找到?\lib\arm64-v8a目录下的?libcocos2djs.so 文件,拉入ida分析

?找到?xxtea_decrypt 的ida位置是? 0x6FAED4

?

我用的是Frida hook?

frida -U com.yoyo.happyfish -l klby.js --no-pause

包名:com.yoyo.happyfish

获取jsc解密密钥

这里就获取到了jsc 的解密密钥了,剩下的就是解密jsc为js,分析js代码,看看数据怎么加密解密

?

hook代码 klby.js

    // Find base address 
    var baseAddr = Module.findBaseAddress('libcocos2djs.so');
    console.log('libcocos2djs.so baseAddr: ' + baseAddr);

    var xxtea_decrypt =  resolveAddress(0x6FAED4);//解密jsc
    Interceptor.attach(xxtea_decrypt, { 

        onEnter: function (args) {

                console.log('[+] Called xxtea_decrypt ' + xxtea_decrypt);
                console.log('[+] args0,r0: ' + args[0]);//data数据
                console.log('[+] args1,r1: ' + args[1]);//data长度
                console.log('[+] args2,r2: ' + args[2]);//密钥
                console.log('[+] args2,r3: ' + args[3]);//密钥长度

                dumpAddr('args0', args[0], 64);
                dumpAddr('args2', args[2], 64);
        },

        onLeave: function (retval) {
            console.log('[+] Returned from  xxtea_decrypt: ' + retval);
        }
    });

    function dumpAddr(info, addr, size) {
        if (addr.isNull())
            return;

        console.log('Data dump ' + info + ' :'+addr);
        var buf = addr.readByteArray(size);

        // If you want color magic, set ansi to true
        console.log(hexdump(buf, { offset: 0, length: size, header: true, ansi: false }));
    }

    function resolveAddress(addr) {
        var idaBase = 0x0; // Enter the base address of jvm.dll as seen in your favorite disassembler (here IDA)
        var offset = ptr(addr).sub(idaBase); // Calculate offset in memory from base address in IDA database
        var result = baseAddr.add(offset); // Add current memory base address to offset of function to monitor
        console.log('[+] New addr=' + result); // Write location of function in memory to console
        return result;
    }

开始解密jsc文件,这我用的傻瓜是解密方式,只要填写密钥就行了,一个软件自动搞定。

解密后的一个压缩包,打开压缩包把文件拖出来即可。?

?

?打开文件,搜索m-urlencoded;charset=utf-? 定位到发送Http 请求处。

发现是 aesEncryptString?数据加密,同时也发现了?HttpEncryptKey,那我们就把HttpEncryptKey 打印出来。

这我就偷懒一下,直接添加到http请求头里面,从抓包里就能看到密钥了。

选择新加密 ,把.js文件加密回jsc文件,替换原文件。?

效果图,得到aes加密的密钥了。

我顺便也打印了一下POST数据,Content-params: {"ChannelID":"0"}

?那我就去测试一下密钥是否正确,测试结果完全一致

?那我就去看看如何解密。

搜索 aesEncryptString 下面就是解密方法?aesDecryptString

?在搜索?aesDecryptString,找到http数据返回处,调用了aesDecryptString,解密数据密钥也是用的?t.Config.HttpEncryptKey,说明是和加密的一样。

?测试解密返回数据,也成功了,这样我们的第一步①就完成了。

解密部分js代码

var i = function() {
function t() {}
t.randomAesKeyBuffer = function() {
return n(16);
};
t.randomAesIvBuffer = function() {
return n(16);
};
t.stringToBuffer = function(t) {
for (var e = [], o = t.length, n = 0; n < o; n++) e[n] = t.charCodeAt(n);
return new Uint8Array(e);
};
t.bufferToString = function(t) {
for (var e = "", o = Array.from(t), n = 0, r = o.length; n < r; n++) e += String.fromCharCode(o[n]);
return e;
};
t.aesEncryptString = function(t, e) {
if (e.length > 0) {
var o = by.CryptoJS, n = o.enc.Utf8.parse(t), r = o.enc.Utf8.parse(e);
return by.CryptoJS.AES.encrypt(r, n, {
mode: o.mode.ECB,
padding: o.pad.Pkcs7
}).toString();
}
return "";
};
t.aesDecryptString = function(t, e) {
var o = by.CryptoJS, n = o.enc.Utf8.parse(t), r = o.AES.decrypt(e, n, {
mode: o.mode.ECB,
padding: o.pad.Pkcs7
});
return o.enc.Utf8.stringify(r).toString();
};
t.aesEncryptBuffer = function(t, e, o) {
var n = by.CryptoJS, i = n.lib.WordArray.create(t), a = n.lib.WordArray.create(e), s = n.lib.WordArray.create(o);
return r(n.AES.encrypt(s, i, {
iv: a,
mode: n.mode.CBC,
padding: n.pad.ZeroPadding
}).ciphertext);
};
t.aesDecryptBuffer = function(t, e, o) {
var n = by.CryptoJS, i = n.lib.WordArray.create(t), a = n.lib.WordArray.create(e), s = n.lib.WordArray.create(o), c = n.enc.Base64.stringify(s);
return r(n.AES.decrypt(c, i, {
iv: a,
mode: n.mode.CBC,
padding: n.pad.NoPadding
}));
};
t.rsaEncryptWithPublicKey = function(t) {
var e = by.forge.pki.publicKeyFromPem("-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEA3svz/3o/IBJGL3Lml5zH1jTpey+Z1fZraHF5dOj0FA1f8eJM7naE\ncO4tDuIgbICXfNW4Ln+hTi33EMzulpZpehigYFd9aPinJ6ynhNXE4BL/2NauYIRq\nvTy+72PtL4gswT0l0tWWbCX2yNco0G8J4fk92ZivuO+/osTtmYLMmNJ/hjPi4u86\njRtLkoSQ+6X55OJmLA1enWiu5hxDQQtue3Yw96Wo7fUJh8BnTBw7lTUwTHJhadoK\nt6mJqQfv0DnnHaOERkwxNgL/c6u04R2ruywyKrC5aaFRqZRrGA3zthUZS5K3/YLq\nU8tf+UBiBI1hEyroAWe8Q8/syBJ0cYOCOQIDAQAB\n-----END RSA PUBLIC KEY-----"), o = this.bufferToString(t), n = e.encrypt(o);
return this.stringToBuffer(n);
};
t.hex_md5 = function(t) {
var e = by.CryptoJS;
return e.MD5(t).toString(e.enc.Hex);
};
t.LogTag = "[CryptoTool]";
t.strEncryptKey = "thndwdhbqdyydsy5";
return t;
}();

?

>>>>彩蛋<<<<

细心的人可能已经发现,密钥是保存在 t.Config.HttpEncryptKey,Config关键字,说明是保存到某地方的,那就再挖一挖吧。

正好在assets 目录下找到一个GameConfig.config文件,

?打开文件发现是加密的

?那就在js文件里面找找看,有没有解密的密钥,搜索GameConfig.config

?

找到下面关键代码?aesDecryptString

cc.loader.load({ 
    url: e, 
    type: "text" }, 
    function(e, o) {
         //关键解密密钥 strEncryptKey 已找到是 thndwdhbqdyydsy5
        var n = i.CryptoTool.aesDecryptString(i.CryptoTool.strEncryptKey, o);
        r = JSON.parse(n);
        by.extend("by", "Config", r); 
});
t.loadConfig = function(t) {
if (void 0 == by.Config) {
var e = "";
if (cc.sys.isNative) e = cc.path.join(r.default.pkgInsideRootPath, "GameConfig.config"); else {
e = globalThis.location.origin + globalThis.location.pathname;
var o = globalThis.location.search, n = "TestChannel";
if ("" != o) {
var a = o.substr(1, o.length).split("&");
a && (n = a[0]);
}
e += n + ".config";
}
cc.loader.load({
url: e,
type: "text"
}, function(e, o) {
if (e) t(e); else {
var n = i.CryptoTool.aesDecryptString(i.CryptoTool.strEncryptKey, o), r = JSON.parse(n);
by.extend("by", "Config", r);
t && t(e, r);
}
});
} else t(void 0, by.Config);
};

?解密后的本地配置文件,里面有 HttpEncryptKey字段,和上面获取的相同。

本次只是分析了http层面的加密,本游戏还有一个websocket长连接,具体解密分析下次在写。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-26 22:36:04  更:2021-12-26 22:37:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 11:49:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码