@isopodlabs/binary_libs 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CompoundDocument.d.ts +129 -0
- package/dist/CompoundDocument.js +300 -0
- package/dist/arch.d.ts +26 -0
- package/dist/arch.js +96 -0
- package/dist/clr.d.ts +286 -0
- package/dist/clr.js +658 -0
- package/dist/elf.d.ts +112 -0
- package/dist/elf.js +778 -0
- package/dist/mach.d.ts +394 -0
- package/dist/mach.js +1027 -0
- package/dist/pe.d.ts +156 -0
- package/dist/pe.js +484 -0
- package/package.json +5 -1
- package/.gitmodules +0 -3
- package/.vscode/launch.json +0 -16
- package/.vscode/settings.json +0 -3
- package/.vscode/tasks.json +0 -39
- package/eslint.config.mjs +0 -32
- package/src/CompoundDocument.ts +0 -314
- package/src/arch.ts +0 -79
- package/src/clr.ts +0 -646
- package/src/elf.ts +0 -802
- package/src/mach.ts +0 -1140
- package/src/pe.ts +0 -506
- package/transform.ts +0 -369
- package/tsconfig.json +0 -27
- package/tsconfig.tsbuildinfo +0 -1
package/src/clr.ts
DELETED
|
@@ -1,646 +0,0 @@
|
|
|
1
|
-
import * as binary from '@isopodlabs/binary';
|
|
2
|
-
import * as pe from './pe';
|
|
3
|
-
|
|
4
|
-
//-----------------------------------------------------------------------------
|
|
5
|
-
// CLR
|
|
6
|
-
//-----------------------------------------------------------------------------
|
|
7
|
-
|
|
8
|
-
const HEAP = {
|
|
9
|
-
String: 0,
|
|
10
|
-
GUID: 1,
|
|
11
|
-
Blob: 2,
|
|
12
|
-
UserString: 3,
|
|
13
|
-
} as const;
|
|
14
|
-
|
|
15
|
-
const CLR_FLAGS = {
|
|
16
|
-
FLAGS_ILONLY: 0x00000001,
|
|
17
|
-
FLAGS_32BITREQUIRED: 0x00000002,
|
|
18
|
-
FLAGS_IL_LIBRARY: 0x00000004,
|
|
19
|
-
FLAGS_STRONGNAMESIGNED: 0x00000008,
|
|
20
|
-
FLAGS_NATIVE_ENTRYPOINT: 0x00000010,
|
|
21
|
-
FLAGS_TRACKDEBUGDATA: 0x00010000,
|
|
22
|
-
} as const;
|
|
23
|
-
|
|
24
|
-
const CLR_HEADER = {
|
|
25
|
-
cb: binary.UINT32_LE,
|
|
26
|
-
MajorRuntimeVersion: binary.UINT16_LE,
|
|
27
|
-
MinorRuntimeVersion: binary.UINT16_LE,
|
|
28
|
-
MetaData: pe.DATA_DIRECTORY,
|
|
29
|
-
Flags: binary.asFlags(binary.UINT32_LE, CLR_FLAGS),
|
|
30
|
-
EntryPoint: binary.UINT32_LE,
|
|
31
|
-
Resources: pe.DATA_DIRECTORY,
|
|
32
|
-
StrongNameSignature: pe.DATA_DIRECTORY,
|
|
33
|
-
CodeManagerTable: pe.DATA_DIRECTORY,
|
|
34
|
-
VTableFixups: pe.DATA_DIRECTORY,
|
|
35
|
-
ExportAddressTableJumps: pe.DATA_DIRECTORY,
|
|
36
|
-
//ManagedNativeHeader: pe.DATA_DIRECTORY,
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const STREAM_HDR = {
|
|
40
|
-
Offset: binary.UINT32_LE, // Memory offset to start of this stream from start of the metadata root (§II.24.2.1)
|
|
41
|
-
Size: binary.UINT32_LE, // Size of this stream in bytes, shall be a multiple of 4.
|
|
42
|
-
Name: binary.NullTerminatedStringType, // Name of the stream as null-terminated variable length array of ASCII characters, padded to the next 4-byte boundary with \0 characters. The name is limited to 32 characters.
|
|
43
|
-
unused: binary.AlignType(4),
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const METADATA_ROOT = {
|
|
47
|
-
Signature: binary.UINT32_LE, //'BSJB'
|
|
48
|
-
MajorVersion: binary.UINT16_LE,
|
|
49
|
-
MinorVersion: binary.UINT16_LE,
|
|
50
|
-
Reserved: binary.UINT32_LE, // always 0
|
|
51
|
-
Version: binary.StringType(binary.UINT32_LE, 'utf8', true),
|
|
52
|
-
unknown: binary.UINT16_LE,
|
|
53
|
-
Streams: binary.ArrayType(binary.UINT16_LE, STREAM_HDR)
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const CLR_TABLES = {
|
|
57
|
-
Reserved: binary.UINT32_LE, // Reserved, always 0 (§II.24.1).
|
|
58
|
-
MajorVersion: binary.UINT8, // Major version of table schemata; shall be 2 (§II.24.1).
|
|
59
|
-
MinorVersion: binary.UINT8, // Minor version of table schemata; shall be 0 (§II.24.1).
|
|
60
|
-
HeapSizes: binary.UINT8, // Bit vector for heap sizes.
|
|
61
|
-
Reserved2: binary.UINT8, // Reserved, always 1 (§II.24.1).
|
|
62
|
-
Valid: binary.UINT64_LE, // Bit vector of present tables, let n be the number of bits that are 1.
|
|
63
|
-
Sorted: binary.UINT64_LE, // Bit vector of sorted tables.
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
enum TABLE {
|
|
67
|
-
Module = 0x00,
|
|
68
|
-
TypeRef = 0x01,
|
|
69
|
-
TypeDef = 0x02,
|
|
70
|
-
// Unused = 0x03,
|
|
71
|
-
Field = 0x04,
|
|
72
|
-
// Unused = 0x05,
|
|
73
|
-
MethodDef = 0x06,
|
|
74
|
-
// Unused = 0x07,
|
|
75
|
-
Param = 0x08,
|
|
76
|
-
InterfaceImpl = 0x09,
|
|
77
|
-
MemberRef = 0x0a,
|
|
78
|
-
Constant = 0x0b,
|
|
79
|
-
CustomAttribute = 0x0c,
|
|
80
|
-
FieldMarshal = 0x0d,
|
|
81
|
-
DeclSecurity = 0x0e,
|
|
82
|
-
ClassLayout = 0x0f,
|
|
83
|
-
|
|
84
|
-
FieldLayout = 0x10,
|
|
85
|
-
StandAloneSig = 0x11,
|
|
86
|
-
EventMap = 0x12,
|
|
87
|
-
// Unused = 0x13,
|
|
88
|
-
Event = 0x14,
|
|
89
|
-
PropertyMap = 0x15,
|
|
90
|
-
// Unused = 0x16,
|
|
91
|
-
Property = 0x17,
|
|
92
|
-
MethodSemantics = 0x18,
|
|
93
|
-
MethodImpl = 0x19,
|
|
94
|
-
ModuleRef = 0x1a,
|
|
95
|
-
TypeSpec = 0x1b,
|
|
96
|
-
ImplMap = 0x1c,
|
|
97
|
-
FieldRVA = 0x1d,
|
|
98
|
-
// Unused = 0x1e,
|
|
99
|
-
// Unused = 0x1f,
|
|
100
|
-
|
|
101
|
-
Assembly = 0x20,
|
|
102
|
-
AssemblyProcessor = 0x21,
|
|
103
|
-
AssemblyOS = 0x22,
|
|
104
|
-
AssemblyRef = 0x23,
|
|
105
|
-
AssemblyRefProcessor = 0x24,
|
|
106
|
-
AssemblyRefOS = 0x25,
|
|
107
|
-
File = 0x26,
|
|
108
|
-
ExportedType = 0x27,
|
|
109
|
-
ManifestResource = 0x28,
|
|
110
|
-
NestedClass = 0x29,
|
|
111
|
-
GenericParam = 0x2a,
|
|
112
|
-
MethodSpec = 0x2b,
|
|
113
|
-
GenericParamConstraint = 0x2c,
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function bytesToGuid(bytes: Uint8Array) {
|
|
117
|
-
// Convert each byte to a two-digit hexadecimal string
|
|
118
|
-
const hexArray = Array.from(bytes, byte => ('0' + (byte & 0xFF).toString(16)).slice(-2));
|
|
119
|
-
|
|
120
|
-
// Join the hex strings into the standard GUID format
|
|
121
|
-
return hexArray.slice(0, 4).join('') + '-' +
|
|
122
|
-
hexArray.slice(4, 6).join('') + '-' +
|
|
123
|
-
hexArray.slice(6, 8).join('') + '-' +
|
|
124
|
-
hexArray.slice(8, 10).join('') + '-' +
|
|
125
|
-
hexArray.slice(10, 16).join('');
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
class clr_stream extends binary.stream {
|
|
129
|
-
constructor(buffer: Uint8Array, public heaps:Uint8Array[], public heap_sizes: number, public table_counts: number[]) {
|
|
130
|
-
super(buffer);
|
|
131
|
-
}
|
|
132
|
-
getOffset(big: boolean) {
|
|
133
|
-
return (big ? binary.UINT32_LE : binary.UINT16_LE).get(this);
|
|
134
|
-
}
|
|
135
|
-
getHeap(heap:number) {
|
|
136
|
-
return this.heaps[heap].subarray(this.getOffset(!!(this.heap_sizes & (1 << heap))));
|
|
137
|
-
}
|
|
138
|
-
getIndex(table:number) {
|
|
139
|
-
return this.getOffset(this.table_counts[table] > 0xffff);
|
|
140
|
-
}
|
|
141
|
-
getCodedIndex(B: number, trans:number[]) {
|
|
142
|
-
const thresh = 0xffff >> B;
|
|
143
|
-
for (const i of trans) {
|
|
144
|
-
if (this.table_counts[i] > thresh)
|
|
145
|
-
return binary.UINT32_LE.get(this);
|
|
146
|
-
}
|
|
147
|
-
return binary.UINT16_LE.get(this);
|
|
148
|
-
}
|
|
149
|
-
getString() {
|
|
150
|
-
const mem = this.getHeap(HEAP.String);
|
|
151
|
-
const n = mem.indexOf(0);
|
|
152
|
-
return String.fromCharCode(...mem.subarray(0, n));
|
|
153
|
-
}
|
|
154
|
-
getGUID() {
|
|
155
|
-
return bytesToGuid(this.getHeap(HEAP.GUID));
|
|
156
|
-
}
|
|
157
|
-
getBlob() {
|
|
158
|
-
return this.getHeap(HEAP.Blob);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
class clr_dummy extends binary.dummy {
|
|
162
|
-
constructor(public heap_sizes: number, public table_counts: number[]) {
|
|
163
|
-
super();
|
|
164
|
-
}
|
|
165
|
-
getOffset(big: boolean) {
|
|
166
|
-
return (big ? binary.UINT32_LE : binary.UINT16_LE).get(this);
|
|
167
|
-
}
|
|
168
|
-
getHeap(heap:number) {
|
|
169
|
-
return this.getOffset(!!(this.heap_sizes & (1 << heap)));
|
|
170
|
-
}
|
|
171
|
-
getIndex(table:number) {
|
|
172
|
-
return this.getOffset(this.table_counts[table] > 0xffff);
|
|
173
|
-
}
|
|
174
|
-
getCodedIndex(B: number, trans:number[]) {
|
|
175
|
-
const thresh = 0xffff >> B;
|
|
176
|
-
for (const i of trans) {
|
|
177
|
-
if (this.table_counts[i] > thresh)
|
|
178
|
-
return binary.UINT32_LE.get(this);
|
|
179
|
-
}
|
|
180
|
-
return binary.UINT16_LE.get(this);
|
|
181
|
-
}
|
|
182
|
-
getString() { return this.getHeap(HEAP.String); }
|
|
183
|
-
getGUID() { return this.getHeap(HEAP.GUID); }
|
|
184
|
-
getBlob() { return this.getHeap(HEAP.Blob); }
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const clr_String = {
|
|
188
|
-
get(s: clr_stream) { return s.getString(); },
|
|
189
|
-
put(_s: clr_stream, _v : number) {}
|
|
190
|
-
};
|
|
191
|
-
const clr_GUID = {
|
|
192
|
-
get(s: clr_stream) { return s.getGUID(); },
|
|
193
|
-
put(_s: clr_stream, _v : number) {}
|
|
194
|
-
};
|
|
195
|
-
const clr_Blob = {
|
|
196
|
-
get(s: clr_stream) { return s.getBlob(); },
|
|
197
|
-
put(_s: clr_stream, _v : number) {}
|
|
198
|
-
};
|
|
199
|
-
const Signature = clr_Blob;
|
|
200
|
-
const CustomAttributeValue = clr_Blob;
|
|
201
|
-
|
|
202
|
-
const clr_Code = binary.UINT32_LE;
|
|
203
|
-
|
|
204
|
-
class Indexed {
|
|
205
|
-
constructor(public table:number) {}
|
|
206
|
-
get(s: clr_stream) { return s.getIndex(this.table); }
|
|
207
|
-
}
|
|
208
|
-
class IndexedList extends Indexed {
|
|
209
|
-
get(s: clr_stream) { return s.getIndex(this.table); }
|
|
210
|
-
}
|
|
211
|
-
class CodedIndex {
|
|
212
|
-
constructor(public trans:number[], public B:number) {}
|
|
213
|
-
get(s: clr_stream) { return s.getCodedIndex(this.B, this.trans); }
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const TypeDefOrRef = new CodedIndex([TABLE.TypeDef, TABLE.TypeRef, TABLE.TypeSpec], 2);
|
|
217
|
-
const HasConstant = new CodedIndex([TABLE.Field, TABLE.Param, TABLE.Property], 2);
|
|
218
|
-
const HasCustomAttribute = new CodedIndex([
|
|
219
|
-
TABLE.MethodDef, TABLE.Field, TABLE.TypeRef, TABLE.TypeDef, TABLE.Param, TABLE.InterfaceImpl, TABLE.MemberRef, TABLE.Module, TABLE.DeclSecurity, TABLE.Property, TABLE.Event, TABLE.StandAloneSig,
|
|
220
|
-
TABLE.ModuleRef, TABLE.TypeSpec, TABLE.Assembly, TABLE.AssemblyRef, TABLE.File, TABLE.ExportedType, TABLE.ManifestResource, TABLE.GenericParam, TABLE.GenericParamConstraint, TABLE.MethodSpec,
|
|
221
|
-
], 5);
|
|
222
|
-
const HasFieldMarshall = new CodedIndex([TABLE.Field, TABLE.Param], 1);
|
|
223
|
-
const HasDeclSecurity = new CodedIndex([TABLE.TypeDef, TABLE.MethodDef, TABLE.Assembly], 2);
|
|
224
|
-
const MemberRefParent = new CodedIndex([TABLE.TypeDef, TABLE.TypeRef, TABLE.ModuleRef, TABLE.MethodDef, TABLE.TypeSpec], 1);
|
|
225
|
-
const HasSemantics = new CodedIndex([TABLE.Event, TABLE.Property], 1);
|
|
226
|
-
const MethodDefOrRef = new CodedIndex([TABLE.MethodDef, TABLE.MemberRef], 1);
|
|
227
|
-
const MemberForwarded = new CodedIndex([TABLE.Field, TABLE.MethodDef], 1);
|
|
228
|
-
const Implementation = new CodedIndex([TABLE.File, TABLE.AssemblyRef, TABLE.ExportedType], 2);
|
|
229
|
-
const CustomAttributeType = new CodedIndex([0, 0, TABLE.MethodDef, TABLE.MemberRef], 3);
|
|
230
|
-
const TypeOrMethodDef = new CodedIndex([TABLE.TypeDef, TABLE.MethodDef], 1);
|
|
231
|
-
const ResolutionScope = new CodedIndex([TABLE.Module, TABLE.ModuleRef, TABLE.AssemblyRef, TABLE.TypeRef], 2);
|
|
232
|
-
|
|
233
|
-
const ENTRY_Module = {
|
|
234
|
-
generation: binary.UINT16_LE,
|
|
235
|
-
name: clr_String,
|
|
236
|
-
mvid: clr_GUID,
|
|
237
|
-
encid: clr_GUID,
|
|
238
|
-
encbaseid: clr_GUID,
|
|
239
|
-
};
|
|
240
|
-
const ENTRY_TypeRef = {
|
|
241
|
-
scope: ResolutionScope,
|
|
242
|
-
name: clr_String,
|
|
243
|
-
namespce: clr_String,
|
|
244
|
-
};
|
|
245
|
-
const ENTRY_TypeDef = {
|
|
246
|
-
flags: binary.UINT32_LE,
|
|
247
|
-
name: clr_String,
|
|
248
|
-
namespce: clr_String,
|
|
249
|
-
extends: TypeDefOrRef,
|
|
250
|
-
fields: new IndexedList(TABLE.Field),
|
|
251
|
-
methods: new IndexedList(TABLE.MethodDef),
|
|
252
|
-
};
|
|
253
|
-
const ENTRY_Field = {
|
|
254
|
-
flags: binary.UINT16_LE,
|
|
255
|
-
name: clr_String,
|
|
256
|
-
signature: Signature,
|
|
257
|
-
};
|
|
258
|
-
const ENTRY_MethodDef = {
|
|
259
|
-
code: clr_Code,
|
|
260
|
-
implflags: binary.UINT16_LE,
|
|
261
|
-
flags: binary.UINT16_LE,
|
|
262
|
-
name: clr_String,
|
|
263
|
-
signature: Signature,
|
|
264
|
-
paramlist: new IndexedList(TABLE.Param),
|
|
265
|
-
};
|
|
266
|
-
const ENTRY_Param = {
|
|
267
|
-
flags: binary.UINT16_LE,
|
|
268
|
-
sequence: binary.UINT16_LE,
|
|
269
|
-
name: clr_String,
|
|
270
|
-
};
|
|
271
|
-
const ENTRY_InterfaceImpl = {
|
|
272
|
-
clss: new Indexed(TABLE.TypeDef),
|
|
273
|
-
interfce: TypeDefOrRef,
|
|
274
|
-
};
|
|
275
|
-
const ENTRY_MemberRef = {
|
|
276
|
-
clss: MemberRefParent,
|
|
277
|
-
name: clr_String,
|
|
278
|
-
signature: Signature,
|
|
279
|
-
};
|
|
280
|
-
const ENTRY_Constant = {
|
|
281
|
-
type: binary.UINT16_LE,
|
|
282
|
-
parent: HasConstant,
|
|
283
|
-
value: clr_Blob,
|
|
284
|
-
};
|
|
285
|
-
const ENTRY_CustomAttribute = {
|
|
286
|
-
parent: HasCustomAttribute,
|
|
287
|
-
type: CustomAttributeType,
|
|
288
|
-
value: CustomAttributeValue,
|
|
289
|
-
};
|
|
290
|
-
const ENTRY_FieldMarshal = {
|
|
291
|
-
parent: HasFieldMarshall,
|
|
292
|
-
native_type: clr_Blob,
|
|
293
|
-
};
|
|
294
|
-
const ENTRY_DeclSecurity = {
|
|
295
|
-
action: binary.UINT16_LE,
|
|
296
|
-
parent: HasDeclSecurity,
|
|
297
|
-
permission_set: clr_Blob,
|
|
298
|
-
};
|
|
299
|
-
const ENTRY_ClassLayout = {
|
|
300
|
-
packing_size: binary.UINT16_LE,
|
|
301
|
-
class_size: binary.UINT32_LE,
|
|
302
|
-
parent: new Indexed(TABLE.TypeDef),
|
|
303
|
-
};
|
|
304
|
-
const ENTRY_FieldLayout = {
|
|
305
|
-
offset: binary.UINT32_LE,
|
|
306
|
-
field: new Indexed(TABLE.Field),
|
|
307
|
-
};
|
|
308
|
-
const ENTRY_StandAloneSig = {
|
|
309
|
-
signature: Signature,
|
|
310
|
-
};
|
|
311
|
-
const ENTRY_EventMap = {
|
|
312
|
-
parent: new Indexed(TABLE.TypeDef),
|
|
313
|
-
event_list: new IndexedList(TABLE.Event),
|
|
314
|
-
};
|
|
315
|
-
const ENTRY_Event = {
|
|
316
|
-
flags: binary.UINT16_LE,
|
|
317
|
-
name: clr_String,
|
|
318
|
-
event_type: TypeDefOrRef,
|
|
319
|
-
};
|
|
320
|
-
const ENTRY_PropertyMap = {
|
|
321
|
-
parent: new Indexed(TABLE.TypeDef),
|
|
322
|
-
property_list: new IndexedList(TABLE.Property),
|
|
323
|
-
};
|
|
324
|
-
const ENTRY_Property = {
|
|
325
|
-
flags: binary.UINT16_LE,
|
|
326
|
-
name: clr_String,
|
|
327
|
-
type: Signature,
|
|
328
|
-
};
|
|
329
|
-
const ENTRY_MethodSemantics = {
|
|
330
|
-
flags: binary.UINT16_LE,
|
|
331
|
-
method: new Indexed(TABLE.MethodDef),
|
|
332
|
-
association: HasSemantics,
|
|
333
|
-
};
|
|
334
|
-
const ENTRY_MethodImpl = {
|
|
335
|
-
clss: new Indexed(TABLE.TypeDef),
|
|
336
|
-
method_body: MethodDefOrRef,
|
|
337
|
-
method_declaration: MethodDefOrRef,
|
|
338
|
-
};
|
|
339
|
-
const ENTRY_ModuleRef = {
|
|
340
|
-
name: clr_String,
|
|
341
|
-
};
|
|
342
|
-
const ENTRY_TypeSpec = {
|
|
343
|
-
signature: clr_Blob,
|
|
344
|
-
};
|
|
345
|
-
const ENTRY_ImplMap = {
|
|
346
|
-
flags: binary.UINT16_LE,
|
|
347
|
-
member_forwarded: MemberForwarded,
|
|
348
|
-
name: clr_String,
|
|
349
|
-
scope: new Indexed(TABLE.ModuleRef),
|
|
350
|
-
};
|
|
351
|
-
const ENTRY_FieldRVA = {
|
|
352
|
-
rva: binary.UINT32_LE,
|
|
353
|
-
field: new Indexed(TABLE.Field),
|
|
354
|
-
};
|
|
355
|
-
const ENTRY_Assembly = {
|
|
356
|
-
hashalg: binary.UINT32_LE,
|
|
357
|
-
major: binary.UINT16_LE,
|
|
358
|
-
minor: binary.UINT16_LE,
|
|
359
|
-
build: binary.UINT16_LE,
|
|
360
|
-
rev: binary.UINT16_LE,
|
|
361
|
-
flags: binary.UINT32_LE,
|
|
362
|
-
publickey: clr_Blob,
|
|
363
|
-
name: clr_String,
|
|
364
|
-
culture: clr_String,
|
|
365
|
-
};
|
|
366
|
-
const ENTRY_AssemblyProcessor = {
|
|
367
|
-
processor: binary.UINT32_LE,
|
|
368
|
-
};
|
|
369
|
-
const ENTRY_AssemblyOS = {
|
|
370
|
-
platform: binary.UINT32_LE,
|
|
371
|
-
minor: binary.UINT32_LE,
|
|
372
|
-
major: binary.UINT32_LE,
|
|
373
|
-
};
|
|
374
|
-
const ENTRY_AssemblyRef = {
|
|
375
|
-
major: binary.UINT16_LE,
|
|
376
|
-
minor: binary.UINT16_LE,
|
|
377
|
-
build: binary.UINT16_LE,
|
|
378
|
-
rev: binary.UINT16_LE,
|
|
379
|
-
flags: binary.UINT32_LE,
|
|
380
|
-
publickey: clr_Blob,
|
|
381
|
-
name: clr_String,
|
|
382
|
-
culture: clr_String,
|
|
383
|
-
hashvalue: clr_Blob,
|
|
384
|
-
};
|
|
385
|
-
const ENTRY_AssemblyRefProcessor = {
|
|
386
|
-
processor: binary.UINT32_LE,
|
|
387
|
-
assembly: new Indexed(TABLE.AssemblyRef),
|
|
388
|
-
};
|
|
389
|
-
const ENTRY_AssemblyRefOS = {
|
|
390
|
-
platform: binary.UINT32_LE,
|
|
391
|
-
major: binary.UINT32_LE,
|
|
392
|
-
minor: binary.UINT32_LE,
|
|
393
|
-
assembly: new Indexed(TABLE.AssemblyRef),
|
|
394
|
-
};
|
|
395
|
-
const ENTRY_File = {
|
|
396
|
-
flags: binary.UINT32_LE,
|
|
397
|
-
name: clr_String,
|
|
398
|
-
hash: clr_Blob,
|
|
399
|
-
};
|
|
400
|
-
const ENTRY_ExportedType = {
|
|
401
|
-
flags: binary.UINT32_LE,
|
|
402
|
-
typedef_id: binary.UINT32_LE,//(a 4-byte index into a TypeDef table of another module in this Assembly).
|
|
403
|
-
name: clr_String,
|
|
404
|
-
namespce: clr_String,
|
|
405
|
-
implementation: Implementation,
|
|
406
|
-
};
|
|
407
|
-
const ENTRY_ManifestResource = {
|
|
408
|
-
data: binary.UINT32_LE,
|
|
409
|
-
flags: binary.UINT32_LE,
|
|
410
|
-
name: clr_String,
|
|
411
|
-
implementation: Implementation,
|
|
412
|
-
};
|
|
413
|
-
const ENTRY_NestedClass = {
|
|
414
|
-
nested_class: new Indexed(TABLE.TypeDef),
|
|
415
|
-
enclosing_class: new Indexed(TABLE.TypeDef),
|
|
416
|
-
};
|
|
417
|
-
const ENTRY_GenericParam = {
|
|
418
|
-
number: binary.UINT16_LE,
|
|
419
|
-
flags: binary.UINT16_LE,
|
|
420
|
-
owner: TypeOrMethodDef,
|
|
421
|
-
name: clr_String,
|
|
422
|
-
};
|
|
423
|
-
const ENTRY_MethodSpec = {
|
|
424
|
-
method: MethodDefOrRef,
|
|
425
|
-
instantiation: Signature,
|
|
426
|
-
};
|
|
427
|
-
const ENTRY_GenericParamConstraint = {
|
|
428
|
-
owner: new Indexed(TABLE.GenericParam),
|
|
429
|
-
constraint: TypeDefOrRef,
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
const TableReaders = {
|
|
433
|
-
[TABLE.Module]: ENTRY_Module,
|
|
434
|
-
[TABLE.TypeRef]: ENTRY_TypeRef,
|
|
435
|
-
[TABLE.TypeDef]: ENTRY_TypeDef,
|
|
436
|
-
[TABLE.Field]: ENTRY_Field,
|
|
437
|
-
[TABLE.MethodDef]: ENTRY_MethodDef,
|
|
438
|
-
[TABLE.Param]: ENTRY_Param,
|
|
439
|
-
[TABLE.InterfaceImpl]: ENTRY_InterfaceImpl,
|
|
440
|
-
[TABLE.MemberRef]: ENTRY_MemberRef,
|
|
441
|
-
[TABLE.Constant]: ENTRY_Constant,
|
|
442
|
-
[TABLE.CustomAttribute]: ENTRY_CustomAttribute,
|
|
443
|
-
[TABLE.FieldMarshal]: ENTRY_FieldMarshal,
|
|
444
|
-
[TABLE.DeclSecurity]: ENTRY_DeclSecurity,
|
|
445
|
-
[TABLE.ClassLayout]: ENTRY_ClassLayout,
|
|
446
|
-
[TABLE.FieldLayout]: ENTRY_FieldLayout,
|
|
447
|
-
[TABLE.StandAloneSig]: ENTRY_StandAloneSig,
|
|
448
|
-
[TABLE.EventMap]: ENTRY_EventMap,
|
|
449
|
-
[TABLE.Event]: ENTRY_Event,
|
|
450
|
-
[TABLE.PropertyMap]: ENTRY_PropertyMap,
|
|
451
|
-
[TABLE.Property]: ENTRY_Property,
|
|
452
|
-
[TABLE.MethodSemantics]: ENTRY_MethodSemantics,
|
|
453
|
-
[TABLE.MethodImpl]: ENTRY_MethodImpl,
|
|
454
|
-
[TABLE.ModuleRef]: ENTRY_ModuleRef,
|
|
455
|
-
[TABLE.TypeSpec]: ENTRY_TypeSpec,
|
|
456
|
-
[TABLE.ImplMap]: ENTRY_ImplMap,
|
|
457
|
-
[TABLE.FieldRVA]: ENTRY_FieldRVA,
|
|
458
|
-
[TABLE.Assembly]: ENTRY_Assembly,
|
|
459
|
-
[TABLE.AssemblyProcessor]: ENTRY_AssemblyProcessor,
|
|
460
|
-
[TABLE.AssemblyOS]: ENTRY_AssemblyOS,
|
|
461
|
-
[TABLE.AssemblyRef]: ENTRY_AssemblyRef,
|
|
462
|
-
[TABLE.AssemblyRefProcessor]: ENTRY_AssemblyRefProcessor,
|
|
463
|
-
[TABLE.AssemblyRefOS]: ENTRY_AssemblyRefOS,
|
|
464
|
-
[TABLE.File]: ENTRY_File,
|
|
465
|
-
[TABLE.ExportedType]: ENTRY_ExportedType,
|
|
466
|
-
[TABLE.ManifestResource]: ENTRY_ManifestResource,
|
|
467
|
-
[TABLE.NestedClass]: ENTRY_NestedClass,
|
|
468
|
-
[TABLE.GenericParam]: ENTRY_GenericParam,
|
|
469
|
-
[TABLE.MethodSpec]: ENTRY_MethodSpec,
|
|
470
|
-
[TABLE.GenericParamConstraint]: ENTRY_GenericParamConstraint,
|
|
471
|
-
};
|
|
472
|
-
|
|
473
|
-
const ResourceManagerHeader = {
|
|
474
|
-
magic: binary.UINT32_LE,
|
|
475
|
-
version: binary.UINT32_LE,
|
|
476
|
-
skip: binary.UINT32_LE,
|
|
477
|
-
};
|
|
478
|
-
|
|
479
|
-
const ResourceManager = {
|
|
480
|
-
reader: binary.StringType(binary.UINT8),// Class name of IResourceReader to parse this file
|
|
481
|
-
set: binary.StringType(binary.UINT8),// Class name of ResourceSet to parse this file
|
|
482
|
-
version: binary.UINT32_LE,
|
|
483
|
-
num_resources: binary.UINT32_LE,
|
|
484
|
-
types: binary.ArrayType(binary.UINT32_LE, binary.StringType(binary.UINT8)),
|
|
485
|
-
};
|
|
486
|
-
|
|
487
|
-
const ResourceEntry = {
|
|
488
|
-
name: binary.StringType(binary.UINT8, 'utf16le', false, 1),
|
|
489
|
-
offset: binary.UINT32_LE,
|
|
490
|
-
};
|
|
491
|
-
|
|
492
|
-
interface Table { count: number, size: number, offset: number }
|
|
493
|
-
|
|
494
|
-
export class CLR {
|
|
495
|
-
header: any;
|
|
496
|
-
table_info: any;
|
|
497
|
-
heaps: Uint8Array[] = [];
|
|
498
|
-
tables!: Record<TABLE, Table>;
|
|
499
|
-
raw?: Uint8Array;
|
|
500
|
-
Resources?: Uint8Array;
|
|
501
|
-
/*
|
|
502
|
-
static async load(dll: string) {
|
|
503
|
-
const p = await pe.PE.load(dll);
|
|
504
|
-
if (p) {
|
|
505
|
-
const clr_data = p.GetDataDir(p.opt.DataDirectory.CLR_DESCRIPTOR);
|
|
506
|
-
if (clr_data)
|
|
507
|
-
return new CLR(p, clr_data);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
*/
|
|
511
|
-
constructor(pe: pe.PE, clr_data: Uint8Array) {
|
|
512
|
-
this.header = binary.read(new binary.stream(clr_data), CLR_HEADER);
|
|
513
|
-
const meta_data = pe.GetDataDir(this.header.MetaData);
|
|
514
|
-
const meta_root = meta_data && binary.read(new binary.stream(meta_data.data), METADATA_ROOT);
|
|
515
|
-
|
|
516
|
-
if (meta_root?.Signature != binary.utils.stringCode('BSJB'))
|
|
517
|
-
throw new Error("Invalid CLR");
|
|
518
|
-
|
|
519
|
-
let table_data;
|
|
520
|
-
|
|
521
|
-
for (const h of meta_root!.Streams) {
|
|
522
|
-
const mem = meta_data!.data.subarray(h.Offset, h.Offset + h.Size);
|
|
523
|
-
switch (h.Name) {
|
|
524
|
-
case "#~": table_data = mem; break;
|
|
525
|
-
case "#Strings": this.heaps[HEAP.String] = mem; break;
|
|
526
|
-
case "#US": this.heaps[HEAP.UserString] = mem; break;
|
|
527
|
-
case "#GUID": this.heaps[HEAP.GUID] = mem; break;
|
|
528
|
-
case "#Blob": this.heaps[HEAP.Blob] = mem; break;
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
if (table_data) {
|
|
533
|
-
const stream = new binary.stream(table_data);
|
|
534
|
-
this.table_info = binary.read(stream, CLR_TABLES);
|
|
535
|
-
const table_counts: number[] = [];
|
|
536
|
-
|
|
537
|
-
//read counts
|
|
538
|
-
for (let b = this.table_info.Valid; b; b = binary.utils.clearLowest(b)) {
|
|
539
|
-
const i = binary.utils.lowestSetIndex(b);
|
|
540
|
-
table_counts[i] = binary.UINT32_LE.get(stream);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
this.raw = stream.remainder();
|
|
544
|
-
const stream1 = new clr_dummy(this.table_info.HeapSizes, table_counts);
|
|
545
|
-
let offset = 0;
|
|
546
|
-
|
|
547
|
-
for (let b = this.table_info.Valid; b; b = binary.utils.clearLowest(b)) {
|
|
548
|
-
const i = binary.utils.lowestSetIndex(b) as TABLE;
|
|
549
|
-
stream1.seek(0);
|
|
550
|
-
binary.read(stream1, TableReaders[i]);
|
|
551
|
-
this.tables[i] = {offset, count: table_counts[i], size: stream1.tell()};
|
|
552
|
-
offset += this.tables[i]!.size * this.tables[i]!.count;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
this.Resources = pe.GetDataDir(this.header.Resources)?.data;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
getEntry(t: TABLE, i: number) : any {
|
|
560
|
-
const table = this.tables[t];
|
|
561
|
-
if (table) {
|
|
562
|
-
const stream2 = new clr_stream(this.raw!, this.heaps, this.table_info.HeapSizes, Object.values(this.tables).map(i => i.count));
|
|
563
|
-
stream2.seek(table.offset + i * table.size);
|
|
564
|
-
return binary.read(stream2, TableReaders[t]);
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
getTable<T extends TABLE> (t: T): binary.ReadType<typeof TableReaders[T]>[];
|
|
569
|
-
getTable(t: TABLE) {
|
|
570
|
-
const table = this.tables[t];
|
|
571
|
-
if (table) {
|
|
572
|
-
const stream2 = new clr_stream(this.raw!, this.heaps, this.table_info.HeapSizes, Object.values(this.tables).map(i => i.count));
|
|
573
|
-
stream2.seek(table.offset);
|
|
574
|
-
const result: any[] = [];
|
|
575
|
-
for (let i = 0; i < table.count; i++)
|
|
576
|
-
result.push(binary.read(stream2, TableReaders[t]));
|
|
577
|
-
return result;
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
getResources(block: string) {
|
|
582
|
-
if (this.Resources) {
|
|
583
|
-
for (const i of this.getTable(TABLE.ManifestResource)!) {
|
|
584
|
-
if (i.name == block) {
|
|
585
|
-
const data0 = new binary.stream(this.Resources.subarray(i.data));
|
|
586
|
-
const size = binary.UINT32_LE.get(data0);
|
|
587
|
-
return getResources(data0.read_buffer(size));
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
getResource(block: string, name: string) {
|
|
594
|
-
return this.getResources(block)?.[name];
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
allResources() {
|
|
598
|
-
if (this.Resources) {
|
|
599
|
-
const result = {};
|
|
600
|
-
for (const i of this.getTable(TABLE.ManifestResource)!) {
|
|
601
|
-
const data0 = new binary.stream(this.Resources.subarray(i.data));
|
|
602
|
-
const size = binary.UINT32_LE.get(data0);
|
|
603
|
-
const resources = getResources(data0.read_buffer(size));
|
|
604
|
-
if (resources)
|
|
605
|
-
Object.assign(result, resources);
|
|
606
|
-
}
|
|
607
|
-
return result;
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
function getResources(data: Uint8Array) {
|
|
613
|
-
const stream = new binary.stream(data);
|
|
614
|
-
const manager0 = binary.read(stream, ResourceManagerHeader);
|
|
615
|
-
if (manager0.magic == 0xBEEFCACE) {
|
|
616
|
-
const manager = binary.read_more(stream, ResourceManager, manager0);
|
|
617
|
-
stream.align(8);
|
|
618
|
-
const hashes = binary.readn(stream, binary.UINT32_LE, manager.num_resources);
|
|
619
|
-
const offsets = binary.readn(stream, binary.UINT32_LE, manager.num_resources);
|
|
620
|
-
const start = binary.UINT32_LE.get(stream);
|
|
621
|
-
const entries = binary.readn(stream, ResourceEntry, manager.num_resources);
|
|
622
|
-
|
|
623
|
-
const resources : Record<string, any> = {};
|
|
624
|
-
const decoder = new TextDecoder('utf-8');
|
|
625
|
-
for (let j = 0; j < manager.num_resources; j++) {
|
|
626
|
-
const from = start + entries[j].offset;
|
|
627
|
-
resources[entries[j].name] = data[from] == 1
|
|
628
|
-
? decoder.decode(data.subarray(from + 2, from + 2 + data[from + 1]))
|
|
629
|
-
: data.subarray(from, j < manager.num_resources - 1 ? start + entries[j + 1].offset : data.length);
|
|
630
|
-
}
|
|
631
|
-
return resources;
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
// hook into PE reader
|
|
636
|
-
|
|
637
|
-
pe.DIRECTORIES.CLR_DESCRIPTOR.read = (pe: pe.PE, data: binary.MappedMemory) => {
|
|
638
|
-
function fix_names(table: any[]) {
|
|
639
|
-
if ('name' in table[0])
|
|
640
|
-
return Object.fromEntries(table.map(i => [i.name, i]));
|
|
641
|
-
return table;
|
|
642
|
-
}
|
|
643
|
-
const clr = new CLR(pe, data.data);
|
|
644
|
-
return Object.fromEntries(Object.entries(clr.tables).map(([k, v]) => [TABLE[+k], fix_names(clr.getTable(+k)!)]));
|
|
645
|
-
};
|
|
646
|
-
|