diff --git a/README.md b/README.md index b2baab2..7a3a952 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | Java Class | `application/x-java-applet` | [`patterns/java_class.hexpat`](patterns/java_class.hexpat) | Java Class files | | JPEG | `image/jpeg` | [`patterns/jpeg.hexpat`](patterns/jpeg.hexpat) | JPEG Image Format | | Lua 5.1 | | [`patterns/lua51.hexpat`](patterns/lua51.hexpat) | Lua 5.1 bytecode | +| Lua 5.2 | | [`patterns/lua52.hexpat`](patterns/lua52.hexpat) | Lua 5.2 bytecode | | Lua 5.4 | | [`patterns/lua54.hexpat`](patterns/lua54.hexpat) | Lua 5.4 bytecode | | LCE Savefile | | [`patterns/lcesave.hexpat`](patterns/lcesave.hexpat) | Minecraft Legacy Console Edition save file | | Mach-O | `application/x-mach-binary` | [`patterns/macho.hexpat`](patterns/macho.hexpat) | Mach-O executable | diff --git a/patterns/lua52.hexpat b/patterns/lua52.hexpat new file mode 100644 index 0000000..c25ad64 --- /dev/null +++ b/patterns/lua52.hexpat @@ -0,0 +1,110 @@ +#pragma description Lua 5.2 bytecode + +import std.io; +import std.mem; + +namespace impl { + fn format_LuaString(auto string) { + if (string.size == 0) { + return "None"; + } + return std::format("\"{}\"", string.data); + }; + + fn format_Constant(auto constant) { + return constant.data; + }; + + fn format_Version(auto ver) { + return std::format("Ver. {}.{}", ver.major, ver.minor); + }; +} +using LuaFunction; + +bitfield Version { + minor : 4; + major : 4; +} [[format("impl::format_Version")]]; + +struct LuaBinaryHeader { + char magic[4]; + Version version_number; + u8 format_version; + u8 endianness; + u8 size_of_int; + u8 size_of_size_t; + u8 size_of_Instruction; + u8 lua_Number; + u8 is_lua_Number_integral; + char LUAC_TAIL[6]; +}; + +struct LuaString { + u64 size; + if (size > 0) { + char data[size]; + } +}[[format("impl::format_LuaString")]]; + +struct LuaConstant { + u8 type; + if (type == 0) { // LUA_TNIL + // NULL + } else if (type == 1) { // LUA_TBOOLEAN + u8 data; + } else if (type == 3) { // LUA_TNUMBER + double data; + } else if (type == 4) { // LUA_TSTRING + LuaString data; + } +}[[format("impl::format_Constant")]]; + +struct LuaUpvalue { + u8 instack; + u8 idx; +}; + +struct Vector { + u32 size; + T values[size]; +}; + +struct LocalVar { + LuaString varname; + u32 startpc; + u32 endpc; +}; + +struct LuaDebugInfo { + LuaString source; + Vector lineInfo; + Vector local_vars; + Vector upvalues; +}; + +struct LuaConstants { + Vector constants; + u32 sizep; // size of proto + if (sizep > 0) { + LuaFunction protos[sizep]; + } +}; + +struct LuaFunction { + u32 line_defined; + u32 last_line_defined; + u8 number_of_parameters; + u8 is_vararg; + u8 maxstacksize; + Vector code; + LuaConstants luaConstants; + Vector upvalues; + LuaDebugInfo debugInfo; +}; + +struct LuaFile { + LuaBinaryHeader header; + LuaFunction func; +}; + +LuaFile file @ 0; diff --git a/tests/patterns/test_data/lua52.hexpat.lua b/tests/patterns/test_data/lua52.hexpat.lua new file mode 100644 index 0000000..beb51d5 Binary files /dev/null and b/tests/patterns/test_data/lua52.hexpat.lua differ