查看原文
其他

用 Lua 简单还原 OpCode 顺序

Amun 看雪学院 2019-05-25

前段时间外出游荡,遇上个大兄弟说能不能跑个 Lua 脚本把 Lua 里被修改的 OpCode 顺序弄出来,最近有空自己尝试一下。

 


准备材料


① 被修改 OpCode 顺序的 Lua 虚拟机程序一个,不限 SO/DLL/EXE;

② 同版本的正常 Lua 虚拟机程序一个,不知道版本的同学可以从字符串里找,这里是 Lua 5.1.5;

③ 随便写一个能正常编译的 Lua 函数。




思路


1、dump 出 Lua 虚拟机中的脚本字节码文件;

2、用正常的字节码去校对 OpCode 乱序的字节码。


一般情况下 *.luac 文件由 luac 程序生成,其中的数据是由luaU_dump函数产生,在 luac.c 文件中被调用,而 luaU_dump 的另一个入口在lapi.c lua_dump,被绑定到 Lua 的 string.dump函数。


通过在 Lua 脚本中对需要 dump 的函数用
string.dump,可以得到对应的字节码。

 

分别在目标 Lua 和正常 Lua 虚拟机中运行以下这段代码,获得 OpCode 乱序后的 luac 文件和正常的 luac 文件:


-- lua script
function test()
-- ...略
end
local data = string.dump(test)
local fp = io.open("test.luac","wb")
fp:write(data)
fp:close()


拿得到的两份 luac 文件比较下,提取出差异内容,差异的部分应该是 Instruction 中的 OpCode。


 

从 Lua 源码中的 lvm.c 文件的 luaV_execute 函数中得知,是通过 GET_OPCODE 宏获取到 OpCode,再执行对应的操作。


// lvm.c
void luaV_execute (lua_State *L, int nexeccalls) {
//......
switch (GET_OPCODE(i)) {
case OP_MOVE: {
setobjs2s(L, ra, RB(i));
continue;
}
case OP_LOADK: {
setobj2s(L, ra, KBx(i));
continue;
}
//......
}


GET_OPCODE  宏的定义在 lopcodes.h 文件中,相关代码如下:


// lopcodes.h
#define cast(t, exp) ((t)(exp))
#define SIZE_OP 6
#define POS_OP 0
#define MASK1(n, p) ((~((~(Instruction)0)<<n))<<p)
#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))

简单来说,指令 & 0x3F 就可以得到 OpCode 的数值

 

依旧在目标 Lua 中执行,让它自己输出 OpCode 顺序,完整代码资源在附件。


-- lua sciprt
-- ...
local data = string.dump(test) -- dump
local new_op = {}
-- 用目标 lua 和正常 lua 的 dump 数据对比
for i = 1, #data do
local by_ori = string.byte(ori_data,i)
local by_new = string.byte(data,i)
if by_ori ~= by_new then
local op_name = ori_op_name[bit:_and(0x3F,by_ori) + 1]
local op_idx = bit:_and(0x3F,by_new)
new_op[op_name] = op_idx
end
end

print("old \t new \t name")
for idx, op_name in pairs(ori_op_name) do
local tmp = ''
if new_op[op_name] ~= nil then
tmp = new_op[op_name]
end
print((idx - 1) .. "\t" .. tmp .. "\t" .. op_name )
end



输出结果



 

对于手游中使用的 xlua/ulua/tolua,操作方法类似。

 

下面是技术总结

1、Lua 版本一定要相同

2、用于 dump 的函数,尽量覆盖所有的指令操作,否则只能提取出已有的指令




- End -




看雪ID:Amun           

https://bbs.pediy.com/user-850401.htm



本文由看雪论坛 Amun 原创

转载请注明来自看雪社区



热门图书推荐

 立即购买!




热门文章阅读

1、大学生复制饭卡上千张,仅2月赚10万,已被刑拘

2、API监控+代码乱序的壳

3、治标不治本,黑客仍可利用思科路由器漏洞




公众号ID:ikanxue

官方微博:看雪安全

商务合作:wsc@kanxue.com



↙点击下方“阅读原文”,查看更多干货!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存