@anonympins/fingerprint 0.7.3 → 0.7.5

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.
@@ -1,219 +1,219 @@
1
- import crypto from "node:crypto";
2
-
3
- function encodeULEB128(val) {
4
- const bytes = [];
5
- let num = val >>> 0;
6
- do {
7
- let byte = num & 0x7f;
8
- num >>>= 7;
9
- if (num !== 0) byte |= 0x80;
10
- bytes.push(byte);
11
- } while (num !== 0);
12
- return bytes;
13
- }
14
-
15
- function encodeSLEB128(val) {
16
- const bytes = [];
17
- let num = val | 0;
18
- while (true) {
19
- let byte = num & 0x7f;
20
- num >>= 7;
21
- if ((num === 0 && (byte & 0x40) === 0) || (num === -1 && (byte & 0x40) !== 0)) {
22
- bytes.push(byte);
23
- break;
24
- }
25
- bytes.push(byte | 0x80);
26
- }
27
- return bytes;
28
- }
29
-
30
- function getRandomNonTrivialOpcodes(tempLocal) {
31
- const insts = [];
32
- const ops = [
33
- // local.get tempLocal, i32.const rand, rotl, local.set tempLocal
34
- () => [0x20, tempLocal, 0x41, ...encodeSLEB128(crypto.randomInt(1, 32)), 0x77, 0x21, tempLocal],
35
- // local.get tempLocal, i32.const rand, rotr, local.set tempLocal
36
- () => [0x20, tempLocal, 0x41, ...encodeSLEB128(crypto.randomInt(1, 32)), 0x78, 0x21, tempLocal],
37
- // local.get tempLocal, i32.const rand, xor, local.set tempLocal
38
- () => [0x20, tempLocal, 0x41, ...encodeSLEB128(crypto.randomInt(0, 10000)), 0x73, 0x21, tempLocal],
39
- // local.get tempLocal, popcnt, i32.const rand, mul, local.set tempLocal
40
- () => [0x20, tempLocal, 0x69, 0x41, ...encodeSLEB128(crypto.randomInt(1, 1001)), 0x6c, 0x21, tempLocal],
41
- // local.get tempLocal, clz, local.get tempLocal, ctz, add, local.set tempLocal
42
- () => [0x20, tempLocal, 0x67, 0x20, tempLocal, 0x68, 0x6a, 0x21, tempLocal]
43
- ];
44
- const count = crypto.randomInt(2, 5);
45
- for (let i = 0; i < count; i++) {
46
- const op = ops[crypto.randomInt(0, ops.length)];
47
- insts.push(...op());
48
- }
49
- return insts;
50
- }
51
-
52
- function generatePolymorphicInstructions(stateLocal = 4, tempLocal = 5) {
53
- const insts = [];
54
-
55
- // Initialize tempLocal with a random value
56
- const initVal = crypto.randomInt(-500, 500);
57
- insts.push(0x41, ...encodeSLEB128(initVal), 0x21, tempLocal);
58
-
59
- // Initialize stateLocal to 0
60
- insts.push(0x41, ...encodeSLEB128(0), 0x21, stateLocal);
61
-
62
- // Loop & Block for state machine
63
- insts.push(0x03, 0x40); // loop
64
- insts.push(0x02, 0x40); // block
65
-
66
- for (let state = 0; state < 3; state++) {
67
- insts.push(0x20, stateLocal, 0x41, ...encodeSLEB128(state), 0x46); // state == expected
68
- insts.push(0x04, 0x40); // if
69
- insts.push(...getRandomNonTrivialOpcodes(tempLocal));
70
- insts.push(0x41, ...encodeSLEB128(state + 1), 0x21, stateLocal); // transit to state + 1
71
- insts.push(0x0c, ...encodeULEB128(2)); // br 2 (targets loop start)
72
- insts.push(0x0b); // end if
73
- }
74
-
75
- // Fallthrough / Default break (targets block depth 0, which exits the loop)
76
- insts.push(0x0c, ...encodeULEB128(0));
77
-
78
- // end block
79
- insts.push(0x0b);
80
- // end loop
81
- insts.push(0x0b);
82
-
83
- return insts;
84
- }
85
-
86
- export class DynamicWasmGenerator {
87
- /**
88
- * Generates a unique polymorphic WebAssembly module containing a custom hash function
89
- * with randomized constants and control flow variables.
90
- * @param {object} constants - Custom seed, multiplier and adder.
91
- * @returns {Buffer} Valid WebAssembly binary buffer.
92
- */
93
- static generate(constants) {
94
- const { seed, multiplier, adder } = constants;
95
-
96
- const preLoopPoly = generatePolymorphicInstructions(4, 5);
97
- const midLoopPoly = generatePolymorphicInstructions(4, 5);
98
-
99
- const inst = [
100
- 0x01, 0x06, 0x7f, // Locals: 1 entry of 6 locals of type i32
101
- ...preLoopPoly,
102
- // h = seed
103
- 0x41, ...encodeSLEB128(seed),
104
- 0x21, 0x03,
105
- // i = 0
106
- 0x41, 0x00,
107
- 0x21, 0x02,
108
-
109
- // block
110
- 0x02, 0x40,
111
- // loop
112
- 0x03, 0x40,
113
-
114
- // if i >= len break
115
- 0x20, 0x02,
116
- 0x20, 0x01,
117
- 0x4f,
118
- 0x0d, 0x01,
119
-
120
- // byte = load8_u(ptr + i)
121
- 0x20, 0x00,
122
- 0x20, 0x02,
123
- 0x6a,
124
- 0x2d, 0x00, 0x00,
125
-
126
- // h = h ^ byte
127
- 0x20, 0x03,
128
- 0x73,
129
-
130
- // h = h * multiplier
131
- 0x41, ...encodeSLEB128(multiplier),
132
- 0x6c,
133
-
134
- // h = h + adder
135
- 0x41, ...encodeSLEB128(adder),
136
- 0x6a,
137
-
138
- // local.set 3
139
- 0x21, 0x03,
140
- ...midLoopPoly,
141
-
142
- // i = i + 1
143
- 0x20, 0x02,
144
- 0x41, 0x01,
145
- 0x6a,
146
- 0x21, 0x02,
147
-
148
- // br 0
149
- 0x0c, 0x00,
150
-
151
- 0x0b, // end loop
152
- 0x0b, // end block
153
-
154
- // return h
155
- 0x20, 0x03,
156
- 0x0b // end function
157
- ];
158
-
159
- const funcBody = [
160
- ...encodeULEB128(inst.length),
161
- ...inst
162
- ];
163
-
164
- const codeSectionPayload = [
165
- ...encodeULEB128(1),
166
- ...funcBody
167
- ];
168
-
169
- const codeSection = [
170
- 0x0a,
171
- ...encodeULEB128(codeSectionPayload.length),
172
- ...codeSectionPayload
173
- ];
174
-
175
- const typeSection = [
176
- 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f
177
- ];
178
-
179
- const funcSection = [
180
- 0x03, 0x02, 0x01, 0x00
181
- ];
182
-
183
- const memSection = [
184
- 0x05, 0x03, 0x01, 0x00, 0x01
185
- ];
186
-
187
- const exportSection = [
188
- 0x07, 0x11, 0x02, 0x04, 0x68, 0x61, 0x73, 0x68, 0x00, 0x00, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00
189
- ];
190
-
191
- const wasm = [
192
- 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
193
- ...typeSection,
194
- ...funcSection,
195
- ...memSection,
196
- ...exportSection,
197
- ...codeSection
198
- ];
199
-
200
- return Buffer.from(wasm);
201
- }
202
-
203
- /**
204
- * Pure JavaScript fallback equivalent of the custom polymorphic hash.
205
- * @param {string} str Input string.
206
- * @param {object} constants Parameters.
207
- * @returns {number} 32-bit unsigned integer hash.
208
- */
209
- static hashJs(str, constants) {
210
- const { seed, multiplier, adder } = constants;
211
- let h = seed | 0;
212
- for (let i = 0; i < str.length; i++) {
213
- const byte = str.charCodeAt(i) & 0xff;
214
- h = h ^ byte;
215
- h = Math.imul(h, multiplier) + adder;
216
- }
217
- return h >>> 0;
218
- }
1
+ import crypto from "node:crypto";
2
+
3
+ function encodeULEB128(val) {
4
+ const bytes = [];
5
+ let num = val >>> 0;
6
+ do {
7
+ let byte = num & 0x7f;
8
+ num >>>= 7;
9
+ if (num !== 0) byte |= 0x80;
10
+ bytes.push(byte);
11
+ } while (num !== 0);
12
+ return bytes;
13
+ }
14
+
15
+ function encodeSLEB128(val) {
16
+ const bytes = [];
17
+ let num = val | 0;
18
+ while (true) {
19
+ let byte = num & 0x7f;
20
+ num >>= 7;
21
+ if ((num === 0 && (byte & 0x40) === 0) || (num === -1 && (byte & 0x40) !== 0)) {
22
+ bytes.push(byte);
23
+ break;
24
+ }
25
+ bytes.push(byte | 0x80);
26
+ }
27
+ return bytes;
28
+ }
29
+
30
+ function getRandomNonTrivialOpcodes(tempLocal) {
31
+ const insts = [];
32
+ const ops = [
33
+ // local.get tempLocal, i32.const rand, rotl, local.set tempLocal
34
+ () => [0x20, tempLocal, 0x41, ...encodeSLEB128(crypto.randomInt(1, 32)), 0x77, 0x21, tempLocal],
35
+ // local.get tempLocal, i32.const rand, rotr, local.set tempLocal
36
+ () => [0x20, tempLocal, 0x41, ...encodeSLEB128(crypto.randomInt(1, 32)), 0x78, 0x21, tempLocal],
37
+ // local.get tempLocal, i32.const rand, xor, local.set tempLocal
38
+ () => [0x20, tempLocal, 0x41, ...encodeSLEB128(crypto.randomInt(0, 10000)), 0x73, 0x21, tempLocal],
39
+ // local.get tempLocal, popcnt, i32.const rand, mul, local.set tempLocal
40
+ () => [0x20, tempLocal, 0x69, 0x41, ...encodeSLEB128(crypto.randomInt(1, 1001)), 0x6c, 0x21, tempLocal],
41
+ // local.get tempLocal, clz, local.get tempLocal, ctz, add, local.set tempLocal
42
+ () => [0x20, tempLocal, 0x67, 0x20, tempLocal, 0x68, 0x6a, 0x21, tempLocal]
43
+ ];
44
+ const count = crypto.randomInt(2, 5);
45
+ for (let i = 0; i < count; i++) {
46
+ const op = ops[crypto.randomInt(0, ops.length)];
47
+ insts.push(...op());
48
+ }
49
+ return insts;
50
+ }
51
+
52
+ function generatePolymorphicInstructions(stateLocal = 4, tempLocal = 5) {
53
+ const insts = [];
54
+
55
+ // Initialize tempLocal with a random value
56
+ const initVal = crypto.randomInt(-500, 500);
57
+ insts.push(0x41, ...encodeSLEB128(initVal), 0x21, tempLocal);
58
+
59
+ // Initialize stateLocal to 0
60
+ insts.push(0x41, ...encodeSLEB128(0), 0x21, stateLocal);
61
+
62
+ // Loop & Block for state machine
63
+ insts.push(0x03, 0x40); // loop
64
+ insts.push(0x02, 0x40); // block
65
+
66
+ for (let state = 0; state < 3; state++) {
67
+ insts.push(0x20, stateLocal, 0x41, ...encodeSLEB128(state), 0x46); // state == expected
68
+ insts.push(0x04, 0x40); // if
69
+ insts.push(...getRandomNonTrivialOpcodes(tempLocal));
70
+ insts.push(0x41, ...encodeSLEB128(state + 1), 0x21, stateLocal); // transit to state + 1
71
+ insts.push(0x0c, ...encodeULEB128(2)); // br 2 (targets loop start)
72
+ insts.push(0x0b); // end if
73
+ }
74
+
75
+ // Fallthrough / Default break (targets block depth 0, which exits the loop)
76
+ insts.push(0x0c, ...encodeULEB128(0));
77
+
78
+ // end block
79
+ insts.push(0x0b);
80
+ // end loop
81
+ insts.push(0x0b);
82
+
83
+ return insts;
84
+ }
85
+
86
+ export class DynamicWasmGenerator {
87
+ /**
88
+ * Generates a unique polymorphic WebAssembly module containing a custom hash function
89
+ * with randomized constants and control flow variables.
90
+ * @param {object} constants - Custom seed, multiplier and adder.
91
+ * @returns {Buffer} Valid WebAssembly binary buffer.
92
+ */
93
+ static generate(constants) {
94
+ const { seed, multiplier, adder } = constants;
95
+
96
+ const preLoopPoly = generatePolymorphicInstructions(4, 5);
97
+ const midLoopPoly = generatePolymorphicInstructions(4, 5);
98
+
99
+ const inst = [
100
+ 0x01, 0x06, 0x7f, // Locals: 1 entry of 6 locals of type i32
101
+ ...preLoopPoly,
102
+ // h = seed
103
+ 0x41, ...encodeSLEB128(seed),
104
+ 0x21, 0x03,
105
+ // i = 0
106
+ 0x41, 0x00,
107
+ 0x21, 0x02,
108
+
109
+ // block
110
+ 0x02, 0x40,
111
+ // loop
112
+ 0x03, 0x40,
113
+
114
+ // if i >= len break
115
+ 0x20, 0x02,
116
+ 0x20, 0x01,
117
+ 0x4f,
118
+ 0x0d, 0x01,
119
+
120
+ // byte = load8_u(ptr + i)
121
+ 0x20, 0x00,
122
+ 0x20, 0x02,
123
+ 0x6a,
124
+ 0x2d, 0x00, 0x00,
125
+
126
+ // h = h ^ byte
127
+ 0x20, 0x03,
128
+ 0x73,
129
+
130
+ // h = h * multiplier
131
+ 0x41, ...encodeSLEB128(multiplier),
132
+ 0x6c,
133
+
134
+ // h = h + adder
135
+ 0x41, ...encodeSLEB128(adder),
136
+ 0x6a,
137
+
138
+ // local.set 3
139
+ 0x21, 0x03,
140
+ ...midLoopPoly,
141
+
142
+ // i = i + 1
143
+ 0x20, 0x02,
144
+ 0x41, 0x01,
145
+ 0x6a,
146
+ 0x21, 0x02,
147
+
148
+ // br 0
149
+ 0x0c, 0x00,
150
+
151
+ 0x0b, // end loop
152
+ 0x0b, // end block
153
+
154
+ // return h
155
+ 0x20, 0x03,
156
+ 0x0b // end function
157
+ ];
158
+
159
+ const funcBody = [
160
+ ...encodeULEB128(inst.length),
161
+ ...inst
162
+ ];
163
+
164
+ const codeSectionPayload = [
165
+ ...encodeULEB128(1),
166
+ ...funcBody
167
+ ];
168
+
169
+ const codeSection = [
170
+ 0x0a,
171
+ ...encodeULEB128(codeSectionPayload.length),
172
+ ...codeSectionPayload
173
+ ];
174
+
175
+ const typeSection = [
176
+ 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f
177
+ ];
178
+
179
+ const funcSection = [
180
+ 0x03, 0x02, 0x01, 0x00
181
+ ];
182
+
183
+ const memSection = [
184
+ 0x05, 0x03, 0x01, 0x00, 0x01
185
+ ];
186
+
187
+ const exportSection = [
188
+ 0x07, 0x11, 0x02, 0x04, 0x68, 0x61, 0x73, 0x68, 0x00, 0x00, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00
189
+ ];
190
+
191
+ const wasm = [
192
+ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
193
+ ...typeSection,
194
+ ...funcSection,
195
+ ...memSection,
196
+ ...exportSection,
197
+ ...codeSection
198
+ ];
199
+
200
+ return Buffer.from(wasm);
201
+ }
202
+
203
+ /**
204
+ * Pure JavaScript fallback equivalent of the custom polymorphic hash.
205
+ * @param {string} str Input string.
206
+ * @param {object} constants Parameters.
207
+ * @returns {number} 32-bit unsigned integer hash.
208
+ */
209
+ static hashJs(str, constants) {
210
+ const { seed, multiplier, adder } = constants;
211
+ let h = seed | 0;
212
+ for (let i = 0; i < str.length; i++) {
213
+ const byte = str.charCodeAt(i) & 0xff;
214
+ h = h ^ byte;
215
+ h = Math.imul(h, multiplier) + adder;
216
+ }
217
+ return h >>> 0;
218
+ }
219
219
  }