Rev 507 | Rev 509 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 507 | Rev 508 | ||
---|---|---|---|
Line 80... | Line 80... | ||
80 | } |
80 | } |
81 | #endif |
81 | #endif |
82 | #else |
82 | #else |
83 | // Unfortunately, with this compiler, we the value needs to be in the .data segment... |
83 | // Unfortunately, with this compiler, we the value needs to be in the .data segment... |
84 | // Due to "const volatile", this value will only exist a single time in the binary file. |
84 | // Due to "const volatile", this value will only exist a single time in the binary file. |
85 | const volatile uint64_t seed = 0x7416972a52830517ull; |
85 | const volatile uint64_t obfusc_seed = 0x7416972a52830517ull; |
86 | uint64_t GetObfuscSeed() { |
86 | uint64_t GetObfuscSeed() { |
87 | return seed; |
87 | return obfusc_seed; |
88 | } |
88 | } |
89 | #endif |
89 | #endif |
90 | 90 | ||
- | 91 | // Random seed #2 for obfuscation "86 21 1f 3e f1 a2 87 ef" |
|
- | 92 | // Lies in the data segment. Same rules like for the random seed #1. |
|
- | 93 | const volatile uint64_t obfusc_seed2 = 0xef87a2f13e1f2186ull; |
|
- | 94 | #ifdef _MSC_VER |
|
- | 95 | __declspec(noinline) |
|
- | 96 | #endif |
|
- | 97 | uint64_t GetObfuscSeed2() { |
|
- | 98 | // Additional seed for Obfusc V7. It is always in the data segment, |
|
- | 99 | // while obfusc seed 1 is in the code segment (if the compiler allows it) |
|
- | 100 | return obfusc_seed2; |
|
- | 101 | } |
|
- | 102 | ||
91 | int rand_msvcc(unsigned int* seed) { |
103 | int rand_msvcc(unsigned int* seed) { |
92 | *seed = *seed * 214013L + 2531011L; |
104 | *seed = *seed * 214013L + 2531011L; |
93 | return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */ |
105 | return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */ |
94 | } |
106 | } |
95 | 107 | ||
Line 110... | Line 122... | ||
110 | *x++ ^= *x32; |
122 | *x++ ^= *x32; |
111 | } |
123 | } |
112 | *p = x; |
124 | *p = x; |
113 | } |
125 | } |
114 | 126 | ||
- | 127 | void xorshift64(unsigned char** p, uint64_t* x64, size_t num) { |
|
- | 128 | // https://de.wikipedia.org/wiki/Xorshift |
|
- | 129 | size_t i; |
|
- | 130 | unsigned char* x = *p; |
|
- | 131 | for (i = 0; i < num; i++) { |
|
- | 132 | *x64 ^= *x64 << 13; |
|
- | 133 | *x64 ^= *x64 >> 7; |
|
- | 134 | *x64 ^= *x64 << 17; |
|
- | 135 | *x++ ^= *x64; |
|
- | 136 | } |
|
- | 137 | *p = x; |
|
- | 138 | } |
|
- | 139 | ||
115 | #ifndef CHAR_BIT |
140 | #ifndef CHAR_BIT |
116 | #define CHAR_BIT 8 |
141 | #define CHAR_BIT 8 |
117 | #endif |
142 | #endif |
118 | 143 | ||
119 | uint64_t rol_u64(uint64_t value, uint64_t by) { |
144 | uint64_t rol_u64(uint64_t value, uint64_t by) { |
Line 277... | Line 302... | ||
277 | } |
302 | } |
278 | else if ((obfusc_info >= 4) && (obfusc_info <= 0xFF)) { // xx 00 00 00 |
303 | else if ((obfusc_info >= 4) && (obfusc_info <= 0xFF)) { // xx 00 00 00 |
279 | // Version 4 obfuscation (Filter Foundry 1.7.0.7) |
304 | // Version 4 obfuscation (Filter Foundry 1.7.0.7) |
280 | // Version 5 obfuscation (Filter Foundry 1.7.0.8) |
305 | // Version 5 obfuscation (Filter Foundry 1.7.0.8) |
281 | // Version 6 obfuscation (Filter Foundry 1.7.0.10) |
306 | // Version 6 obfuscation (Filter Foundry 1.7.0.10) |
- | 307 | // Version 7 obfuscation (Filter Foundry 1.7.0.17) |
|
282 | // Future: Version 7, 8, ... 255 |
308 | // Future: Version 8, ... 255 |
283 | return obfusc_info; |
309 | return obfusc_info; |
284 | } |
310 | } |
285 | else { |
311 | else { |
286 | // Version 3 obfuscation (Filter Foundry 1.7.0.5) |
312 | // Version 3 obfuscation (Filter Foundry 1.7.0.5) |
287 | // obfusc_info is the srand() seed and is equal to the time(0) build timestamp |
313 | // obfusc_info is the srand() seed and is equal to the time(0) build timestamp |
288 | return 3; |
314 | return 3; |
289 | } |
315 | } |
290 | } |
316 | } |
291 | 317 | ||
292 | uint64_t obfusc(PARM_T* pparm) { |
318 | void obfusc(PARM_T* pparm, uint64_t* out_initial_seed, uint64_t* out_initial_seed2) { |
293 | // Version 6 obfuscation (Introduced in Filter Foundry 1.7.0.10) |
319 | // Version 7 obfuscation (Introduced in Filter Foundry 1.7.0.17) |
294 | 320 | ||
295 | unsigned char* p; |
321 | unsigned char* p; |
296 | uint64_t initial_seed, rolseed; |
322 | uint64_t initial_seed, initial_seed2, rolseed; |
297 | uint32_t xorseed; |
323 | uint32_t xorseed; |
298 | - | ||
299 | pparm->unknown1 = 0; |
- | |
300 | pparm->unknown2 = 0; |
- | |
301 | pparm->unknown3 = 0; |
324 | uint64_t xorseed2; |
302 | 325 | ||
303 | #ifdef MAC_ENV |
326 | #ifdef MAC_ENV |
304 | // Currently, make_mac.c does not implement modifying the executable code (TODO), |
327 | // Currently, make_mac.c does not implement modifying the executable code (TODO), |
305 | // so we will use the default initial_seed! |
328 | // so we will use the default initial_seed! |
306 | initial_seed = GetObfuscSeed(); |
329 | initial_seed = GetObfuscSeed(); |
- | 330 | initial_seed2 = GetObfuscSeed2(); |
|
307 | #else |
331 | #else |
308 | // Give always the same seed if the parameters are the same. No random values. |
332 | // Give always the same seed if the parameters are the same. No random values. |
309 | // This initial seed will be returned and built into the executable code by make_win.c |
333 | // This initial seed will be returned and built into the executable code by make_win.c |
- | 334 | pparm->unknown1 = 0; |
|
- | 335 | pparm->unknown2 = 0; |
|
- | 336 | pparm->unknown3 = 0; |
|
310 | initial_seed = crc64((unsigned char*)pparm, sizeof(PARM_T)); |
337 | initial_seed = crc64((unsigned char*)pparm, sizeof(PARM_T)); |
- | 338 | pparm->unknown3 = crc32b((char*)pparm, sizeof(PARM_T)); // make sure that the second seed is different |
|
- | 339 | pparm->unknown2 = crc32b((char*)pparm, sizeof(PARM_T)); // make sure that the second seed is different |
|
- | 340 | pparm->unknown1 = crc32b((char*)pparm, sizeof(PARM_T)); // make sure that the second seed is different |
|
- | 341 | initial_seed2 = crc64((unsigned char*)pparm, sizeof(PARM_T)); |
|
311 | #endif |
342 | #endif |
312 | 343 | ||
313 | // AFTER unknown1-3 have been set to 0, calculate the checksum! |
344 | // AFTER unknown1-3 have been set to 0 (again), calculate the checksum! |
- | 345 | pparm->unknown1 = 0; |
|
- | 346 | pparm->unknown2 = 0; |
|
- | 347 | pparm->unknown3 = 0; |
|
314 | pparm->unknown1 = crc32b((char*)pparm, sizeof(PARM_T)); |
348 | pparm->unknown1 = crc32b((char*)pparm, sizeof(PARM_T)); |
315 | 349 | ||
316 | xorseed = initial_seed & 0xFFFFFFFF; |
350 | xorseed = initial_seed & 0xFFFFFFFF; |
317 | p = (unsigned char*)pparm; |
351 | p = (unsigned char*)pparm; |
318 | xorshift(&p, &xorseed, sizeof(PARM_T)); |
352 | xorshift(&p, &xorseed, sizeof(PARM_T)); |
319 | 353 | ||
320 | rolseed = initial_seed; |
354 | rolseed = initial_seed; |
321 | p = (unsigned char*)pparm; |
355 | p = (unsigned char*)pparm; |
322 | rolshift(&p, &rolseed, sizeof(PARM_T)); |
356 | rolshift(&p, &rolseed, sizeof(PARM_T)); |
323 | 357 | ||
- | 358 | xorseed2 = initial_seed2; |
|
- | 359 | p = (unsigned char*)pparm; |
|
- | 360 | xorshift64(&p, &xorseed2, sizeof(PARM_T)); |
|
- | 361 | ||
324 | pparm->unknown2 = 6; // obfusc version |
362 | pparm->unknown2 = 7; // obfusc version |
325 | 363 | ||
326 | return initial_seed; |
364 | *out_initial_seed = initial_seed; |
- | 365 | *out_initial_seed2 = initial_seed2; |
|
327 | } |
366 | } |
328 | 367 | ||
329 | void deobfusc(PARM_T* pparm) { |
368 | void deobfusc(PARM_T* pparm) { |
330 | uint32_t obfusc_version; |
369 | uint32_t obfusc_version; |
331 | size_t size = sizeof(PARM_T); |
370 | size_t size = sizeof(PARM_T); |
Line 454... | Line 493... | ||
454 | 493 | ||
455 | rolseed = initial_seed; |
494 | rolseed = initial_seed; |
456 | p = (unsigned char*)pparm; |
495 | p = (unsigned char*)pparm; |
457 | rolshift(&p, &rolseed, sizeof(PARM_T)); |
496 | rolshift(&p, &rolseed, sizeof(PARM_T)); |
458 | 497 | ||
- | 498 | xorseed = initial_seed & 0xFFFFFFFF; |
|
- | 499 | p = (unsigned char*)pparm; |
|
- | 500 | xorshift(&p, &xorseed, sizeof(PARM_T)); |
|
- | 501 | ||
- | 502 | checksum = pparm->unknown1; |
|
- | 503 | ||
- | 504 | pparm->unknown1 = 0; |
|
- | 505 | pparm->unknown2 = 0; |
|
- | 506 | pparm->unknown3 = 0; |
|
- | 507 | ||
- | 508 | if (checksum != crc32b((char*)pparm, sizeof(PARM_T))) { |
|
- | 509 | // Integrity check failed! |
|
- | 510 | memset(pparm, 0, sizeof(PARM_T)); // invalidate everything |
|
- | 511 | } |
|
- | 512 | ||
- | 513 | break; |
|
- | 514 | } |
|
- | 515 | case 7: { |
|
- | 516 | // Version 7 obfuscation (Filter Foundry 1.7.0.17) |
|
- | 517 | // Not compiler dependent, but individual for each standalone filter |
|
- | 518 | // It is important that this code works for both x86 and x64 indepdently from the used compiler, |
|
- | 519 | // otherwise, the cross-make x86/x64 won't work! |
|
- | 520 | ||
- | 521 | unsigned char* p; |
|
- | 522 | uint32_t xorseed, checksum; |
|
- | 523 | uint64_t xorseed2; |
|
- | 524 | uint64_t initial_seed, initial_seed2, rolseed; |
|
- | 525 | ||
- | 526 | initial_seed = GetObfuscSeed(); // this value will be manipulated during the building of each individual filter (see make_win.c) |
|
- | 527 | initial_seed2 = GetObfuscSeed2(); // this value will be manipulated during the building of each individual filter (see make_win.c) |
|
- | 528 | ||
- | 529 | // This is the difference between V6 and V7 |
|
- | 530 | xorseed2 = initial_seed2; |
|
- | 531 | p = (unsigned char*)pparm; |
|
- | 532 | xorshift64(&p, &xorseed2, sizeof(PARM_T)); |
|
- | 533 | ||
- | 534 | rolseed = initial_seed; |
|
- | 535 | p = (unsigned char*)pparm; |
|
- | 536 | rolshift(&p, &rolseed, sizeof(PARM_T)); |
|
- | 537 | ||
459 | xorseed = initial_seed & 0xFFFFFFFF; |
538 | xorseed = initial_seed & 0xFFFFFFFF; |
460 | p = (unsigned char*)pparm; |
539 | p = (unsigned char*)pparm; |
461 | xorshift(&p, &xorseed, sizeof(PARM_T)); |
540 | xorshift(&p, &xorseed, sizeof(PARM_T)); |
462 | 541 | ||
463 | checksum = pparm->unknown1; |
542 | checksum = pparm->unknown1; |