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