@isopodlabs/binary_libs 0.0.1

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/src/pe.ts ADDED
@@ -0,0 +1,510 @@
1
+ import * as binary from '@isopodlabs/binary';
2
+
3
+ class MyDate extends Date {
4
+ constructor(x: number) { super(x * 1000); }
5
+ valueOf() { return this.getTime() / 1000; }
6
+ toString() { return super.toString(); }
7
+ }
8
+
9
+ const TIMEDATE = binary.as(binary.UINT32_LE, MyDate);
10
+
11
+
12
+ //-----------------------------------------------------------------------------
13
+ // COFF
14
+ //-----------------------------------------------------------------------------
15
+
16
+ const DOS_HEADER = {
17
+ magic: binary.UINT16_LE,
18
+ cblp: binary.UINT16_LE,
19
+ cp: binary.UINT16_LE,
20
+ crlc: binary.UINT16_LE,
21
+ cparhdr: binary.UINT16_LE,
22
+ minalloc: binary.UINT16_LE,
23
+ maxalloc: binary.XINT16_LE,
24
+ ss: binary.UINT16_LE,
25
+ sp: binary.UINT16_LE,
26
+ csum: binary.UINT16_LE,
27
+ ip: binary.UINT16_LE,
28
+ cs: binary.UINT16_LE,
29
+ lfarlc: binary.UINT16_LE,
30
+ ovno: binary.UINT16_LE,
31
+ };
32
+
33
+ const EXE_HEADER = {
34
+ res: binary.ArrayType(4, binary.UINT16_LE),
35
+ oemid: binary.UINT16_LE,
36
+ oeminfo: binary.UINT16_LE,
37
+ res2: binary.ArrayType(10, binary.UINT16_LE),
38
+ lfanew: binary.INT32_LE,
39
+ };
40
+
41
+ //-----------------------------------------------------------------------------
42
+ // PE
43
+ //-----------------------------------------------------------------------------
44
+
45
+ export class pe_stream extends binary.stream {
46
+ constructor(public pe: PE, data: Uint8Array) {
47
+ super(data);
48
+ }
49
+ get_rva() { return this.pe.GetDataRVA(binary.UINT32_LE.get(this))?.data; }
50
+ }
51
+
52
+ const RVA_STRING = {
53
+ get(s: pe_stream) { return binary.utils.decodeTextTo0(s.get_rva(), 'utf8'); },
54
+ put(s: pe_stream) {}
55
+ };
56
+ const RVA_ARRAY16 = {
57
+ get(s: pe_stream) { return binary.utils.to16(s.get_rva()); },
58
+ put(s: pe_stream) {}
59
+ };
60
+ const RVA_ARRAY32 = {
61
+ get(s: pe_stream) { return binary.utils.to32(s.get_rva()); },
62
+ put(s: pe_stream) {}
63
+ };
64
+ const RVA_ARRAY64 = {
65
+ get(s: pe_stream) { return binary.utils.to64(s.get_rva()); },
66
+ put(s: pe_stream) {}
67
+ };
68
+
69
+ const FILE_HEADER = {
70
+ Machine: binary.UINT16_LE,
71
+ NumberOfSections: binary.UINT16_LE,
72
+ TimeDateStamp: binary.UINT32_LE,
73
+ PointerToSymbolTable: binary.UINT32_LE,
74
+ NumberOfSymbols: binary.UINT32_LE,
75
+ SizeOfOptionalHeader: binary.UINT16_LE,
76
+ Characteristics: binary.UINT16_LE,
77
+ };
78
+
79
+ enum SECTION_CHARACTERISTICS {
80
+ // = 0x00000000,
81
+ // = 0x00000001,
82
+ // = 0x00000002,
83
+ // = 0x00000004,
84
+ TYPE_NO_PAD = 0x00000008,
85
+ // = 0x00000010,
86
+ CNT_CODE = 0x00000020,
87
+ CNT_INITIALIZED_DATA = 0x00000040,
88
+ CNT_UNINITIALIZED_DATA = 0x00000080,
89
+ LNK_OTHER = 0x00000100,
90
+ LNK_INFO = 0x00000200,
91
+ // = 0x00000400,
92
+ LNK_REMOVE = 0x00000800,
93
+ LNK_COMDAT = 0x00001000,
94
+ GPREL = 0x00008000,
95
+ // MEM_PURGEABLE = 0x00020000,
96
+ MEM_16BIT = 0x00020000,
97
+ MEM_LOCKED = 0x00040000,
98
+ MEM_PRELOAD = 0x00080000,
99
+ ALIGN = 0x00f00000,
100
+ //ALIGN_1BYTES = 0x00100000,
101
+ //ALIGN_2BYTES = 0x00200000,
102
+ //ALIGN_4BYTES = 0x00300000,
103
+ //ALIGN_8BYTES = 0x00400000,
104
+ //ALIGN_16BYTES = 0x00500000,
105
+ //ALIGN_32BYTES = 0x00600000,
106
+ //ALIGN_64BYTES = 0x00700000,
107
+ //ALIGN_128BYTES = 0x00800000,
108
+ //ALIGN_256BYTES = 0x00900000,
109
+ //ALIGN_512BYTES = 0x00A00000,
110
+ //ALIGN_1024BYTES = 0x00B00000,
111
+ //ALIGN_2048BYTES = 0x00C00000,
112
+ //ALIGN_4096BYTES = 0x00D00000,
113
+ //ALIGN_8192BYTES = 0x00E00000,
114
+ LNK_NRELOC_OVFL = 0x01000000,
115
+ MEM_DISCARDABLE = 0x02000000,
116
+ MEM_NOT_CACHED = 0x04000000,
117
+ MEM_NOT_PAGED = 0x08000000,
118
+ MEM_SHARED = 0x10000000,
119
+ MEM_EXECUTE = 0x20000000,
120
+ MEM_READ = 0x40000000,
121
+ MEM_WRITE = 0x80000000,
122
+ }
123
+
124
+ class Section extends binary.ReadStruct({
125
+ Name: binary.StringType(8),
126
+ VirtualSize: binary.UINT32_LE,
127
+ VirtualAddress: binary.XINT32_LE,
128
+ SizeOfRawData: binary.UINT32_LE,
129
+ PointerToRawData: binary.XINT32_LE,
130
+ PointerToRelocations: binary.XINT32_LE,
131
+ PointerToLinenumbers: binary.XINT32_LE,
132
+ NumberOfRelocations: binary.INT16_LE,
133
+ NumberOfLinenumbers: binary.INT16_LE,
134
+ Characteristics: binary.asFlags(binary.UINT32_LE, SECTION_CHARACTERISTICS)
135
+ }) {
136
+ data?: binary.utils.MappedMemory;
137
+ constructor(r: binary.stream) {
138
+ super(r);
139
+ try {
140
+ this.data = new binary.utils.MappedMemory(r.buffer_at(+this.PointerToRawData, this.SizeOfRawData), +this.VirtualAddress, this.flags);
141
+ } catch (e) {
142
+ console.log(e);
143
+ }
144
+ }
145
+ get flags() {
146
+ return binary.utils.MEM.RELATIVE
147
+ | (this.Characteristics.MEM_READ ? binary.utils.MEM.READ : 0)
148
+ | (this.Characteristics.MEM_WRITE ? binary.utils.MEM.WRITE : 0)
149
+ | (this.Characteristics.MEM_EXECUTE ? binary.utils.MEM.EXECUTE : 0);
150
+ }
151
+ }
152
+
153
+ interface DirectoryInfo {
154
+ read?: (pe: PE, data: binary.utils.MappedMemory) => any;
155
+ }
156
+
157
+ export const DIRECTORIES : Record<string, DirectoryInfo> = {
158
+ EXPORT: {read: (pe, data) => ReadExports(new pe_stream(pe, data.data)) },
159
+ IMPORT: {read: (pe, data) => ReadImports(new pe_stream(pe, data.data)) },
160
+ RESOURCE: {read: (pe, data) => ReadResourceDirectory(new binary.stream(data.data), data)},
161
+ EXCEPTION: {}, // Exception Directory
162
+ SECURITY: {}, // Security Directory
163
+ BASERELOC: {}, // Base Relocation Table
164
+ DEBUG_DIR: {}, // Debug Directory
165
+ ARCHITECTURE: {}, // Architecture Specific Data
166
+ GLOBALPTR: {}, // RVA of GP
167
+ TLS: {},
168
+ LOAD_CONFIG: {}, // Load Configuration Directory
169
+ BOUND_IMPORT: {}, // Bound Import Directory in headers
170
+ IAT: {}, // Import Address Table
171
+ DELAY_IMPORT: {},
172
+ CLR_DESCRIPTOR: {},
173
+ };
174
+
175
+ export const DATA_DIRECTORY = {
176
+ VirtualAddress: binary.UINT32_LE,
177
+ Size: binary.UINT32_LE,
178
+ };
179
+
180
+ type Directory = binary.ReadType<typeof DATA_DIRECTORY>;
181
+
182
+ const MAGIC = {
183
+ NT32: 0x10b,
184
+ NT64: 0x20b,
185
+ ROM: 0x107,
186
+ OBJ: 0x104, // object files, eg as output
187
+ // DEMAND: 0x10b, // demand load format, eg normal ld output
188
+ TARGET: 0x101, // target shlib
189
+ HOST: 0x123, // host shlib
190
+ };
191
+
192
+ const DLLCHARACTERISTICS = {
193
+ DYNAMIC_BASE: 0x0040, // DLL can be relocated at load time (ASLR)
194
+ FORCE_INTEGRITY: 0x0080, // Code integrity checks are enforced
195
+ NX_COMPAT: 0x0100, // Image is NX compatible (DEP)
196
+ NO_ISOLATION: 0x0200, // Isolation aware, but do not isolate the image
197
+ NO_SEH: 0x0400, // Does not use structured exception handling
198
+ NO_BIND: 0x0800, // Do not bind the image
199
+ WDM_DRIVER: 0x2000, // Driver uses WDM model
200
+ TERMINAL_SERVER_AWARE: 0x8000, // Terminal Server aware
201
+ };
202
+
203
+ const OPTIONAL_HEADER = {
204
+ Magic: binary.asEnum(binary.UINT16_LE, MAGIC),
205
+ MajorLinkerVersion: binary.UINT8,
206
+ MinorLinkerVersion: binary.UINT8,
207
+ SizeOfCode: binary.UINT32_LE,
208
+ SizeOfInitializedData: binary.UINT32_LE,
209
+ SizeOfUninitializedData: binary.UINT32_LE,
210
+ AddressOfEntryPoint: binary.XINT32_LE,
211
+ BaseOfCode: binary.XINT32_LE,
212
+ };
213
+
214
+ const OPTIONAL_HEADER32 = {
215
+ BaseOfData: binary.XINT32_LE,
216
+ ImageBase: binary.XINT32_LE,
217
+ SectionAlignment: binary.UINT32_LE,
218
+ FileAlignment: binary.UINT32_LE,
219
+ MajorOperatingSystemVersion:binary.UINT16_LE,
220
+ MinorOperatingSystemVersion:binary.UINT16_LE,
221
+ MajorImageVersion: binary.UINT16_LE,
222
+ MinorImageVersion: binary.UINT16_LE,
223
+ MajorSubsystemVersion: binary.UINT16_LE,
224
+ MinorSubsystemVersion: binary.UINT16_LE,
225
+ Win32VersionValue: binary.UINT32_LE,
226
+ SizeOfImage: binary.UINT32_LE,
227
+ SizeOfHeaders: binary.UINT32_LE,
228
+ CheckSum: binary.UINT32_LE,
229
+ Subsystem: binary.UINT16_LE,
230
+ DllCharacteristics: binary.asFlags(binary.UINT16_LE, DLLCHARACTERISTICS),
231
+ SizeOfStackReserve: binary.UINT32_LE,
232
+ SizeOfStackCommit: binary.UINT32_LE,
233
+ SizeOfHeapReserve: binary.UINT32_LE,
234
+ SizeOfHeapCommit: binary.UINT32_LE,
235
+ LoaderFlags: binary.UINT32_LE,
236
+ DataDirectory: binary.objectWithNames(binary.ArrayType(binary.UINT32_LE, DATA_DIRECTORY), binary.names(Object.keys(DIRECTORIES))),
237
+ };
238
+
239
+ const OPTIONAL_HEADER64 = {
240
+ ImageBase: binary.XINT64_LE,
241
+ SectionAlignment: binary.UINT32_LE,
242
+ FileAlignment: binary.UINT32_LE,
243
+ MajorOperatingSystemVersion:binary.UINT16_LE,
244
+ MinorOperatingSystemVersion:binary.UINT16_LE,
245
+ MajorImageVersion: binary.UINT16_LE,
246
+ MinorImageVersion: binary.UINT16_LE,
247
+ MajorSubsystemVersion: binary.UINT16_LE,
248
+ MinorSubsystemVersion: binary.UINT16_LE,
249
+ Win32VersionValue: binary.UINT32_LE,
250
+ SizeOfImage: binary.UINT32_LE,
251
+ SizeOfHeaders: binary.UINT32_LE,
252
+ CheckSum: binary.UINT32_LE,
253
+ Subsystem: binary.UINT16_LE,
254
+ DllCharacteristics: binary.asFlags(binary.UINT16_LE, DLLCHARACTERISTICS),
255
+ SizeOfStackReserve: binary.UINT64_LE,
256
+ SizeOfStackCommit: binary.UINT64_LE,
257
+ SizeOfHeapReserve: binary.UINT64_LE,
258
+ SizeOfHeapCommit: binary.UINT64_LE,
259
+ LoaderFlags: binary.UINT32_LE,
260
+ DataDirectory: binary.objectWithNames(binary.ArrayType(binary.UINT32_LE, DATA_DIRECTORY), binary.names(Object.keys(DIRECTORIES))),
261
+ };
262
+
263
+ export class PE {
264
+ header: binary.ReadType<typeof DOS_HEADER> & binary.ReadType<typeof EXE_HEADER>;
265
+ sections: Section[];
266
+ opt?: binary.ReadType<typeof OPTIONAL_HEADER> & (binary.ReadType<typeof OPTIONAL_HEADER32> | binary.ReadType<typeof OPTIONAL_HEADER64>);
267
+
268
+ static check(data: Uint8Array): boolean {
269
+ return binary.UINT16_LE.get(new binary.stream(data)) === binary.utils.stringCode("MZ");
270
+ }
271
+
272
+ constructor(private data: Uint8Array) {
273
+ const file = new binary.stream(data);
274
+ this.header = binary.read(file, {...DOS_HEADER, ...EXE_HEADER});
275
+
276
+ file.seek(this.header.lfanew);
277
+ if (binary.UINT32_LE.get(file) == binary.utils.stringCode("PE\0\0")) {
278
+ const h = binary.read(file, FILE_HEADER);
279
+
280
+ if (h.SizeOfOptionalHeader) {
281
+ const opt = new binary.stream(file.read_buffer(h.SizeOfOptionalHeader));
282
+ const opt1 = binary.read(opt, OPTIONAL_HEADER);
283
+ if (opt1.Magic == 'NT32')
284
+ this.opt = binary.read_more(opt, OPTIONAL_HEADER32, opt1);
285
+ else if (opt1.Magic == 'NT64')
286
+ this.opt = binary.read_more(opt, OPTIONAL_HEADER64, opt1);
287
+ }
288
+
289
+ this.sections = Array.from({length: h.NumberOfSections}, () => new Section(file));
290
+ } else {
291
+ this.sections = [];
292
+ }
293
+ }
294
+
295
+ get directories() {
296
+ return this.opt?.DataDirectory;
297
+ }
298
+
299
+ FindSectionRVA(rva: number) {
300
+ for (const i of this.sections) {
301
+ if (rva >= +i.VirtualAddress && rva < +i.VirtualAddress + i.SizeOfRawData)
302
+ return i;
303
+ }
304
+ }
305
+
306
+ FindSectionRaw(addr: number) {
307
+ for (const i of this.sections) {
308
+ if (addr >= +i.PointerToRawData && addr < +i.PointerToRawData + i.SizeOfRawData)
309
+ return i;
310
+ }
311
+ }
312
+
313
+ GetDataRVA(rva: number, size?: number) {
314
+ const sect = this.FindSectionRVA(rva);
315
+ if (sect && sect.data)
316
+ return sect.data.at(rva, size);
317
+ }
318
+ GetDataRaw(addr: number, size: number) {
319
+ const sect = this.FindSectionRaw(addr);
320
+ if (sect && sect.data) {
321
+ const offset = addr - +sect.PointerToRawData;
322
+ return sect.data.data.subarray(offset, offset + size);
323
+ }
324
+ }
325
+ GetDataDir(dir: Directory) {
326
+ if (dir.Size)
327
+ return this.GetDataRVA(dir.VirtualAddress, dir.Size);
328
+ }
329
+
330
+ ReadDirectory(name: string) {
331
+ const dir = this.opt?.DataDirectory[name];
332
+ if (dir?.Size) {
333
+ const data = this.GetDataDir(dir);
334
+ const info = DIRECTORIES[name];
335
+ if (data && info?.read)
336
+ return info.read(this, data);
337
+ return data;
338
+ }
339
+ }
340
+ }
341
+
342
+
343
+ //-----------------------------------------------------------------------------
344
+ // exports
345
+ //-----------------------------------------------------------------------------
346
+
347
+ const EXPORT_DIRECTORY = {
348
+ ExportFlags: binary.UINT32_LE, // Reserved, must be 0.
349
+ TimeDateStamp: TIMEDATE, // The time and date that the export data was created.
350
+ MajorVersion: binary.XINT16_LE, // The major version number. The major and minor version numbers can be set by the user.
351
+ MinorVersion: binary.XINT16_LE, // The minor version number.
352
+ DLLName: RVA_STRING, // The address of the ASCII string that contains the name of the DLL. This address is relative to the image base.
353
+ OrdinalBase: binary.UINT32_LE, // The starting ordinal number for exports in this image. This field specifies the starting ordinal number for the export address table. It is usually set to 1.
354
+ NumberEntries: binary.UINT32_LE, // The number of entries in the export address table.
355
+ NumberNames: binary.UINT32_LE, // The number of entries in the name pointer table. This is also the number of entries in the ordinal table.
356
+ FunctionTable: RVA_ARRAY32, // RVA of functions
357
+ NameTable: RVA_ARRAY32, // RVA of names
358
+ OrdinalTable: RVA_ARRAY16, // RVA from base of image
359
+ };
360
+
361
+ interface ExportEntry {
362
+ ordinal: number;
363
+ name: string;
364
+ address: number;
365
+ }
366
+
367
+ export function ReadExports(file: pe_stream) {
368
+ const dir = binary.read(file, EXPORT_DIRECTORY);
369
+ const addresses = dir.FunctionTable!;
370
+ const names = dir.NameTable;
371
+ const ordinals = dir.OrdinalTable;
372
+
373
+ const result: ExportEntry[] = [];
374
+ for (let i = 0; i < dir.NumberEntries; i++) {
375
+ const sect = file.pe.FindSectionRVA(addresses[i]);
376
+ if (sect) {
377
+ const ordinal = (ordinals && i < dir.NumberNames ? ordinals[i] : i) + dir.OrdinalBase;
378
+ const name = names && i < dir.NumberNames ? binary.utils.decodeTextTo0(file.pe.GetDataRVA(names[i])?.data, 'utf8') : '';
379
+ result.push({ordinal, name, address: addresses[i]});
380
+ }
381
+ }
382
+ const sorted = result.sort((a, b)=> a.address - b.address);
383
+ return sorted.map((v, i) => {
384
+ let j = i;
385
+ while (++j < sorted.length && sorted[j].address == v.address);
386
+ return [v.ordinal, v.name, file.pe.GetDataRVA(v.address, j < sorted.length ? sorted[j].address - v.address : undefined)];
387
+ });
388
+ }
389
+
390
+ //-----------------------------------------------------------------------------
391
+ // imports
392
+ //-----------------------------------------------------------------------------
393
+
394
+ export class DLLImports extends Array {}
395
+
396
+ const RVA_ITA64 = {
397
+ get(s: pe_stream) {
398
+ const r = binary.utils.to64(s.get_rva());
399
+ if (r) {
400
+ const result = Array.from(r.subarray(0, r.indexOf(0n)), i =>
401
+ i >> 63n
402
+ ? `ordinal_${i - (1n << 63n)}`
403
+ : binary.utils.decodeTextTo0(s.pe.GetDataRVA(Number(i))?.data.subarray(2), 'utf8')
404
+ );
405
+ Object.setPrototypeOf(result, DLLImports.prototype);
406
+ return result;
407
+ }
408
+ },
409
+ put(s: pe_stream) {}
410
+ };
411
+
412
+ const IMPORT_DESCRIPTOR = {
413
+ Characteristics: binary.UINT32_LE, // 0 for terminating null import descriptor
414
+ TimeDateStamp: TIMEDATE, // 0 if not bound, -1 if bound, and real date\time stamp in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) // O.W. date/time stamp of DLL bound to (Old BIND)
415
+ ForwarderChain: binary.UINT32_LE, // -1 if no forwarders
416
+ DllName: RVA_STRING,//binary.UINT32_LE,
417
+ FirstThunk: RVA_ITA64,//binary.UINT32_LE, // RVA to IAT (if bound this IAT has actual addresses)
418
+ };
419
+
420
+ export function ReadImports(file: pe_stream) {
421
+ const result: [string, any][] = [];
422
+ while (file.remaining()) {
423
+ const r = binary.read(file, IMPORT_DESCRIPTOR);
424
+ if (!r.Characteristics)
425
+ break;
426
+ result.push([r.DllName, r.FirstThunk]);
427
+ }
428
+ return result;
429
+ }
430
+
431
+ //-----------------------------------------------------------------------------
432
+ // resources
433
+ //-----------------------------------------------------------------------------
434
+
435
+ const RESOURCE_DIRECTORY_ENTRY = {
436
+ get(s: binary.stream) {
437
+ const u0 = binary.UINT32_LE.get(s);
438
+ const u1 = binary.UINT32_LE.get(s);
439
+ return [u0, u1];
440
+ },
441
+ put(s: binary.stream) {}
442
+
443
+ };
444
+
445
+ class RESOURCE_DATA_ENTRY extends binary.ReadStruct({
446
+ OffsetToData: binary.UINT32_LE,
447
+ Size: binary.UINT32_LE,
448
+ CodePage: binary.UINT32_LE,
449
+ Reserved: binary.UINT32_LE,
450
+ }) {
451
+ data: Uint8Array;
452
+ constructor(file: binary.stream, data: binary.utils.MappedMemory) {
453
+ super(file);
454
+ this.data = data.slice(this.OffsetToData, this.OffsetToData + this.Size).data;
455
+ }
456
+ }
457
+
458
+ const RESOURCE_DIRECTORY = {
459
+ Characteristics: binary.UINT32_LE,
460
+ TimeDateStamp: binary.UINT32_LE,
461
+ MajorVersion: binary.UINT16_LE,
462
+ MinorVersion: binary.UINT16_LE,
463
+ NumberOfNamedEntries: binary.UINT16_LE,
464
+ NumberOfIdEntries: binary.UINT16_LE,
465
+ };
466
+
467
+ enum IRT {
468
+ NONE = 0,
469
+ CURSOR = 1,
470
+ BITMAP = 2,
471
+ ICON = 3,
472
+ MENU = 4,
473
+ DIALOG = 5,
474
+ STRING = 6,
475
+ FONTDIR = 7,
476
+ FONT = 8,
477
+ ACCELERATOR = 9,
478
+ RCDATA = 10,
479
+ MESSAGETABLE = 11,
480
+ GROUP_CURSOR = 12,
481
+ GROUP_ICON = 14,
482
+ VERSION = 16,
483
+ DLGINCLUDE = 17,
484
+ PLUGPLAY = 19,
485
+ VXD = 20,
486
+ ANICURSOR = 21,
487
+ ANIICON = 22,
488
+ HTML = 23,
489
+ MANIFEST = 24,
490
+ TOOLBAR = 241,
491
+ }
492
+
493
+ export function ReadResourceDirectory(file: binary.stream, data: binary.utils.MappedMemory, type = IRT.NONE) {
494
+ const dir = binary.read(file, RESOURCE_DIRECTORY);
495
+ const n = dir.NumberOfNamedEntries + dir.NumberOfIdEntries;
496
+ const entries = binary.readn(file, RESOURCE_DIRECTORY_ENTRY, n);
497
+ const id_type = binary.StringType(binary.UINT16_LE, 'utf16le');
498
+ const topbit = 0x80000000;
499
+ const result : Record<string, any> = {};
500
+
501
+ for (const i of entries) {
502
+ const id = i[0] & topbit ? id_type.get(file.seek(i[0] & ~topbit)) : !type ? IRT[i[0]] : i[0];
503
+
504
+ file.seek(i[1] & ~topbit);
505
+ result[id] = i[1] & topbit
506
+ ? ReadResourceDirectory(file, data, type || i[0])
507
+ : new RESOURCE_DATA_ENTRY(file, data);
508
+ }
509
+ return result;
510
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "commonjs",
5
+ "strict": true,
6
+ "declaration": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "outDir": "./dist",
11
+ "rootDir": "./src"
12
+ },
13
+ "include": [
14
+ "src/**/*.ts"
15
+ ],
16
+ "exclude": [
17
+ "node_modules",
18
+ "**/*.spec.ts"
19
+ ]
20
+ }