解释隐藏代码

时间:2013-08-23 10:18:24

标签: lua decoding

我正在试图看看这个文件里面有什么(用你写的)我玩的游戏,这样我就可以学习并看看它是如何完成的。但是在开始时它定义了使一切都不可读的函数 - 代码在文件中。

随着代码的继续,你会用###获得更多“美化”的编码。有人能告诉我如何制作它再次可读吗?

3 个答案:

答案 0 :(得分:5)

您的file包含[===[]===]之间的压缩代码块。压缩只是dictionary coder,其中关键字映射到单个字节值。解压缩是通过prettify完成的(参见Lorenzo的帖子)。

通过prettify运行压缩代码会为您提供this code(压缩率~46%),这恰好是另一个解压缩例程!实际上,它似乎是this code的最小化版本。

然后使用“ungzip”例程处理文件中包含的另一个~150KB字符串,该字符串扩展为675KB的文本。

信不信由该文本压缩,通过与ungzip代码相同的方案,并包含其{em>自己的副本prettify。通过prettify运行该文本,为我们提供了最终的963KB Lua,然后执行。

这是发布到我发现允许上传963KB的第一个网站的final, decompressed code。格式化就像prettify一样。

答案 1 :(得分:3)

我是用于创建该文件的实用程序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)

如果您愿意,可以将这些文件拆分为单独的文件,以帮助提高可读性。

希望这有帮助!

编辑:在您不信任的文件上小心使用此技术,因为它会在您运行时实际执行它们。如果您还不知道他们做了什么,那不是一个好主意!

答案 2 :(得分:2)

由于发布的代码不完整,可能搞砸了,我的只是受过教育的猜测。

似乎整个代码在变量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",其中yyyyxxxx,并删除所有硬新行。

可能所有代码都会以某种方式进行预处理。