Rev 311 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 311 | Rev 317 | ||
---|---|---|---|
1 | # Obfuscated filters |
1 | # Obfuscated filters |
2 | 2 | ||
3 | ## Resource location |
3 | ## Resource location |
4 | 4 | ||
5 | Obfuscated standalone filters: |
5 | Obfuscated standalone filters: |
6 | - Windows resource: RCDATA\16001\0 |
6 | - Windows resource: RCDATA\16001\0 |
7 | - MacOS resource: 'DATA' 16001 |
7 | - MacOS resource: 'DATA' 16001 |
8 | 8 | ||
9 | Normal standalone filters: |
9 | Normal standalone filters: |
10 | - Windows resource: PARM\16000\0 |
10 | - Windows resource: PARM\16000\0 |
11 | - MacOS resource: 'PARM' 16000 |
11 | - MacOS resource: 'PARM' 16000 |
12 | 12 | ||
13 | ## Implementation |
13 | ## Implementation |
14 | 14 | ||
15 | Defined in **ff.h**, implemented in **obfusc.c**: |
15 | Defined in **ff.h**, implemented in **obfusc.c**: |
16 | 16 | ||
- | 17 | // Implements Obfusc V5 on Windows and Obfusc V4 on MacOS. |
|
17 | // Only implements V5. Returns a seed that needs to be stored in the executable code. |
18 | // Returns a seed that needs to be stored in the executable code. |
18 | unsigned int obfusc(PARM_T* pparm); |
19 | uint32_t obfusc(PARM_T* pparm); |
19 | 20 | ||
20 | // In V1+V2: Seed is hardcoded |
21 | // In V1+V2: Seed is hardcoded |
21 | // In V3: Seed is in PARM (field "unknown2") |
22 | // In V3: Seed is in PARM (field "unknown2") |
22 | // In V4+V5: Seed is in the program code and will me modified with a binary search+replace |
23 | // In V4+V5: Seed is in the program code and will me modified with a binary search+replace |
23 | void deobfusc(PARM_T* pparm); |
24 | void deobfusc(PARM_T* pparm); |
24 | 25 | ||
25 | ### Obfuscation "Version 5" |
26 | ### Obfuscation "Version 5" |
26 | 27 | ||
27 | Introduced in **Filter Foundry 1.7.0.8** |
28 | Introduced in **Filter Foundry 1.7.0.8** |
28 | 29 | ||
29 | Obfuscation version 5 is the same as version 4, but there is a constraint |
30 | Obfuscation version 5 is the same as version 4, but there is a constraint |
30 | that the seed must be equal to the CRC32b checksum of the deobfuscated PARM. |
31 | that the seed must be equal to the CRC32b checksum of the deobfuscated PARM. |
31 | This is done to check the integrity of the deobfuscation. |
32 | This is done to check the integrity of the deobfuscation. |
32 | 33 | ||
33 | Also, the xor-shifting is intentionally incompatible with version 4 |
34 | Also, the xor-shifting is intentionally incompatible with version 4 |
34 | (to avoid downgrade-attacks) by XORing the initial seed with 0xFFFFFFFF. |
35 | (to avoid downgrade-attacks) by XORing the initial seed with 0xFFFFFFFF. |
35 | 36 | ||
36 | ### Obfuscation "Version 4" |
37 | ### Obfuscation "Version 4" |
37 | 38 | ||
38 | Introduced in **Filter Foundry 1.7.0.7** |
39 | Introduced in **Filter Foundry 1.7.0.7** |
39 | 40 | ||
40 | It is not compiler-dependant, but different between every standalone filter. |
41 | It is not compiler-dependant, but different between every standalone filter. |
41 | 42 | ||
42 | Windows version: |
43 | Windows version: |
43 | The binary code of the 8BF file will be manipulated during building |
44 | The binary code of the 8BF file will be manipulated during building |
44 | to store the seed into the `deobfusc()` function. |
45 | to store the seed into the `deobfusc()` function. |
45 | The placeholder value is `OBFUSC_V4_DEFAULT_SEED 0x52830517` |
46 | The placeholder value is `OBFUSC_V4_DEFAULT_SEED 0x52830517` |
46 | This allows that 32-bit and 64-bit filters are "cross built". |
47 | This allows that 32-bit and 64-bit filters are "cross built". |
47 | 48 | ||
48 | (Theoretical) Macintosh version: |
49 | (Theoretical) Macintosh version: |
49 | Obfuscation and deobfuscation has the seed 0x52830517, since the |
50 | Obfuscation and deobfuscation has the seed 0x52830517, since the |
50 | manipulation of the binary code is not implemented. |
51 | manipulation of the binary code is not implemented. |
51 | 52 | ||
52 | Algorithm: XOR-Shift like in version 2, but the seed is individual for |
53 | Algorithm: XOR-Shift like in version 2, but the seed is individual for |
53 | each individual built standalone filter. |
54 | each individual built standalone filter. |
54 | 55 | ||
55 | The DWORD value "0x00000004" will be stored at position 0x30 (this field is not used in the `PARM` resource). |
56 | The DWORD value "0x00000004" will be stored at position 0x30 (this field is not used in the `PARM` resource). |
56 | 57 | ||
57 | ### Obfuscation "Version 3" |
58 | ### Obfuscation "Version 3" |
58 | 59 | ||
59 | Introduced in **Filter Foundry 1.7.0.5** |
60 | Introduced in **Filter Foundry 1.7.0.5** |
60 | 61 | ||
61 | It is compiler-dependant, therefore the resource cannot be exchanged between plugins! |
62 | It is compiler-dependant, therefore the resource cannot be exchanged between plugins! |
62 | 63 | ||
63 | Algorithm: XOR with a modified `rand()`-stream with seed that is stored at position 0x30 |
64 | Algorithm: XOR with a modified `rand()`-stream with seed that is stored at position 0x30 |
64 | (this field is not used in the `PARM` resource). |
65 | (this field is not used in the `PARM` resource). |
65 | 66 | ||
66 | 32 bit plugin is built with OpenWatcom (for Win95 compatibility) which has following formula: |
67 | 32 bit plugin is built with OpenWatcom (for Win95 compatibility) which has following formula: |
67 | 68 | ||
68 | int rand_openwatcom(unsigned int* seed) { |
69 | int rand_openwatcom(unsigned int* seed) { |
69 | *seed = *seed * 1103515245L + 12345L; |
70 | *seed = *seed * 1103515245L + 12345L; |
70 | return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */ |
71 | return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */ |
71 | } |
72 | } |
72 | 73 | ||
73 | 64 bit plugin is built with Visual C++ which has following formula: |
74 | 64 bit plugin is built with Visual C++ which has following formula: |
74 | 75 | ||
75 | int rand_msvcc(unsigned int* seed) { |
76 | int rand_msvcc(unsigned int* seed) { |
76 | *seed = *seed * 214013L + 2531011L; |
77 | *seed = *seed * 214013L + 2531011L; |
77 | return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */ |
78 | return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */ |
78 | } |
79 | } |
79 | 80 | ||
80 | ### Obfuscation "Version 2" |
81 | ### Obfuscation "Version 2" |
81 | 82 | ||
82 | Introduced in **Filter Foundry 1.7b1** |
83 | Introduced in **Filter Foundry 1.7b1** |
83 | 84 | ||
84 | It is compiler-independant! |
85 | It is compiler-independant! |
85 | 86 | ||
86 | Algorithm: [XOR-Shift](https://de.wikipedia.org/wiki/Xorshift "XOR-Shift") with hardcoded seed `0x95d4a68f`. |
87 | Algorithm: [XOR-Shift](https://de.wikipedia.org/wiki/Xorshift "XOR-Shift") with hardcoded seed `0x95d4a68f`. |
87 | 88 | ||
88 | x32 = 0x95d4a68f; |
89 | x32 = 0x95d4a68f; |
89 | for(i = size, p = pparm; i--;) { |
90 | for(i = size, p = pparm; i--;) { |
90 | x32 ^= x32 << 13; |
91 | x32 ^= x32 << 13; |
91 | x32 ^= x32 >> 17; |
92 | x32 ^= x32 >> 17; |
92 | x32 ^= x32 << 5; |
93 | x32 ^= x32 << 5; |
93 | *p++ ^= x32; |
94 | *p++ ^= x32; |
94 | } |
95 | } |
95 | 96 | ||
96 | ### Obfuscation "Version 1" |
97 | ### Obfuscation "Version 1" |
97 | 98 | ||
98 | Introduced in **Filter Foundry 1.4b8,9,10** |
99 | Introduced in **Filter Foundry 1.4b8,9,10** |
99 | 100 | ||
100 | It is compiler-dependant, therefore the resource cannot be exchanged between plugins! |
101 | It is compiler-dependant, therefore the resource cannot be exchanged between plugins! |
101 | 102 | ||
102 | Algorithm: XOR with `rand()`-stream with hardcoded seed `0xdc43df3c`. |
103 | Algorithm: XOR with `rand()`-stream with hardcoded seed `0xdc43df3c`. |
103 | 104 | ||
104 | srand(0xdc43df3c); |
105 | srand(0xdc43df3c); |
105 | for(i = size, p = pparm; i--;) { |
106 | for(i = size, p = pparm; i--;) { |
106 | *p++ ^= rand(); |
107 | *p++ ^= rand(); |
107 | } |
108 | } |
108 | 109 | ||
109 | The plugin is built with Visual C++ which has following formula: |
110 | The plugin is built with Visual C++ which has following formula: |
110 | 111 | ||
111 | int rand_msvcc(unsigned int* seed) { |
112 | int rand_msvcc(unsigned int* seed) { |
112 | *seed = *seed * 214013L + 2531011L; |
113 | *seed = *seed * 214013L + 2531011L; |
113 | return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */ |
114 | return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */ |
114 | } |
115 | } |
115 | 116 |