我正在尝试查看我玩的游戏的这个文件里面有什么(用Lua写的),这样我就可以学习并看看它是如何完成的。但在一开始,它定义了使所有内容都无法读取的功能 - 代码在文件中。
随着代码的继续,您将使用### 获得更多“美化”的编码。有人可以告诉我如何使它再次可读吗?
您的文件包含[===[
和之间的压缩代码块]===]
。压缩只是一个字典编码器,其中关键字被映射到单个字节值。解压是通过prettify
(参见 Lorenzo 的帖子)完成的。
运行压缩代码prettify
会给你这个代码(压缩率~46%),这恰好是另一个解压缩程序!事实上,它似乎是该代码的最小化版本。
然后,该“ungzip”例程用于处理文件中包含的另一个约 150KB 的字符串,该字符串扩展为 675KB 的文本。
信不信由你,该文本也通过与 ungzip 代码相同的方案进行压缩,并包含其自己的prettify
. 通过它运行该文本prettify
会给我们最终的 963KB Lua,然后执行。
这是最终的解压缩代码,发布到我发现的第一个允许上传 963KB 的站点。格式就像它来自prettify
.
我是用于创建该文件的实用程序Squish的作者。
Squish 的一些过滤器是可逆的,有些则不是。这是一个尽可能轻松地倒车的提示:
在文件顶部,粘贴以下代码片段:
local _ls = loadstring;
function loadstring(...)
local f = assert(io.open("unsquished.lua", "w+"));
f:write((...));
f:close();
return _ls(...)
end
然后使用 Lua 运行该文件。它将unsquished.lua
在当前目录中生成一个新文件 . 这个文件现在是 100% 纯 Lua。
但是,您不会发现它特别容易阅读,因为所有不必要的空格都将被删除,并且一些变量名被简短的替代品替换。您可以查看lunadry以重新格式化代码,但原始变量名称无法恢复。
此外,该文件包含合并为一个的多个模块。你会看到这些看起来像:
package.preload['modulename']=(function(...)
--code here--
end)
如果需要,您可以将它们拆分为单独的文件,以提高可读性。
希望这可以帮助!
编辑:在您不信任的文件上使用此技术时要小心,因为它会在您运行时实际执行它们。如果您还不知道他们在做什么,这不是一个好主意!
由于发布的代码不完整,并且可能搞砸了,我的只是有根据的猜测。
似乎整个代码在变量中存储了ungz
对“匿名函数”的调用结果:(function ()
片段可能像这样关闭:
ungz = (function() -- "anonymous function"
-- ...
-- definition of `prettify` + helper data
-- ...
return assert( loadstring(
prettify [===[
...obfuscated code in this long string...
]===]
) ) -- end of `loadstring` and of `assert` calls
end)() --<<-- note the () to call the "anonymous function"
在此函数中,您可能会看到函数的定义prettify
及其辅助数据,可以通过以下方式重新格式化以便更好地理解:
local base_char,keywords=128, {
"and","break","do","else","elseif","end","false","for",
"function","if","in","local","nil","not","or","repeat","return",
"then","true","until","while","read","nbits","nbits_left_in_byte",
"wnd_pos","output","val","input",};
function prettify(code)
return code:gsub(
"["..string.char(base_char).."-"..string.char(base_char+#keywords).."]",
function (c)
return keywords[c:byte()-base_char];
end
)
end
函数prettify
应用于字符串时,将返回相同的字符串,其中任何在范围内具有数字代码的字符base_char
-base_char+#keywords
被替换为keyword
列表的关键字。
这用于“反混淆”“混淆”代码,使用assert(loadstring(prettify[===[xxxx]===]))
我将混淆代码表示为xxxx
.
附录:请注意,应用于prettify
片段[===[xxxx]===]
不会返回有意义的代码(base_char
值202
会给出更好的结果,尽管并不完美)。此外,您必须合并该长字符串中的所有行并将其替换为普通字符串,即将其转换为,"yyyy"
其中删除了所有硬换行符。yyyy
xxxx
可能所有这些代码都以某种更进一步的方式进行了预处理。