当前位置:网站首页>【frida实战】“一行”代码教你获取WeGame平台中所有的lua脚本
【frida实战】“一行”代码教你获取WeGame平台中所有的lua脚本
2022-07-07 06:58:00 【夜猫逐梦】
文章目录
导读
开发环境
版本号 | 描述 | |
---|---|---|
操作系统 | Win11-21H2 | 内部版本号22000.588 |
Python | Python3.7.1 | |
frida.exe | 15.0.18 | |
预备知识
luaL_loadbuffer
函数原型(https://www.lua.org/manual/5.1/manual.html#luaL_loadbuffer):
int luaL_loadbuffer (lua_State *L, // Lua句柄
const char *buff, // lua脚本
size_t sz, // lua脚本字节数
const char *name); // 标记(通过分析可以发现这里是文件名)
将缓冲区加载为 Lua 块。此函数用于加载lua_load指向的缓冲区中的块。 name是块名称,用于调试信息和错误消息。
WeGame中使用的是Lua51.dll,它导出了两个函数luaL_loadbuffer
和luaL_loadbufferx
,通过IDA分析可以猜测,luaL_loadbufferx
只是比luaL_loadbuffer
多了个参数a5
,其他参数都是一样的。
frida拦截器Interceptor
frida的Interceptor模块中,attach函数原型为Interceptor.attach(target, callbacks[, data])
,实现了对参数target
进行hook的操作,下面是简单的参数分析:
target:
这是一个 NativePointer,指定您想要拦截调用的函数的地址。我们可以通过Module.getExportByName()
来获取可执行文件的导出函数作为该参数,frida会自动处理。callbacks:
顾名思义,这是hook的回调函数集合,里面包含了hook前和hook后两个回调函数。onEnter(args):
该回调函数的参数args为hook函数的参数数组,每个参数都是一个NativePointer
对象,我们可以在这里获取参数信息,或者篡改参数内容。onLeave(retval):
该调用是执行完目标函数
后的处理,参数retval
是一个NativePointer
对象,是目标函数
的返回值,我们可以修改该指针内容达到hook的目的。
data:
可选参数,暂时忽略掉。
示例:
Interceptor.attach(Module.getExportByName('libc.so', 'read'), {
onEnter(args) {
this.fileDescriptor = args[0].toInt32();
// this上下文信息:包含寄存器信息context、返回值地址returnAddress、线程ID threadId等
console.log('Context information:');
console.log('Context : ' + JSON.stringify(this.context));
console.log('Return : ' + this.returnAddress);
console.log('ThreadId : ' + this.threadId);
console.log('Depth : ' + this.depth);
console.log('Errornr : ' + this.err);
},
onLeave(retval) {
if (retval.toInt32() > 0) {
/* do something with this.fileDescriptor */
}
}
});
ps: callbacks是一个对象,frida实现中,会在初始化的时候,给该对象填充
上下文信息信息
,这也就是为什么示例中的this可以访问context、returnAddress、threadId
这些内容。
ps2: 之前一直纠结
onEnter
中生成的变量,怎么在onLeave
中使用,其实直接通过this就可以了this.tempVal=333;
。这都是对js的基础理解和应用。
NativeFunction创建目录
frida调用dll函数,通过NativeFunction
创建一个函数对象,设置响应的参数和返回值。
本文使用的是WinExec
函数调用了cmd命令中的mkdir
指令来实现创建目录,具体实现看下面的代码。
ps: 也可以使用c函数中的
system
,其原型如下:
分析思路
挂起启动WeGame
为了保证hook所有的lua,需要挂起启动WeGame,使用命令frida -f 应用程序全路径
即可挂起启动目标进程,命令行示例:
D:\Python\Python371\Scripts\frida.exe -f "G:\Program Files (x86)\WeGame\wegame.exe"
WeGame需要管理员权限启动,否则会报0x000002e4
的启动失败错误。
hook函数luaL_loadbufferx保存所有js
var fnWinExec = new NativeFunction(
Module.findExportByName('Kernel32.dll', 'WinExec'),
'int',
['pointer', 'int'],
'stdcall'
);
function ez_fnWinExec(jsStr) {
console.log( 'ez_fnWinExec: ', jsStr );
var cStrPointer = Memory.allocUtf8String(jsStr);
fnWinExec(cStrPointer, 0);
}
Interceptor.attach(Module.getExportByName('Lua51.dll', 'luaL_loadbufferx'), {
onEnter(args) {
// 不可以使用数组解构赋值!!!
// var [_,a,b]=[0,1,3]
// var [L, buff, sz, name] = args;
var buff = args[1];
var sz = args[2];
var name = args[3];
console.log( name.readCString(), sz.toInt32(), buff );
// 过滤非lua文件
if (!name.readCString().endsWith('.lua')){
return;
}
var pth = 'D:\\_TMP\\wegame\\' + name.readCString();
// 创建文件夹
var dir_ = pth.substr(0, pth.lastIndexOf('\\')+1);
ez_fnWinExec('cmd.exe /c mkdir '+ dir_);
// 保存文件
var f = new File(pth, 'wb');
var data = buff.readByteArray(sz.toInt32());
f.write(data);
f.close();
},
onLeave(retval) {
}
});
一开始想的是不需要调用函数
WinExec
,优化一下可以写成“一行”代码的,后来发现多级目录,得自己创建目录,又加上了一堆的代码。。。
所以,就不再是“一行”代码实现了。
参考资料
- [frida] 00_简单介绍和使用 https://blog.csdn.net/kinghzking/article/details/123225580
- Lua游戏逆向及破解方法介绍 https://blog.csdn.net/liujiayu2/article/details/81942010
- qq群:夜猫逐梦技术交流裙/953949723
**ps:**文章中内容仅用于技术交流,请勿用于违规违法行为。
边栏推荐
- Mysql database lock learning notes
- Test Engineer Interview Questions 2022
- Upload taro pictures to Base64
- Run can start normally, and debug doesn't start or report an error, which seems to be stuck
- nlohmann json
- 印象笔记终于支持默认markdown预览模式
- Unity uses mesh to realize real-time point cloud (I)
- Data association between two interfaces of postman
- 创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,且是随机赋值。同时,要求元素的值各不相同。
- Integer or int? How to select data types for entity classes in ORM
猜你喜欢
[cloud native] Devops (I): introduction to Devops and use of code tool
Connecting mobile phone with ADB
Information Security Experiment 4: implementation of IP packet monitoring program
Kubernetes cluster capacity expansion to add node nodes
Sublime Text4 download the view in bower and set the shortcut key
Netease cloud wechat applet
Nested (multi-level) childrn routes, query parameters, named routes, replace attribute, props configuration of routes, params parameters of routes
[SVN] what is SVN? How do you use it?
Difference between interface iterator and iteratable
Network request process
随机推荐
IIS faked death this morning, various troubleshooting, has been solved
# Arthas 简单使用说明
Netease cloud wechat applet
第一讲:寻找矩阵的极小值
Nested (multi-level) childrn routes, query parameters, named routes, replace attribute, props configuration of routes, params parameters of routes
Cesium does not support 4490 problem solution and cesium modified source code packaging scheme
Entity of cesium data visualization (Part 1)
Niuke - Huawei question bank (61~70)
Test Engineer Interview Questions 2022
Information Security Experiment 3: the use of PGP email encryption software
JMeter JDBC batch references data as input parameters (the simplest method for the whole website)
Create an int type array with a length of 6. The values of the array elements are required to be between 1-30 and are assigned randomly. At the same time, the values of the required elements are diffe
Interface test API case, data and interface separation
软件建模与分析
[4G/5G/6G专题基础-147]: 6G总体愿景与潜在关键技术白皮书解读-2-6G发展的宏观驱动力
【云原生】DevOps(一):DevOps介绍及Code工具使用
Zen - batch import test cases
Jemter operation
shake数据库中怎么使用Mongo-shake实现MongoDB的双向同步啊?
Colorbar of using vertexehelper to customize controls (II)