这道题就是在开逆向分享会,听过学长讲解后做的复现
这是一个用Unity编写的一个程序,核心逻辑在Assembly-CSharp.dll这个文件中
主逻辑就是起一个lua的环境,运行lua文件,在lua中找到加密函数(encrypt)。
下一步就是要找到用到的lua文件,然后dump出来
使用assetStudio工具查看文件,找到vm52.lua这个lua53文件,反汇编一下,看名字应该是一个vm,用lua53写的lua52汇编器,下面找到lua52的字节文件,此处用的是编译lua的在线网站https://luadec.metaworm.site/
文件名称是vm52.lua,说明是一个用lua编写的vm程序来编译lua52,下面就需要找到lua52的字节文件
在main.lua中有目标字节码 1b 4c 75 61 52
Dump出来,编译一下有我们需要的main,encrypt字样,而且逻辑清晰是一个tea加密,
注意在lua中^符号是pow的意思
r6_1是一个很大的数字,这个数字在进行乘方就会更大,lua对大数的处理会将他当作浮点数,然后进行异或操作就会报错,所以这里乘方一定是不对的。所以就要在vm的时候看他的乘方被改成了什么。找到对应vm,查看pow的字节码是18,18对应r33_6,然后找到对应的运算
这里对pow进行了魔改,让我们改过来然后跑一下解密tea的脚本。
跑过脚本,还是不对。所以就要考虑是不是在哪里又更改了一些东西
在unity运行lua时会用到xlua.dll这个插件,我们可以diff一下是不是这里改过了,首先找个xlua.dll源码,然后diff找到有差异的vm函数
Case0x11是pow,大概的逻辑就是(输入*8)^0x4736251
知道又改了东西,所以就要开始跑脚本。。。。
#include<stdio.h>
int main(void)
{
unsigned long long v[]
{
75405591852,
78071625542,
69577277816,
57193980063
};
unsigned key[4] = { 3735928575,
3405691582,
3735929054,
3221229823
};
unsigned int sum = 0;
unsigned int v1,v0;
unsigned char m[17] = { 0 };
for (int j = 0; j < 2; j++)
{
v0 = v[2 * j]&0xffffffff;
v1 = v[2 * j + 1]&0xffffffff;
sum = 32 * 2654435769;
for (int i = 0; i < 32; i++)
{
v1 -= (((v0*8)^ 0x4736251) + key[2]) ^ (v0 + sum) ^ (((v0 >> 6) ^ 359874885) + key[3]);
v0 -= (((v1*8) ^ 0x4736251) + key[0]) ^ (v1 + sum) ^ (((v1 >> 6) ^ 359874885) + key[1]);
sum -= 2654435769;
}
*((unsigned int*)m + 2 * j) = v0;
*((unsigned int*)m + 2 * j+1) = v1;
}
printf("%s", m);
}
这道题主要考的是lua+vm+vm修改,我们通过汇编lua得到一个vm.lua,发现vm.lua还会汇编一个lua,这样两层套娃,得到最后的加密脚本,加密脚本会报错,猜测pow操作被修改,然后返回vm.lua层查看pow操作,n==5时变为的右移加异或,然后跑脚本,发现还不对,接着找修改,因为n==4时仍是pow操作,所以猜测第一次汇编lua时的pow修改了,进而找xlua.dll,寻找里面的vm_loop,发现出错,然后修改跑脚本。 很有价值的一道题,了解了unity,unity中对lua的引用,了解了lua的汇编,以及lua的一些细节,比如大数转浮点数等等