/
exe_lua.go
93 lines (69 loc) · 2.25 KB
/
exe_lua.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package exe
// STATUS: 1%
import (
"os"
"github.com/martinlindhe/formats/parse"
)
// LUA parses the Lua bytecode format
func LUA(c *parse.Checker) (*parse.ParsedLayout, error) {
if !isLUA(c.Header) {
return nil, nil
}
return parseLUA(c.File, c.ParsedLayout)
}
func isLUA(b []byte) bool {
if b[3] == 0x61 && b[2] == 0x75 && b[1] == 0x4c && b[0] == 0x1b {
// Lua 5.1 and 5.2 identifer
return true
}
return false
}
func parseLUA(file *os.File, pl parse.ParsedLayout) (*parse.ParsedLayout, error) {
pos := int64(0)
pl.FileKind = parse.Executable
pl.Layout = []parse.Layout{{
Offset: pos,
Length: 4, // XXX
Info: "header",
Type: parse.Group,
Childs: []parse.Layout{
{Offset: pos, Length: 4, Info: "magic", Type: parse.Uint32le},
}}}
return &pl, nil
}
/*
override public List<Chunk> GetFileStructure()
{
// NOTE: first 12 bytes are same for lua 5.1 and lua 5.2
List<Chunk> res = new List<Chunk>();
var header = new Chunk{ Text = "Lua header", length = 12 };
res.Add(header);
var identifier = new Chunk{ Text = "Lua identifier", length = 4 };
header.Nodes.Add(identifier);
BaseStream.Position = 4;
var versionNumber = ReadByte();
if (versionNumber >= 0x52) {
header.length = 18;
}
// TODO need samples for more versions, like lua 5.0
if (versionNumber != 0x51 && versionNumber != 0x52) {
Console.WriteLine("unknown LUA version " + versionNumber + ", sample please!");
return res;
}
var version = new Chunk("Version = " + versionNumber.ToString("x2"), 1); // TODO decode version number
version.offset = 4;
header.Nodes.Add(version);
var officialCode = ReadByte();
var official = version.RelativeTo("Official = " + (officialCode == 0 ? "yes" : "no"), 1);
header.Nodes.Add(official);
// TODO decode meaning of system params
var systemParam = official.RelativeTo("System params", 6);
header.Nodes.Add(systemParam);
if (versionNumber >= 0x52) {
var conversionErr = systemParam.RelativeTo("data to catch conversation errors", 6);
header.Nodes.Add(conversionErr);
}
// TODO after header comes: function definitions, then opcodes, then constants, then function prototypes, upvalues, debug info,
return res;
}
*/