首页
社区
课程
招聘
未解决 [求助]对游戏类安卓进行逆向 500.00雪花
发表于: 2023-8-18 21:31 6918

未解决 [求助]对游戏类安卓进行逆向 500.00雪花

2023-8-18 21:31
6918

各位大佬,由于工作需要,近期接触了很多APP,他们的特点是:

  1. 在安卓设备内部启动代理服务器,(每次IP和端口都不一样)
  2. 调用网络请求,是通过上面的代理走的请求(UDP?) 总之无法使用burpsuite抓包

这里有个例子; 816K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6A6L8h3M7J5i4K6u0W2P5s2q4B7K9h3q4K6N6g2)9J5k6h3y4G2L8g2)9J5c8X3E0H3L8q4)9J5c8Y4S2A6j5g2)9J5c8X3q4H3K9#2)9J5c8V1N6S2L8h3g2Q4y4h3j5J5x3o6M7&6x3g2)9#2k6U0b7I4y4o6l9#2y4q4)9J5k6h3q4H3K9H3`.`.

我在逆向过程中,找到相关文章: 10aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2%4j5h3&6Y4j5h3&6Q4x3X3g2U0L8$3#2Q4x3V1k6H3i4K6u0r3y4$3k6&6y4K6b7%4x3o6g2T1j5K6j5I4z5o6N6X3j5R3`.`. ( frida内存检索svc指令查找sendto和recvfrom进行hook抓包 )

但是由于时间有限,一直没能搞定。

所以请好心师傅帮我指点一下,能:

  1. 教会我如何对这个app进行逆向。
  2. 本次这个app帮我获得远程请求的接口。

Orz 感激不尽。
新人首次发帖,不当之处我立刻改正!


[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!

最后于 2023-8-18 21:33 被mb_pbluixcu编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 3054
活跃值: (6837)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2

这种想抓包就安装个虚拟机然后在虚拟机里装抓包工具的证书(提前转换成安卓支持的格),在把apk安装到虚拟机里,抓包工具打开忽略CONNECT的包。就能抓包了. 在应用层面做得再好也没法确保他的上层设备没问题,你也可以把应用安装在任何一台手机然后在网关设备上安装抓包的证书之后在网关上开代理抓包。


这游戏是基于网狐精华版二次开发的你可以去网上找源码资源分析, 我不发下载链接你自己去谷歌找多的很 什么皇城、宝博、顺金、彩虹堂、彩虹城、九州、宝鑫、发条II、传奇、招财、梦幻、万利等棋牌都是一样的代码改的。去找个lua解密的看看源码是咋写的。


获取网络接口指的是?URL?那你可以反编译luac文件在里头找。

这类游戏的引擎是开源的,想抓数据包的内容的话可以配合着cocos2d的源码去hook对应的函数获取或写入数据。而cocos2d-lua里常用luasocket通信你可以去hook这个函数去获取或写入游戏与服务器的通信数据。游戏外的可以hook Java层的函数获取或写入数据。


1d3K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2B7K9h3q4F1M7$3S2#2i4K6u0W2j5$3!0E0i4K6u0r3M7q4)9J5c8U0M7^5x3h3b7^5x3K6g2U0z5o6S2U0z5b7`.`.   Cocos2d-lua工程运行流程的理解

f6bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6B7N6h3g2B7K9h3&6Q4x3X3g2U0L8W2)9J5c8Y4m8G2M7%4c8Q4x3V1j5%4x3e0j5J5y4e0p5I4y4U0x3$3x3o6V1H3x3o6j5H3z5o6p5K6   cocos2d-x lua-binding:将lua-binding结果引入到项目中使用

9f7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8X3#2&6k6s2u0W2j5h3#2J5k6h3#2A6L8X3c8E0k6g2)9J5c8X3q4J5N6r3W2U0L8r3g2Q4x3V1k6V1k6i4c8S2K9h3I4K6i4K6u0r3y4o6M7%4x3o6M7&6z5o6V1`.   cocos2d lua绑定感悟---像cc.Sprite,cc.Director这些是如何识别的

020K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8V1u0&6b7h3I4A6j5$3E0Q4x3V1k6S2M7Y4c8A6j5$3I4W2i4K6u0r3k6r3g2@1j5h3W2D9M7#2)9J5c8U0R3I4x3e0f1K6z5o6t1H3   Cocos2dx中lua实现与java交互(异步线程间的数据同步)

根据这几篇文章找到lua绑定的具体函数然后hook 就能获取或写入服务器的通信数据了。


lua绑定的Socket通信源码, 玩游戏时于游戏服务器通信通常会用这个

6d7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3y4G2M7K6u0V1i4K6u0r3j5$3!0U0L8%4x3J5k6q4)9J5k6s2S2Q4x3V1k6T1L8r3!0T1i4K6u0r3y4K6j5&6x3o6y4V1k6h3f1$3y4o6l9@1y4X3x3%4j5X3k6V1j5X3p5#2x3o6M7&6x3r3u0W2x3U0R3K6y4o6R3@1j5U0c8T1k6e0t1%4x3g2)9J5c8X3y4G2j5$3!0K6i4K6u0r3M7$3y4J5K9i4m8@1K9h3&6Y4i4K6u0r3L8s2g2S2i4K6u0V1j5X3W2F1k6r3W2F1k6%4y4Q4x3V1k6E0j5h3&6#2j5h3I4Q4x3V1k6F1k6i4c8%4L8%4u0C8i4K6u0r3e0s2g2S2i4K6g2X3N6$3g2T1i4K6g2X3M7$3!0U0K9$3g2@1i4K6u0W2j5%4m8H3


比如你要在玩游戏时抓游戏客户端与服务器的通信数据就可以

//函数定义 void LuaWebSocket::onMessage(WebSocket* ws, const WebSocket::Data& data)


// 这种方式可以精确的hook某个函数但需要自行查找函数调用地址,动态调试需要自行查找偏移地址。

// 用 nm -DC libcocos2dlua.so | grep -i LuaWebSocket::onMessage 可以找到so内静态的调用地址。

//var func = Module.findBaseAddress("libcocos2dlua.so").add(0x8244b4);


//  当函数是全局唯一时可以用这种方式,如果存在多个函数名则hook无效。

var func = Module.findExportByName("libcocos2dlua.so" , "LuaWebSocket::onMessage");

var Log = Java.use("android.util.Log");

Interceptor.attach(func, {

  onEnter: function (args) {

    // 在不知道数据类型前先这样看看hook后是否有数据,有数据再用对应数据类型的读函数或转换函数。数据类型不对会导致hook失败。

    Log.e("frida-HOOK", "ws:"+args[1]);

    Log.e("frida-HOOK", "data:"+args[2]);

  }

});


lua绑定的XMLHttpRequest通信源码,游戏内需要HTTP通信会用到这个

e52K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3y4G2M7K6u0V1i4K6u0r3j5$3!0U0L8%4x3J5k6q4)9J5k6s2S2Q4x3V1k6T1L8r3!0T1i4K6u0r3y4K6j5&6x3o6y4V1k6h3f1$3y4o6l9@1y4X3x3%4j5X3k6V1j5X3p5#2x3o6M7&6x3r3u0W2x3U0R3K6y4o6R3@1j5U0c8T1k6e0t1%4x3g2)9J5c8X3y4G2j5$3!0K6i4K6u0r3M7$3y4J5K9i4m8@1K9h3&6Y4i4K6u0r3L8s2g2S2i4K6u0V1j5X3W2F1k6r3W2F1k6%4y4Q4x3V1k6E0j5h3&6#2j5h3I4Q4x3V1k6F1k6i4c8%4L8%4u0C8i4K6u0r3L8s2g2S2i4K6g2X3P5r3#2D9i4K6g2X3K9s2c8@1M7q4)9#2k6Y4u0W2M7i4g2W2M7%4c8Q4x3X3g2U0M7s2l9`. 


lua绑定的Downloader源码, 游戏内要下载啥文件都会用到这个

52cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3y4G2M7K6u0V1i4K6u0r3j5$3!0U0L8%4x3J5k6q4)9J5k6s2S2Q4x3V1k6T1L8r3!0T1i4K6u0r3y4K6j5&6x3o6y4V1k6h3f1$3y4o6l9@1y4X3x3%4j5X3k6V1j5X3p5#2x3o6M7&6x3r3u0W2x3U0R3K6y4o6R3@1j5U0c8T1k6e0t1%4x3g2)9J5c8X3y4G2j5$3!0K6i4K6u0r3M7$3y4J5K9i4m8@1K9h3&6Y4i4K6u0r3L8s2g2S2i4K6u0V1j5X3W2F1k6r3W2F1k6%4y4Q4x3V1k6E0j5h3&6#2j5h3I4Q4x3V1k6F1k6i4c8%4L8%4u0C8i4K6u0r3L8s2g2S2i4K6g2X3k6r3!0%4L8X3I4G2j5h3c8W2M7W2)9J5k6h3y4H3M7l9`.`. 


519K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8X3k6J5k6h3g2C8K9h3&6Y4x3e0l9I4i4K6u0r3j5i4u0@1K9h3y4D9k6g2)9J5c8X3c8W2N6r3q4A6L8s2y4Q4x3V1j5I4x3o6V1J5x3e0x3K6z5o6x3`.   FRIDA - API使用篇:rpc、Process、Module、Memory 使用方法及示例



Frida抓包逆向方面你可以去看看这本书 安卓Frida逆向与协议分析 (陈佳林) 和 安卓Frida逆向与抓包实战 (陈佳林)


这游戏解密用的

key是:ShengRiKuaiLe  

sign是:elegate_setHttp


脱壳后的dex在附件classes.dex


脱壳修复加集成frida在附件分卷压缩 Game_20791_414054_frida.zip Game_20791_414054_frida.z01 Game_20791_414054_frida.z02


集成frida用到26eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6F1M7%4A6V1K9r3b7I4i4K6u0r3g2i4c8A6L8q4y4U0M7X3W2H3N6q4!0q4y4q4!0n7b7W2)9&6x3#2!0q4y4g2!0n7b7g2)9&6x3#2!0q4y4#2)9&6b7g2)9^5y4p5I4u0c8f1k6u0L8X3A6W2j5%4c8r3M7X3W2V1j5g2)9J5k6i4m8&6i4@1g2r3i4@1u0o6i4K6S2o6i4@1f1@1i4@1u0p5i4@1u0r3i4@1f1%4i4K6V1@1i4@1p5^5i4@1f1$3i4K6V1$3i4@1t1&6i4@1f1#2i4@1u0o6i4K6S2r3i4@1f1%4i4K6W2o6i4K6S2n7i4@1f1@1i4@1u0p5i4K6W2o6i4@1f1^5i4K6R3H3i4K6R3#2i4@1f1^5i4@1q4r3i4@1t1@1i4@1f1$3i4K6V1^5i4K6S2q4


已解密的luac在附件luac.zip

已反编译的lua在附件lua.zip


反编译用的是 c3cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6p5M7W2)9J5k6p5#2f1e0W2)9J5c8X3I4#2j5h3A6A6N6q4)9J5k6r3c8W2j5$3!0E0M7r3W2D9k6i4t1`. 

批量反编译用到的bash脚本

for i in `find declua -name "*.luac"`;do

dn=`dirname $i`

fn=`basename -s .luac $i`

mkdir -p ./out/$dn

python main.py $i >./out/$dn/$fn.lua

done



Dump lua文件的frida脚本, 脚本文件放置路径为/data/local/tmp/frida_script.js


var func = Module.findBaseAddress("libcocos2dlua.so").add(0x93ad2d);

//var func = Module.findBaseAddress("libcocos2dlua.so").add(0x93ad0d);

Interceptor.attach(func, {

  onEnter: function (args) {

    this.fileout = "/sdcard/lua/" + Memory.readCString(args[3]).split("/").join(".");

    console.log("read file from: "+this.fileout);

    var tmp = Memory.readByteArray(args[1], args[2].toInt32());

    var file = new File(this.fileout, "w");

    file.write(tmp);

    file.flush();

    file.close();

  }

});


获取sign和key的frida脚本, 脚本文件放置路径为/data/local/tmp/frida_script.js


var func = Module.findBaseAddress("libcocos2dlua.so").add(0x6ea6d4);

//var func = Module.findExportByName("libcocos2dlua.so" , "cocos2d::LuaStack::setXXTEAKeyAndSign");

var Log = Java.use("android.util.Log");

Interceptor.attach(func, {

  onEnter: function (args) {

    Log.e("frida-HOOK", "key:"+Memory.readCString(args[1]));

    Log.e("frida-HOOK", "sign:"+Memory.readCString(args[3]));

  }

});




最后于 2023-9-14 03:24 被微启宇编辑 ,原因:
上传的附件:
2023-8-24 23:47
4
雪    币: 324
活跃值: (2974)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3

软件有壳,用脱壳工具就可以脱出来dex

lua解密一下,就可以看到软件具体实现了

2023-8-26 16:08
2
雪    币: 73
活跃值: (339)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
微启宇 这种想抓包就安装个虚拟机然后在虚拟机里装抓包工具的证书(提前转换成安卓支持的格),在把apk安装到虚拟机里,抓包工具打开忽略CONNECT的包。就能抓包了. 在应用层面做得再好也没法确保他的上层设备没 ...
老哥太强,很全的说
2024-9-3 20:14
0
雪    币: 3054
活跃值: (6837)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
bugshunter 老哥太强,很全的说
很简单的事没必要藏着掖着
2024-9-4 02:23
0
游客
登录 | 注册 方可回帖
返回