本帖最后由 Raven95676 于 2024-12-30 21:59 编辑
从https://bbs.kafan.cn/thread-2277676-1-1.html继续讨论。
打开相关文件后发现其包含经过编码的Lua脚本内容。
脚本中的decodeFunction由Cheat Engine提供,用于加载经过encodeFunction编码的Lua函数。
由于Cheat Engine是开源项目,因此我们可以查看decodeFunction的具体实现。该函数位于LuaHandler.pas文件中:
- function lua_decodeFunction(L: Plua_State): integer; cdecl;
- var
- ds: Tdecompressionstream;
- s: TMemoryStream;
- decompressed: TMemoryStream;
- i: integer;
- size: integer;
- input, output: pchar;
- begin
- result:=1;
- if (lua_gettop(L)=1) and lua_isstring(L,1) then
- begin
- input:=lua.lua_tostring(L,1);
- size:=(length(input) div 5)*4+(length(input) mod 5);
- getmem(output, size*2);
- size:=Base85ToBin(input, output);
- lua_pushlstring(L, output, size);
- s:=TMemoryStream.Create;
- s.WriteBuffer(output^, size);
- s.position:=0;
- ds:=Tdecompressionstream.create(s);
- decompressed:=TMemoryStream.create;
- decompressed.CopyFrom(ds,0);
- decompressed.position:=0;
- lua_load(L, @lreader, decompressed,'cechunk', 'b');
- freeandnil(decompressed);
- freeandnil(ds);
- freeandnil(s);
- FreeMemAndNil(output);
- result:=1;
- end;
- end;
复制代码
上述代码将Base85编码字符串解码为二进制数据,并在解压缩后加载。
接下来我们需要分析Base85ToBin的实现。其完整代码请前往GitHub查看。
该函数加载了自定义的Base85字符集,每5个Base85字符将被转换为4个字节的二进制数据。如果输入的Base85字符串长度不是5的倍数,则会进行填充处理。
为了方便,我们直接使用现有的CEFunctionDecoder。得到的lua字节码使用luadec进行处理,得到1.lua。
推测l_0_0为自定义解密算法,l_0_1为密文,l_0_2为解密相关参数。
解码l_0_0,得到2.lua
传入参数为l_0_0与l_0_1。我们先来看看l_0_14函数到底干了什么。可见其内容是由l_0_2经过变换后调用decodeFunction得出的,其内容如下:
- while l_0_1 ~= 0 do
- upval_0.z = l_0_0
- l_0_0 = l_0_1
- l_0_1 = upval_0.z % l_0_1
- end
- return l_0_0
复制代码
其作用为求最大公约数。
结合1.lua的内容,我们使用Python复现其解密算法为:
- import math
- def l_0_14(a, b):
- while b:
- a, b = b, a % b
- return a
- l_0_0 = 数据
- l_0_1 = 13
- l_0_15 = len(l_0_0)
- l_0_1 = int(l_0_1 / l_0_14(l_0_1, l_0_15) % l_0_15)
- l_0_16 = (math.floor(int(l_0_15 / 2)) + l_0_1) % l_0_15
- l_0_17 = {}
- l_0_18 = ""
- for l_0_24 in range(1, l_0_15 + 1):
- l_0_25 = 1 + (l_0_24 * l_0_1 + l_0_16) % l_0_15
- l_0_37 = ord(l_0_0[l_0_24 - 1])
- l_0_17[l_0_25] = l_0_37
-
- if 33 <= l_0_37 <= 126:
- l_0_37 = l_0_17[l_0_25]
- l_0_37 = l_0_37 - 33
- l_0_37 = l_0_37 + l_0_1 * (l_0_24 % (126 + 1 - 33))
- l_0_37 = l_0_37 - l_0_24
- l_0_37 = l_0_37 % (126 + 1 - 33)
- l_0_37 = l_0_37 + 33
- l_0_17[l_0_25] = l_0_37
- for l_0_29 in range(1, l_0_15 + 1):
- l_0_18 += chr(l_0_17[l_0_29])
- print(l_0_18)
复制代码
需要注意的是Lua的索引从1开始,而Python的索引从0开始。Python的除法默认会算出浮点数,故需要显式转换。
最终,输出的内容通过CEFunctionDecoder处理后再反编译即可得到完整的Lua脚本3.lua:
|