binary_chunk.go 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Author: simon
  2. // Author: ynwdlxm@163.com
  3. // Date: 2024/4/5 15:52
  4. // Desc:
  5. // luac -v
  6. // Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio
  7. //
  8. // (base) ➜ lua xxd -u -g 1 luac.out
  9. // 00000000: 1B 4C 75 61 53 00 19 93 0D 0A 1A 0A 04 08 04 08 .LuaS...........
  10. // 00000010: 08 78 56 00 00 00 00 00 00 00 00 00 00 00 28 77 .xV...........(w
  11. // 00000020: 40 01 11 40 68 65 6C 6C 6F 5F 77 6F 72 6C 64 2E @..@hello_world.
  12. // 00000030: 6C 75 61 00 00 00 00 00 00 00 00 00 01 02 04 00 lua.............
  13. // 00000040: 00 00 06 00 40 00 41 40 00 00 24 40 00 01 26 00 ....@.A@..$@..&.
  14. // 00000050: 80 00 02 00 00 00 04 06 70 72 69 6E 74 04 0D 48 ........print..H
  15. // 00000060: 65 6C 6C 6F 2C 20 57 6F 72 6C 64 01 00 00 00 01 ello, World.....
  16. // 00000070: 00 00 00 00 00 04 00 00 00 01 00 00 00 01 00 00 ................
  17. // 00000080: 00 01 00 00 00 01 00 00 00 00 00 00 00 01 00 00 ................
  18. // 00000090: 00 05 5F 45 4E 56 .._ENV
  19. package binchunk
  20. const (
  21. LUA_SIGNATURE = "\x1bLua"
  22. LUAC_VERSION = 0x53
  23. LUAC_FORMAT = 0
  24. LUAC_DATA = "\x19\x93\r\n\x1a\n"
  25. CINT_SIZE = 4
  26. CSZIET_SIZE = 8
  27. INSTRUCTION_SIZE = 4
  28. LUA_INTEGER_SIZE = 8
  29. LUA_NUMBER_SIZE = 8
  30. LUAC_INT = 0X5678
  31. LUAC_NUM = 370.5
  32. TAG_NIL = 0X00
  33. TAG_BOOLEAN = 0X01
  34. TAG_NUMBER = 0X03
  35. TAG_INTEGER = 0X13
  36. TAG_SHORT_STR = 0X04
  37. TAG_LONG_STR = 0X14
  38. )
  39. // Undump 解析二进制 chunk
  40. func Undump(data []byte) *Prototype {
  41. reader := &reader{data}
  42. reader.checkHeader() // 校验头部
  43. reader.readByte() // 跳过 Upvalue 数量
  44. return reader.readProto("") // 读取函数原型
  45. }
  46. type binaryChunk struct {
  47. header // 头部
  48. sizeUpvalues byte // 主函数 upvalue 数量 01
  49. mainFunc *Prototype // 主函数原型
  50. }
  51. type header struct {
  52. signature [4]byte // 签名 1B 4C 75 61(ESC L u a 的 ASCII 码)
  53. version byte // 版本号 大版本号 小版本号 发布版本号 Lua 5.3.6 5X16+4=83(0X53)
  54. format byte // 格式号 0
  55. luacData [6]byte // LUAC_DATA 0x1993 回车(0X0D) 换行(0X0A) 替换(0X1A) 换行(0X0A)
  56. cintSize byte // cint 在二进制 chunk 里占用的字节数 04
  57. sizetSize byte // size_t 在二进制 chunk 里占用的字节数 08
  58. instructionSize byte // Lua 虚拟机指令在二进制 chunk 里占用的字节数 04
  59. luaIntegerSize byte // Lua 整数在二进制 chunk 里占用的字节数 08
  60. luaNumberSize byte // Lua 浮点数在二进制 chunk 里占用的字节数 08
  61. luacInt int64 // 78 56 00 00 00 00 00 00
  62. luacNum float64 // 00 00 00 00 00 28 77 40
  63. }
  64. type Prototype struct {
  65. Source string // 源文件名
  66. LineDefined uint32 // 起止行号
  67. LastLineDefined uint32 // 起止行号
  68. NumParams byte // 固定参数个数
  69. IsVararg byte // 是否有变长参数
  70. MaxStackSize byte // 寄存器数量
  71. Code []uint32 // 指令表
  72. Constants []interface{} // 常量表
  73. Upvalues []Upvalue // Upvalue 表,每个元素占用 2 个字节
  74. Protos []*Prototype // 函数原型
  75. LineInfo []uint32
  76. LocVars []LocVar // 局部变量表
  77. UpvalueNames []string
  78. }
  79. type Upvalue struct {
  80. Instack byte
  81. Idx byte
  82. }
  83. type LocVar struct {
  84. VarName string
  85. StartPC uint32
  86. EndPC uint32
  87. }