我有一些LUA代码,这似乎是通过默默无闻保护代码的尝试。我对loadstring()
函数的理解是文本字符串由LUA源代码文本组成,然后通过loadstring()
方法转换为可执行的LUA代码。
使用以下LUA源,我尝试通过在变量code
上调用print
来读取变量code
的内容;虽然我确实在转换后的字符串中看到了一些有效的源文本,但大多数字符都没有显示(我假设具有低于40及以上的字符代码的字符(。请注意,ASCII中有一些特别高的值,例如231显然是在扩展集中,是商标标志。此外,那里有几个空字符。所有这些使我怀疑它是否确实是ascii。
有人可以告诉我字符串是否有效lua源,以及如何使lua返回字符串作为可打印字符,以便我可以看到此代码的作用?
当我在Windows的Lua控制台中使用print
运行我的版本时,我得到了许多空盒子,大概是该控制台只能打印纯ASCII?
请注意,该代码是使用LUA版本5.0.2
执行的。code='2776117978014446899818291471042312451256512 64108117971011091034610811797 1 523 8 16 17 17 17 17 17 18 18 19 20 21 35 35 26 49 49 37 59 59 54 61 66 2 4 10452120 1 22 7 77111100117108101 12 22 12 413 12212297781111001017897109101115 46 9090654849 46 9090654850 414 122122978410112011690101105108101110 412 1221229780111115105116105111110 3 2406348 1221229784101120116 41 420 1221229767117114114101110116841011201168697108117101 49 1221229783101116117112 410 122122978310110810199116 49 1221229782101115101116 4 2 1 714 3 3 4 4 4 5 5 5 5 4 5 7 7 8 4 7 11511611411698108 13 16 40102111114321031011101011149711611111441 5 11 12 40102111114321151169711610141 5 11 2 118 5 11 2 47 98117102102101114 41 14 65 17 1 1312812222 12815 4198 5831247 429 184254127 5 127 1127128 26 11 418 27 28 28 29 29 30 32 32 32 32 32 33 33 33 33 33 27 35 2 8 1221229770105108101 17 6 122101105108101 3 16 1 7 77111100117108101 5 45 11410197100 414 122122978410112011690101105108101110 412 1221229780111115105116105111110 3 24063 18 1483128 13962 1153 1185128125 20 128 1482128 4 2663124 3701911373128124 24 37019113140191132011281262212251127 27128 37 12 721 39 39 39 39 39 40 40 40 40 43 46 46 46 46 46 46 46 46 46 46 49 3 6 11897108117101 20 9 1101111001017897109101 20 20 12212297831011081019911610110080111115105116105111110 10 20 1 7 77111100117108101 7 48 1221229784101120116 414 122122978410112011690101105108101110 420 1221229767117114114101110116841011201168697108117101 45 6797108108 45 90906548 414 5865991161051189711610178111100101 3 24063 21 4 24 319819013612813201 12524 24 313419013201 1262 2197 311 4 128 5651 614712411 5 16147129251291 689 2327128 54 1 419 56 56 56 56 56 56 56 56 56 57 57 57 57 57 57 57 57 57 59 1 7 77111100117108101 7 45 6797108108 413 12212297781111001017897109101115 3 24063414 5865991161051189711610178111100101 44 97108108 3 3 64 19 5 4 1198190 16191 1193 2147128 111 2651 389 2 5 4 1198190 16192 1193 2147128 111 2651 389 2 27128 23 34 202 110 1265 3129 495 2137 125110 21371281261201631271736412817364129198 2 128 1371281291162 2 128 137 1301226 2 128 137128130127 1127128 ';
return loadstring(code)();
此字符串是将LUA代码的有效块预先编译到字节码中。头说这是针对LUA 5.0。它不是文本,不需要解码,因此可以直接使用loadstring()
提供了比弗拉德(Vlad(的答案更多的详细信息。
LUA loadstring()
函数接受LUA源文本或LUA字节码的字符串。看来该功能通过查看字符串的第一个字符来查看它是逃生字符(0x1b还是Decimal 27(来确定文本的类型。
loadstring()
功能返回匿名函数,因此在代码示例中:
code='2776117978014446899818291471042312451256512 64108117971011091034610811797 1 523 8 16 17 17 17 17 17 18 18 19 20 21 35 35 26 49 49 37 59 59 54 61 66 2 4 10452120 1 22 7 77111100117108101 12 22 12 413 12212297781111001017897109101115 46 9090654849 46 9090654850 414 122122978410112011690101105108101110 412 1221229780111115105116105111110 3 2406348 1221229784101120116 41 420 1221229767117114114101110116841011201168697108117101 49 1221229783101116117112 410 122122978310110810199116 49 1221229782101115101116 4 2 1 714 3 3 4 4 4 5 5 5 5 4 5 7 7 8 4 7 11511611411698108 13 16 40102111114321031011101011149711611111441 5 11 12 40102111114321151169711610141 5 11 2 118 5 11 2 47 98117102102101114 41 14 65 17 1 1312812222 12815 4198 5831247 429 184254127 5 127 1127128 26 11 418 27 28 28 29 29 30 32 32 32 32 32 33 33 33 33 33 27 35 2 8 1221229770105108101 17 6 122101105108101 3 16 1 7 77111100117108101 5 45 11410197100 414 122122978410112011690101105108101110 412 1221229780111115105116105111110 3 24063 18 1483128 13962 1153 1185128125 20 128 1482128 4 2663124 3701911373128124 24 37019113140191132011281262212251127 27128 37 12 721 39 39 39 39 39 40 40 40 40 43 46 46 46 46 46 46 46 46 46 46 49 3 6 11897108117101 20 9 1101111001017897109101 20 20 12212297831011081019911610110080111115105116105111110 10 20 1 7 77111100117108101 7 48 1221229784101120116 414 122122978410112011690101105108101110 420 1221229767117114114101110116841011201168697108117101 45 6797108108 45 90906548 414 5865991161051189711610178111100101 3 24063 21 4 24 319819013612813201 12524 24 313419013201 1262 2197 311 4 128 5651 614712411 5 16147129251291 689 2327128 54 1 419 56 56 56 56 56 56 56 56 56 57 57 57 57 57 57 57 57 57 59 1 7 77111100117108101 7 45 6797108108 413 12212297781111001017897109101115 3 24063414 5865991161051189711610178111100101 44 97108108 3 3 64 19 5 4 1198190 16191 1193 2147128 111 2651 389 2 5 4 1198190 16192 1193 2147128 111 2651 389 2 27128 23 34 202 110 1265 3129 495 2137 125110 21371281261201631271736412817364129198 2 128 1371281291162 2 128 137 1301226 2 128 137128130127 1127128 ';
return loadstring(code)();
您有一个文本字符串,其中包含LUA字节码,如 27的领先逃生字符所示,然后呼叫loadstring()
来创建一个函数,然后执行该函数。
文本字符串的前几个字符包含预编译的LUA标头(请参见Lua 5.2字节码和虚拟机(。该标头的长度因LUA的版本而异。但是,前几个字符似乎是相当标准的。code='27761179780 ...
包含逃生字符(0x1b或Decimal 27(,大写字母L(十进制76(,小写字母U(十进制117(,下部案例字母A(十进制97(和LUA版本(Decimal 80 IS 0x50 IS 0x50指示版本5.0(。
以下示例来自LUA 5.2字节码和虚拟机。
字节码到底是什么?这是Hello.luac的Hexdump (由HD在我的系统上制造(。
00000000 1b 4c 75 61 52 00 01 04 04 04 08 00 19 93 0d 0a |.LuaR...........| 00000010 1a 0a 00 00 00 00 00 00 00 00 00 01 04 07 00 00 |................| 00000020 00 01 00 00 00 46 40 40 00 80 00 00 00 c1 80 00 |.....F@@........| 00000030 00 96 c0 00 01 5d 40 00 01 1f 00 80 00 03 00 00 |.....]@.........| 00000040 00 04 06 00 00 00 48 65 6c 6c 6f 00 04 06 00 00 |......Hello.....|
该格式未正式记录,需要为 反向工程。必要的材料在LUA源代码中, 当然,在几个地方,主要是ldump.c和lundump.c。我有 也与NFI和LAT进行了交叉检查,但剩余的任何错误是 我的。
代码以18字节文件标头开头,所有标题都相同 官方LUA 5.2字节码在像您这样的机器上编译,无论是 LUAC或LOADFILE。LUA 5.1只有一个12字节的标题,类似 到该字节的前12个字节。
字节数为Origin-1小数(主要显示算术( 和Origin-0 HEX。
1 x00:1b 4c 75 61 lua_signature来自lua.h。
5 x04:52 00 LUA版本的二进制编码十进制52,00要说字节码为 与"官方" PUC-RIO实施兼容。
5 2 x06:01 04 04 04 08 00六个系统参数。在X386机器上,他们的意思是: Little-endian,4字节整数,4字节VM说明,4字节size_t 数字,8字节LUA数字,浮点。这些参数必须全部 匹配字节码文件和LUA解释器,否则 字节码无效。
7 6 x0c:19 93 0d 0a 1a 0a 总之 LUA 5.2从PUC-RIO产生的字节码。在lundump.h中描述为 "捕获转换错误的数据"。可能是由 二进制编码的十进制十进制1993年(全部开始的一年(,Windows系列 终结器,MS-DOS文本文件终结器,UNIX LINE终结器。
这18个字节是在文件中定义的函数。每个功能 从11字节函数标头开始。
13 6 x12:00 00 00 00在源代码中启动的源代码中的行号。 0对于主块。
19 4 x16:00 00 00 00 00 00 00 块停止的代码。0对于主块。
23 4 x1a:00 01 04 参数数量,vararg标志,此使用的寄存器数量 功能(显然不超过255(。本地变量存储在 寄存器;其中可能不超过200个(请参阅lparser.c(。