Rev 277 | Rev 312 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 277 | Rev 292 | ||
---|---|---|---|
Line 33... | Line 33... | ||
33 | #include "compat_string.h" |
33 | #include "compat_string.h" |
34 | 34 | ||
35 | //#define PRINTABLE_HASH_FF16 |
35 | //#define PRINTABLE_HASH_FF16 |
36 | #define ENABLE_APPLESCRIPT |
36 | #define ENABLE_APPLESCRIPT |
37 | 37 | ||
38 | const volatile uint32_t cObfuscV4Seed = 0x52830517; // this value will be manipulated during the building of each individual filter (see make_win.c) |
- | |
39 | - | ||
40 | /* |
38 | /* |
41 | Find a printable 4-character key, remembering (see Photoshop API guide): |
39 | Find a printable 4-character key, remembering (see Photoshop API guide): |
42 | - All IDs starting with an uppercase letter are reserved by Adobe. |
40 | - All IDs starting with an uppercase letter are reserved by Adobe. |
43 | - All IDs that are all uppercase are reserved by Apple. |
41 | - All IDs that are all uppercase are reserved by Apple. |
44 | - All IDs that are all lowercase are reserved by Apple. |
42 | - All IDs that are all lowercase are reserved by Apple. |
Line 448... | Line 446... | ||
448 | } |
446 | } |
449 | AETE_WRITE_DWORD(0); /* padding (FIXME: do we need that? Adobe's Windows filters don't) */ |
447 | AETE_WRITE_DWORD(0); /* padding (FIXME: do we need that? Adobe's Windows filters don't) */ |
450 | 448 | ||
451 | return (unsigned char*)aeteptr - (unsigned char*)beginptr; // length of stuff written |
449 | return (unsigned char*)aeteptr - (unsigned char*)beginptr; // length of stuff written |
452 | } |
450 | } |
453 | - | ||
454 | int rand_msvcc(unsigned int* seed) { |
- | |
455 | *seed = *seed * 214013L + 2531011L; |
- | |
456 | return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */ |
- | |
457 | } |
- | |
458 | - | ||
459 | int rand_openwatcom(unsigned int* seed) { |
- | |
460 | // https://github.com/open-watcom/open-watcom-v2/blob/master/bld/clib/math/c/rand.c |
- | |
461 | *seed = *seed * 1103515245L + 12345L; |
- | |
462 | return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */ |
- | |
463 | } |
- | |
464 | - | ||
465 | void _xorshift(unsigned char** p, uint32_t* x32, size_t num) { |
- | |
466 | size_t i; |
- | |
467 | unsigned char* x = *p; |
- | |
468 | for (i = 0; i < num; i++) { |
- | |
469 | // https://de.wikipedia.org/wiki/Xorshift |
- | |
470 | *x32 ^= *x32 << 13; |
- | |
471 | *x32 ^= *x32 >> 17; |
- | |
472 | *x32 ^= *x32 << 5; |
- | |
473 | *x++ ^= *x32; |
- | |
474 | } |
- | |
475 | *p = x; |
- | |
476 | } |
- | |
477 | - | ||
478 | void obfusc(PARM_T* pparm, unsigned int seed) { |
- | |
479 | unsigned char* p; |
- | |
480 | size_t size, seed_position; |
- | |
481 | - | ||
482 | seed_position = offsetof(PARM_T, unknown2); |
- | |
483 | size = sizeof(PARM_T); |
- | |
484 | - | ||
485 | // Version 4 obfuscation |
- | |
486 | // Filter Foundry >= 1.7.0.7 |
- | |
487 | - | ||
488 | p = (unsigned char*)pparm; |
- | |
489 | _xorshift(&p, &seed, seed_position); |
- | |
490 | *((unsigned int*)p) = 4; // Obfusc V4 info |
- | |
491 | p += 4; |
- | |
492 | _xorshift(&p, &seed, size - seed_position - 4); |
- | |
493 | } |
- | |
494 | - | ||
495 | void deobfusc(PARM_T* pparm) { |
- | |
496 | unsigned char* p; |
- | |
497 | size_t i; |
- | |
498 | unsigned int seed; |
- | |
499 | size_t size, seed_position; |
- | |
500 | - | ||
501 | seed_position = offsetof(PARM_T, unknown2); // = offsetof(PARM_T_PREMIERE, unknown1) |
- | |
502 | size = sizeof(PARM_T); |
- | |
503 | - | ||
504 | seed = pparm->unknown2; |
- | |
505 | - | ||
506 | if (seed == 0x90E364A3) { // A3 64 E3 90 |
- | |
507 | // Version 1 obfuscation, filter built with VC++ (official release by Toby Thain) |
- | |
508 | // Filter Foundry FF >= 1.4b8,9,10 |
- | |
509 | seed = 0xdc43df3c; |
- | |
510 | for (i = size, p = (unsigned char*)pparm; i--;) { |
- | |
511 | *p++ ^= rand_msvcc(&seed); |
- | |
512 | } |
- | |
513 | } |
- | |
514 | else if (seed == 0xE2CFCA34) { // 34 CA CF E2 |
- | |
515 | // Version 2 obfuscation, compiler independent |
- | |
516 | // Filter Foundry >= 1.7b1 |
- | |
517 | unsigned int x32 = 0x95d4a68f; |
- | |
518 | for (i = size, p = (unsigned char*)pparm; i--;) { |
- | |
519 | x32 ^= x32 << 13; |
- | |
520 | x32 ^= x32 >> 17; |
- | |
521 | x32 ^= x32 << 5; |
- | |
522 | *p++ ^= x32; |
- | |
523 | } |
- | |
524 | } |
- | |
525 | else if (seed == 4) { // 04 00 00 00 |
- | |
526 | // Version 4 obfuscation |
- | |
527 | // Filter Foundry >= 1.7.0.7 |
- | |
528 | // Not compiler dependent, but individual for each build |
- | |
529 | // It is important that this code works for both x86 and x64 indepdently from the used compiler, |
- | |
530 | // otherwise, the cross-make x86/x64 won't work! |
- | |
531 | uint32_t v4seed = cObfuscV4Seed; // this value will be manipulated during the building of each individual filter (see make_win.c) |
- | |
532 | p = (unsigned char*)pparm; |
- | |
533 | _xorshift(&p, &v4seed, seed_position); |
- | |
534 | p += 4; // obfusc info == 4 |
- | |
535 | _xorshift(&p, &v4seed, size - seed_position - 4); |
- | |
536 | - | ||
537 | // Filter Foundry >= 1.7.0.5 builds combines obfuscation and protection |
- | |
538 | // when a standalone filter is built. Theoretically, you can un-protect a |
- | |
539 | // plugin, even if it is obfuscated, just by bit-flipping the LSB of byte 0x164. |
- | |
540 | // Therefore, we enforce that the plugin is protected! |
- | |
541 | // Note: We don't need to check PARM_T_PREMIERE, because only PARM_T |
- | |
542 | // can be obfuscated by FilterFoundry. |
- | |
543 | pparm->iProtected = 1; |
- | |
544 | } |
- | |
545 | else { |
- | |
546 | // Version 3 obfuscation |
- | |
547 | // Filter Foundry >= 1.7.0.5 |
- | |
548 | // NO loading of other implementation supported, but that doesn't matter since Obfuscation+Protection is combined in FF >= 1.7.0.5 |
- | |
549 | // Using rand() is more secure, because it differs from compiler to compiler, so |
- | |
550 | // it is harder to read a protected 8BF plugin. |
- | |
551 | // Note that rand() in combination with srand() is deterministic, so it is safe |
- | |
552 | // to use it: https://stackoverflow.com/questions/55438293/does-rand-function-in-c-follows-non-determinstc-algorithm |
- | |
553 | // Note: 32-Bit FF is built using OpenWatcom (to support Win95), while 64-Bit FF is built using Microsoft Visual C++ |
- | |
554 | srand(seed); |
- | |
555 | p = (unsigned char*)pparm; |
- | |
556 | for (i = 0; i < seed_position; i++) *p++ ^= rand(); |
- | |
557 | *((unsigned int*)p) = 0; // here was the seed. Fill it with 0x00000000 |
- | |
558 | p += 4; |
- | |
559 | for (i = 0; i < size - seed_position - 4; i++) *p++ ^= rand(); |
- | |
560 | - | ||
561 | // Filter Foundry >= 1.7.0.5 builds combines obfuscation and protection |
- | |
562 | // when a standalone filter is built. Theoretically, you can un-protect a |
- | |
563 | // plugin, even if it is obfuscated, just by bit-flipping the LSB of byte 0x164. |
- | |
564 | // Therefore, we enforce that the plugin is protected! |
- | |
565 | // Note: We don't need to check PARM_T_PREMIERE, because only PARM_T |
- | |
566 | // can be obfuscated by FilterFoundry. |
- | |
567 | pparm->iProtected = 1; |
- | |
568 | } |
- | |
569 | } |
- |