1 package magic
2
3 import (
4 "bytes"
5 "debug/macho"
6 "encoding/binary"
7 )
8
9 var (
10
11 Lnk = prefix([]byte{0x4C, 0x00, 0x00, 0x00, 0x01, 0x14, 0x02, 0x00})
12
13 Wasm = prefix([]byte{0x00, 0x61, 0x73, 0x6D})
14
15 Exe = prefix([]byte{0x4D, 0x5A})
16
17 Elf = prefix([]byte{0x7F, 0x45, 0x4C, 0x46})
18
19 Nes = prefix([]byte{0x4E, 0x45, 0x53, 0x1A})
20
21 SWF = prefix([]byte("CWS"), []byte("FWS"), []byte("ZWS"))
22
23 Torrent = prefix([]byte("d8:announce"))
24 )
25
26
27
28 func classOrMachOFat(in []byte) bool {
29
30
31 if len(in) < 8 {
32 return false
33 }
34
35 return bytes.HasPrefix(in, []byte{0xCA, 0xFE, 0xBA, 0xBE})
36 }
37
38
39 func Class(raw []byte, limit uint32) bool {
40 return classOrMachOFat(raw) && raw[7] > 30
41 }
42
43
44 func MachO(raw []byte, limit uint32) bool {
45 if classOrMachOFat(raw) && raw[7] < 20 {
46 return true
47 }
48
49 if len(raw) < 4 {
50 return false
51 }
52
53 be := binary.BigEndian.Uint32(raw)
54 le := binary.LittleEndian.Uint32(raw)
55
56 return be == macho.Magic32 ||
57 le == macho.Magic32 ||
58 be == macho.Magic64 ||
59 le == macho.Magic64
60 }
61
62
63
64 func Dbf(raw []byte, limit uint32) bool {
65 if len(raw) < 68 {
66 return false
67 }
68
69
70 if !(0 < raw[2] && raw[2] < 13 && 0 < raw[3] && raw[3] < 32) {
71 return false
72 }
73
74
75 if raw[12] != 0x00 || raw[13] != 0x00 || raw[30] != 0x00 || raw[31] != 0x00 {
76 return false
77 }
78
79
80
81 if raw[28] > 0x01 {
82 return false
83 }
84
85
86 dbfTypes := []byte{
87 0x02, 0x03, 0x04, 0x05, 0x30, 0x31, 0x32, 0x42, 0x62, 0x7B, 0x82,
88 0x83, 0x87, 0x8A, 0x8B, 0x8E, 0xB3, 0xCB, 0xE5, 0xF5, 0xF4, 0xFB,
89 }
90 for _, b := range dbfTypes {
91 if raw[0] == b {
92 return true
93 }
94 }
95
96 return false
97 }
98
99
100 func ElfObj(raw []byte, limit uint32) bool {
101 return len(raw) > 17 && ((raw[16] == 0x01 && raw[17] == 0x00) ||
102 (raw[16] == 0x00 && raw[17] == 0x01))
103 }
104
105
106 func ElfExe(raw []byte, limit uint32) bool {
107 return len(raw) > 17 && ((raw[16] == 0x02 && raw[17] == 0x00) ||
108 (raw[16] == 0x00 && raw[17] == 0x02))
109 }
110
111
112 func ElfLib(raw []byte, limit uint32) bool {
113 return len(raw) > 17 && ((raw[16] == 0x03 && raw[17] == 0x00) ||
114 (raw[16] == 0x00 && raw[17] == 0x03))
115 }
116
117
118 func ElfDump(raw []byte, limit uint32) bool {
119 return len(raw) > 17 && ((raw[16] == 0x04 && raw[17] == 0x00) ||
120 (raw[16] == 0x00 && raw[17] == 0x04))
121 }
122
123
124 func Dcm(raw []byte, limit uint32) bool {
125 return len(raw) > 131 &&
126 bytes.Equal(raw[128:132], []byte{0x44, 0x49, 0x43, 0x4D})
127 }
128
129
130 func Marc(raw []byte, limit uint32) bool {
131
132 if len(raw) < 24 {
133 return false
134 }
135
136
137 if !bytes.Equal(raw[20:24], []byte("4500")) {
138 return false
139 }
140
141
142 for i := 0; i < 5; i++ {
143 if raw[i] < '0' || raw[i] > '9' {
144 return false
145 }
146 }
147
148
149 return bytes.Contains(raw[:min(2048, len(raw))], []byte{0x1E})
150 }
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 var Glb = prefix([]byte("\x67\x6C\x54\x46\x02\x00\x00\x00"),
168 []byte("\x67\x6C\x54\x46\x01\x00\x00\x00"))
169
170
171
172
173
174
175
176
177
178
179
180
181 func TzIf(raw []byte, limit uint32) bool {
182
183 if len(raw) < 44 {
184 return false
185 }
186
187 if !bytes.HasPrefix(raw, []byte("TZif")) {
188 return false
189 }
190
191
192 if binary.BigEndian.Uint32(raw[36:40]) == 0 {
193 return false
194 }
195
196
197 return raw[4] == 0x00 || raw[4] == 0x32 || raw[4] == 0x33
198 }
199
View as plain text