sekant-intercept-js 1.0.0

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.
@@ -0,0 +1,306 @@
1
+ /*
2
+ * Copyright 2026 Rishi Kant (Sekant Security Inc.)
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { computeEntropy, digestHex, calculateMD5, readUint16, readUint32, readUint64, readString, toHex } from "./sharedUtils.mjs";
18
+
19
+ const ELF_MAGIC = [0x7f, 0x45, 0x4c, 0x46];
20
+ const DT_NEEDED = 1;
21
+ const DT_SONAME = 14;
22
+ const DT_RPATH = 15;
23
+ const DT_RUNPATH = 29;
24
+
25
+ /* -------------------------
26
+ ELF Header
27
+ ------------------------- */
28
+ function parseElfHeader(buf) {
29
+ const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
30
+ for (let i = 0; i < 4; i++) if (buf[i] !== ELF_MAGIC[i]) throw new Error("Not ELF");
31
+
32
+ const elfClass = buf[4];
33
+ const littleEndian = buf[5] === 1;
34
+ const header = { is64bit: elfClass === 2, littleEndian };
35
+
36
+ // Parse type and machine (standard ELF header fields)
37
+ header.type = readUint16(view, 0x10, littleEndian);
38
+ header.machine = readUint16(view, 0x12, littleEndian);
39
+
40
+ header.entry_point = header.is64bit ? readUint64(view, 0x18, littleEndian) : readUint32(view, 0x18, littleEndian);
41
+ header.phoff = header.is64bit ? readUint64(view, 0x20, littleEndian) : readUint32(view, 0x1C, littleEndian);
42
+ header.shoff = header.is64bit ? readUint64(view, 0x28, littleEndian) : readUint32(view, 0x20, littleEndian);
43
+ header.phentsize = header.is64bit ? readUint16(view, 0x36, littleEndian) : readUint16(view, 0x2A, littleEndian);
44
+ header.phnum = header.is64bit ? readUint16(view, 0x38, littleEndian) : readUint16(view, 0x2C, littleEndian);
45
+ header.shentsize = header.is64bit ? readUint16(view, 0x3A, littleEndian) : readUint16(view, 0x2E, littleEndian);
46
+ header.shnum = header.is64bit ? readUint16(view, 0x3C, littleEndian) : readUint16(view, 0x30, littleEndian);
47
+ header.shstrndx = header.is64bit ? readUint16(view, 0x3E, littleEndian) : readUint16(view, 0x32, littleEndian);
48
+ return header;
49
+ }
50
+
51
+ /* -------------------------
52
+ Program headers
53
+ ------------------------- */
54
+ function parseProgramHeaders(buf, header) {
55
+ const phs = [];
56
+ const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
57
+ let offset = header.phoff;
58
+
59
+ for (let i = 0; i < header.phnum; i++) {
60
+ let p_type, p_offset, p_vaddr, p_filesz, p_memsz, p_flags, p_align;
61
+ if (header.is64bit) {
62
+ p_type = readUint32(view, offset, header.littleEndian);
63
+ p_flags = readUint32(view, offset + 4, header.littleEndian);
64
+ p_offset = readUint64(view, offset + 8, header.littleEndian);
65
+ p_vaddr = readUint64(view, offset + 16, header.littleEndian);
66
+ p_filesz = readUint64(view, offset + 32, header.littleEndian);
67
+ p_memsz = readUint64(view, offset + 40, header.littleEndian);
68
+ p_align = readUint64(view, offset + 48, header.littleEndian);
69
+ offset += 56;
70
+ } else {
71
+ p_type = readUint32(view, offset, header.littleEndian);
72
+ p_offset = readUint32(view, offset + 4, header.littleEndian);
73
+ p_vaddr = readUint32(view, offset + 8, header.littleEndian);
74
+ p_filesz = readUint32(view, offset + 16, header.littleEndian);
75
+ p_memsz = readUint32(view, offset + 20, header.littleEndian);
76
+ p_flags = readUint32(view, offset + 24, header.littleEndian);
77
+ p_align = readUint32(view, offset + 28, header.littleEndian);
78
+ offset += 32;
79
+ }
80
+ phs.push({ type: p_type, offset: p_offset, vaddr: p_vaddr, filesz: p_filesz, memsz: p_memsz, flags: p_flags, align: p_align });
81
+ }
82
+ return phs;
83
+ }
84
+
85
+ /* -------------------------
86
+ Sections + hashes
87
+ ------------------------- */
88
+ async function parseSections(buf, header) {
89
+ const shs = [];
90
+ const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
91
+ let offset = header.shoff;
92
+
93
+ for (let i = 0; i < header.shnum; i++) {
94
+ const sh_offset = header.is64bit ? readUint64(view, offset + 24, header.littleEndian) : readUint32(view, offset + 16, header.littleEndian);
95
+ const sh_size = header.is64bit ? readUint64(view, offset + 32, header.littleEndian) : readUint32(view, offset + 20, header.littleEndian);
96
+ const sectionData = sh_offset + sh_size <= buf.length ? buf.slice(sh_offset, sh_offset + sh_size) : new Uint8Array();
97
+
98
+ // Compute hashes using shared utilities (browser-compatible)
99
+ const md5Hash = calculateMD5(sectionData);
100
+ const sha1Hash = await digestHex("SHA-1", sectionData);
101
+ const sha256Hash = await digestHex("SHA-256", sectionData);
102
+
103
+ shs.push({
104
+ offset: sh_offset,
105
+ size: sh_size,
106
+ entropy: computeEntropy(sectionData),
107
+ raw_data: sectionData,
108
+ md5: md5Hash,
109
+ sha1: sha1Hash,
110
+ sha256: sha256Hash,
111
+ });
112
+
113
+ offset += header.is64bit ? 64 : 40;
114
+ }
115
+
116
+ return shs;
117
+ }
118
+
119
+ /* -------------------------
120
+ Dynamic dependencies parsing
121
+ ------------------------- */
122
+ function parseDynamicDependencies(buf, sections, header) {
123
+ const dynSection = sections.find(s => s.raw_data && s.raw_data.length > 0 && s.name === ".dynamic");
124
+ const dynstrSection = sections.find(s => s.raw_data && s.raw_data.length > 0 && s.name === ".dynstr");
125
+ if (!dynSection || !dynstrSection) return { needed_libraries: [], soname: null, rpath: null, runpath: null };
126
+
127
+ const dynBuf = dynSection.raw_data;
128
+ const strBuf = dynstrSection.raw_data;
129
+ const view = new DataView(dynBuf.buffer, dynBuf.byteOffset, dynBuf.byteLength);
130
+ const entrySize = header.is64bit ? 16 : 8;
131
+
132
+ const needed_libraries = [];
133
+ let soname = null;
134
+ let rpath = null;
135
+ let runpath = null;
136
+
137
+ for (let offset = 0; offset + entrySize <= dynBuf.length; offset += entrySize) {
138
+ const tag = header.is64bit ? readUint64(view, offset, header.littleEndian) : readUint32(view, offset, header.littleEndian);
139
+ const val = header.is64bit ? readUint64(view, offset + 8, header.littleEndian) : readUint32(view, offset + 4, header.littleEndian);
140
+
141
+ if (tag === DT_NEEDED) needed_libraries.push(readString(strBuf, val));
142
+ else if (tag === DT_SONAME) soname = readString(strBuf, val);
143
+ else if (tag === DT_RPATH) rpath = readString(strBuf, val);
144
+ else if (tag === DT_RUNPATH) runpath = readString(strBuf, val);
145
+ }
146
+
147
+ return { needed_libraries, soname, rpath, runpath };
148
+ }
149
+
150
+ /* -------------------------
151
+ Exported symbols
152
+ ------------------------- */
153
+ function parseExports(buf, sections, header) {
154
+ const exportsArr = [];
155
+ const dynsym = sections.find(s => s.name === ".dynsym");
156
+ const dynstr = sections.find(s => s.name === ".dynstr");
157
+ if (!dynsym || !dynstr) return exportsArr;
158
+
159
+ const symBuf = dynsym.raw_data;
160
+ const strBuf = dynstr.raw_data;
161
+ const view = new DataView(symBuf.buffer, symBuf.byteOffset, symBuf.byteLength);
162
+ const entrySize = header.is64bit ? 24 : 16;
163
+
164
+ for (let offset = 0; offset + entrySize <= symBuf.length; offset += entrySize) {
165
+ const nameOffset = readUint32(view, offset, header.littleEndian);
166
+ if (nameOffset >= strBuf.length) continue;
167
+ const name = readString(strBuf, nameOffset);
168
+ if (name) exportsArr.push(name);
169
+ }
170
+
171
+ return exportsArr;
172
+ }
173
+
174
+ /* -------------------------
175
+ Main YARA-Compatible ELF Parser
176
+ ------------------------- */
177
+ export async function parseELFYaraFull(inputBytes) {
178
+ if (inputBytes instanceof ArrayBuffer) inputBytes = new Uint8Array(inputBytes);
179
+ const file_size = inputBytes.length;
180
+
181
+ let header;
182
+ try { header = parseElfHeader(inputBytes); }
183
+ catch (e) { return { error: "Invalid ELF file", message: e.message }; }
184
+
185
+ const program_headers = parseProgramHeaders(inputBytes, header);
186
+ const sections = await parseSections(inputBytes, header);
187
+ const { needed_libraries, soname, rpath, runpath } = parseDynamicDependencies(inputBytes, sections, header);
188
+ const exportsArr = parseExports(inputBytes, sections, header);
189
+
190
+ const vaddr = (program_headers?.map(ph => ph.vaddr) || [0])[0];
191
+ const offset = (program_headers?.map(ph => ph.offset) || [0])[0];
192
+
193
+ return {
194
+ type: header.type,
195
+ machine: header.machine,
196
+ entry_point: header.entry_point - vaddr + offset,
197
+ is_64bit: header.is64bit,
198
+ endianness: header.littleEndian ? "little" : "big",
199
+ file_size,
200
+ program_headers,
201
+ sections,
202
+ imports: needed_libraries.map(lib => ({ dll: lib, functions: [] })),
203
+ exports: exportsArr,
204
+ needed_libraries,
205
+ soname,
206
+ rpath,
207
+ runpath,
208
+ hashes: {}, // optional whole-file hashes
209
+ };
210
+ }
211
+
212
+ /* -------------------------
213
+ Create YARA-Compatible ELF Module
214
+ ------------------------- */
215
+ export function createELFModule(parsedELF) {
216
+ if (!parsedELF || parsedELF.error) {
217
+ return null;
218
+ }
219
+
220
+ // Create module with all ELF properties
221
+ const elfModule = {
222
+ // Basic properties
223
+ type: parsedELF.type || 0,
224
+ machine: parsedELF.machine || 0,
225
+ entry_point: parsedELF.entry_point || 0,
226
+ file_size: parsedELF.file_size || 0,
227
+ is_64bit: parsedELF.is_64bit || false,
228
+ endianness: parsedELF.endianness || "little",
229
+
230
+ // Sections
231
+ sections: parsedELF.sections || [],
232
+ number_of_sections: (parsedELF.sections || []).length,
233
+
234
+ // Program headers (also exposed as "segments" for Python YARA compatibility)
235
+ program_headers: parsedELF.program_headers || [],
236
+ segments: parsedELF.program_headers || [], // Alias for Python YARA compatibility
237
+ number_of_segments: (parsedELF.program_headers || []).length,
238
+
239
+ // Imports/Exports
240
+ imports: parsedELF.needed_libraries || [],
241
+ exports: parsedELF.exports || [],
242
+ needed_libraries: parsedELF.needed_libraries || [],
243
+
244
+ // Dynamic linking info
245
+ soname: parsedELF.soname || null,
246
+ rpath: parsedELF.rpath || null,
247
+ runpath: parsedELF.runpath || null,
248
+
249
+ // Helper methods
250
+ is_32bit() {
251
+ return !this.is_64bit;
252
+ },
253
+
254
+ is_little_endian() {
255
+ return this.endianness === "little";
256
+ },
257
+
258
+ is_big_endian() {
259
+ return this.endianness === "big";
260
+ },
261
+
262
+ // Check if imports a specific library
263
+ imports_library(libName) {
264
+ return this.needed_libraries.some(lib =>
265
+ lib.toLowerCase().includes(libName.toLowerCase())
266
+ );
267
+ },
268
+
269
+ // Check if exports a specific function
270
+ exports_function(funcName) {
271
+ return this.exports.some(exp => exp === funcName);
272
+ },
273
+
274
+ // Get section by name
275
+ get_section_by_name(name) {
276
+ return this.sections.find(s => s.name === name);
277
+ },
278
+
279
+ // ELF constants (matching YARA standard)
280
+ // ELF types (e_type)
281
+ ET_NONE: 0,
282
+ ET_REL: 1,
283
+ ET_EXEC: 2,
284
+ ET_DYN: 3,
285
+ ET_CORE: 4,
286
+
287
+ // ELF machine types (e_machine)
288
+ EM_NONE: 0,
289
+ EM_386: 3, // Intel 80386
290
+ EM_X86_64: 62, // AMD x86-64
291
+ EM_ARM: 40, // ARM
292
+ EM_AARCH64: 183, // ARM 64-bit
293
+
294
+ // Legacy names for compatibility
295
+ ARCH_X86: 3,
296
+ ARCH_X86_64: 62,
297
+ ARCH_ARM: 40,
298
+ ARCH_AARCH64: 183,
299
+
300
+ TYPE_EXEC: 2,
301
+ TYPE_DYN: 3,
302
+ TYPE_CORE: 4,
303
+ };
304
+
305
+ return elfModule;
306
+ }
@@ -0,0 +1,284 @@
1
+ /*
2
+ * Copyright 2026 Rishi Kant (Sekant Security Inc.)
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * YARA Hash Module Implementation
19
+ *
20
+ * Browser-compatible implementation of YARA's hash module functions.
21
+ * Uses native Web Crypto API for SHA1 and SHA256, and spark-md5 for MD5.
22
+ *
23
+ * Supported functions:
24
+ * - md5(offset, size) : Calculate MD5 hash
25
+ * - md5(string) : Calculate MD5 hash of string
26
+ * - sha1(offset, size) : Calculate SHA1 hash
27
+ * - sha1(string) : Calculate SHA1 hash of string
28
+ * - sha256(offset, size) : Calculate SHA256 hash
29
+ * - sha256(string) : Calculate SHA256 hash of string
30
+ * - checksum32(offset, size) : Calculate 32-bit checksum
31
+ * - checksum32(string) : Calculate 32-bit checksum of string
32
+ * - crc32(offset, size) : Calculate CRC32
33
+ * - crc32(string) : Calculate CRC32 of string
34
+ *
35
+ * All hash functions return lowercase hexadecimal strings.
36
+ *
37
+ * @see https://yara.readthedocs.io/en/stable/modules/hash.html
38
+ */
39
+
40
+ import { digestHex, calculateMD5 } from './sharedUtils.mjs';
41
+
42
+ /**
43
+ * Convert string to Uint8Array
44
+ * @param {string} str
45
+ * @returns {Uint8Array}
46
+ */
47
+ function stringToBytes(str) {
48
+ const encoder = new TextEncoder();
49
+ return encoder.encode(str);
50
+ }
51
+
52
+ /**
53
+ * Calculate 32-bit checksum (sum of all bytes modulo 2^32)
54
+ * @param {Uint8Array} data
55
+ * @returns {number}
56
+ */
57
+ function calculateChecksum32(data) {
58
+ let sum = 0;
59
+ for (let i = 0; i < data.length; i++) {
60
+ sum = (sum + data[i]) >>> 0; // Keep as 32-bit unsigned
61
+ }
62
+ return sum & 0xFFFFFFFF;
63
+ }
64
+
65
+ /**
66
+ * CRC32 lookup table
67
+ */
68
+ const CRC32_TABLE = (() => {
69
+ const table = new Uint32Array(256);
70
+ for (let i = 0; i < 256; i++) {
71
+ let crc = i;
72
+ for (let j = 0; j < 8; j++) {
73
+ crc = (crc & 1) ? (0xEDB88320 ^ (crc >>> 1)) : (crc >>> 1);
74
+ }
75
+ table[i] = crc;
76
+ }
77
+ return table;
78
+ })();
79
+
80
+ /**
81
+ * Calculate CRC32 checksum
82
+ * @param {Uint8Array} data
83
+ * @returns {number}
84
+ */
85
+ function calculateCRC32(data) {
86
+ let crc = 0xFFFFFFFF;
87
+ for (let i = 0; i < data.length; i++) {
88
+ crc = (crc >>> 8) ^ CRC32_TABLE[(crc ^ data[i]) & 0xFF];
89
+ }
90
+ crc = (crc ^ 0xFFFFFFFF) >>> 0;
91
+ return crc;
92
+ }
93
+
94
+ /**
95
+ * Create a hash module instance for a specific data buffer
96
+ * @param {Uint8Array} data - The data to compute hashes on
97
+ * @returns {Object} Hash module with all YARA hash functions
98
+ */
99
+ export function createHashModule(data) {
100
+ if (!data || !(data instanceof Uint8Array)) {
101
+ throw new Error('Hash module requires a Uint8Array data buffer');
102
+ }
103
+
104
+ return {
105
+ /**
106
+ * Calculate MD5 hash
107
+ * Can be called with (offset, size) or (string)
108
+ */
109
+ md5: async function(...args) {
110
+ if (args.length === 1 && typeof args[0] === 'string') {
111
+ // md5(string)
112
+ const bytes = stringToBytes(args[0]);
113
+ return calculateMD5(bytes);
114
+ } else if (args.length === 2) {
115
+ // md5(offset, size)
116
+ const offset = args[0];
117
+ const size = args[1];
118
+ if (offset < 0 || size < 0) {
119
+ throw new Error(`Invalid range: offset=${offset}, size=${size}, data.length=${data.length}`);
120
+ }
121
+ const slice = data.slice(offset, offset + size);
122
+ return calculateMD5(slice);
123
+ } else {
124
+ throw new Error('md5() requires either (offset, size) or (string)');
125
+ }
126
+ },
127
+
128
+ /**
129
+ * Calculate SHA1 hash
130
+ * Can be called with (offset, size) or (string)
131
+ */
132
+ sha1: async function(...args) {
133
+ if (args.length === 1 && typeof args[0] === 'string') {
134
+ // sha1(string)
135
+ const bytes = stringToBytes(args[0]);
136
+ return await digestHex('SHA-1', bytes);
137
+ } else if (args.length === 2) {
138
+ // sha1(offset, size)
139
+ const offset = args[0];
140
+ const size = args[1];
141
+ if (offset < 0 || size < 0 || offset + size > data.length) {
142
+ throw new Error(`Invalid range: offset=${offset}, size=${size}, data.length=${data.length}`);
143
+ }
144
+ const slice = data.slice(offset, offset + size);
145
+ return await digestHex('SHA-1', slice);
146
+ } else {
147
+ throw new Error('sha1() requires either (offset, size) or (string)');
148
+ }
149
+ },
150
+
151
+ /**
152
+ * Calculate SHA256 hash
153
+ * Can be called with (offset, size) or (string)
154
+ */
155
+ sha256: async function(...args) {
156
+ if (args.length === 1 && typeof args[0] === 'string') {
157
+ // sha256(string)
158
+ const bytes = stringToBytes(args[0]);
159
+ return await digestHex('SHA-256', bytes);
160
+ } else if (args.length === 2) {
161
+ // sha256(offset, size)
162
+ const offset = args[0];
163
+ const size = args[1];
164
+ if (offset < 0 || size < 0 || offset + size > data.length) {
165
+ throw new Error(`Invalid range: offset=${offset}, size=${size}, data.length=${data.length}`);
166
+ }
167
+ const slice = data.slice(offset, offset + size);
168
+ return await digestHex('SHA-256', slice);
169
+ } else {
170
+ throw new Error('sha256() requires either (offset, size) or (string)');
171
+ }
172
+ },
173
+
174
+ /**
175
+ * Calculate 32-bit checksum
176
+ * Can be called with (offset, size) or (string)
177
+ */
178
+ checksum32: function(...args) {
179
+ if (args.length === 1 && typeof args[0] === 'string') {
180
+ // checksum32(string)
181
+ const bytes = stringToBytes(args[0]);
182
+ return calculateChecksum32(bytes);
183
+ } else if (args.length === 2) {
184
+ // checksum32(offset, size)
185
+ const offset = args[0];
186
+ const size = args[1];
187
+ if (offset < 0 || size < 0) {
188
+ throw new Error(`Invalid range: offset=${offset}, size=${size}, data.length=${data.length}`);
189
+ }
190
+ const slice = data.slice(offset, offset + size);
191
+ if (slice.length === 0) return 0;
192
+ return calculateChecksum32(slice);
193
+ } else {
194
+ throw new Error('checksum32() requires either (offset, size) or (string)');
195
+ }
196
+ },
197
+
198
+ /**
199
+ * Calculate CRC32 checksum
200
+ * Can be called with (offset, size) or (string)
201
+ */
202
+ crc32: function(...args) {
203
+ if (args.length === 1 && typeof args[0] === 'string') {
204
+ // crc32(string)
205
+ const bytes = stringToBytes(args[0]);
206
+ return calculateCRC32(bytes);
207
+ } else if (args.length === 2) {
208
+ // crc32(offset, size)
209
+ const offset = args[0];
210
+ const size = args[1];
211
+ if (offset < 0 || size < 0) {
212
+ throw new Error(`Invalid range: offset=${offset}, size=${size}, data.length=${data.length}`);
213
+ }
214
+ const slice = data.slice(offset, offset + size);
215
+ if (slice.length === 0) return 0;
216
+ return calculateCRC32(slice);
217
+ } else {
218
+ throw new Error('crc32() requires either (offset, size) or (string)');
219
+ }
220
+ }
221
+ };
222
+ }
223
+
224
+ /**
225
+ * Standalone hash functions that don't require a data buffer
226
+ * (for string hashing only)
227
+ */
228
+ export const hash = {
229
+ /**
230
+ * Calculate MD5 hash of a string
231
+ * @param {string} str
232
+ * @returns {Promise<string>} Hex string
233
+ */
234
+ md5: async function(str) {
235
+ const bytes = stringToBytes(str);
236
+ return calculateMD5(bytes);
237
+ },
238
+
239
+ /**
240
+ * Calculate SHA1 hash of a string
241
+ * @param {string} str
242
+ * @returns {Promise<string>} Hex string
243
+ */
244
+ sha1: async function(str) {
245
+ const bytes = stringToBytes(str);
246
+ return await digestHex('SHA-1', bytes);
247
+ },
248
+
249
+ /**
250
+ * Calculate SHA256 hash of a string
251
+ * @param {string} str
252
+ * @returns {Promise<string>} Hex string
253
+ */
254
+ sha256: async function(str) {
255
+ const bytes = stringToBytes(str);
256
+ return await digestHex('SHA-256', bytes);
257
+ },
258
+
259
+ /**
260
+ * Calculate 32-bit checksum of a string
261
+ * @param {string} str
262
+ * @returns {string} Hex string
263
+ */
264
+ checksum32: function(str) {
265
+ const bytes = stringToBytes(str);
266
+ return calculateChecksum32(bytes);
267
+ },
268
+
269
+ /**
270
+ * Calculate CRC32 of a string
271
+ * @param {string} str
272
+ * @returns {string} Hex string
273
+ */
274
+ crc32: function(str) {
275
+ const bytes = stringToBytes(str);
276
+ return calculateCRC32(bytes);
277
+ }
278
+ };
279
+
280
+ // Export for convenience
281
+ export default {
282
+ createHashModule,
283
+ hash
284
+ };
package/src/index.js ADDED
@@ -0,0 +1,9 @@
1
+ export { InterceptScanner, YaraScanner } from './interceptScanner.mjs';
2
+
3
+ export { parsePEYara, createPEModule } from "./peModule.mjs";
4
+ export { parseELFYaraFull, createELFModule } from "./elfModule.mjs";
5
+ export { createMathModule, math } from "./mathModule.mjs";
6
+ export { createHashModule, hash } from "./hashModule.mjs";
7
+ export { time } from "./timeModule.mjs";
8
+ export { string } from "./stringModule.mjs";
9
+ export { BaseCustomModule } from "./interceptCustomModules.mjs";