Subversion Repositories filter_foundry

Rev

Rev 489 | Rev 506 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
292 daniel-mar 1
/*
2
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
3
    Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
503 daniel-mar 4
    Copyright (C) 2018-2022 Daniel Marschall, ViaThinkSoft
292 daniel-mar 5
 
6
    This program is free software; you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
10
 
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with this program; if not, write to the Free Software
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
*/
20
 
21
#include <stddef.h>
22
#include <stdint.h>
23
 
24
#include "ff.h"
25
 
312 daniel-mar 26
// this value will be manipulated during the building of each individual filter (see make_win.c)
351 daniel-mar 27
// It should be aligned to 4
348 daniel-mar 28
const volatile uint64_t cObfuscSeed = 0x38AD972A52830517ull;
292 daniel-mar 29
 
30
int rand_msvcc(unsigned int* seed) {
31
        *seed = *seed * 214013L + 2531011L;
32
        return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */
33
}
34
 
35
int rand_openwatcom(unsigned int* seed) {
36
        // https://github.com/open-watcom/open-watcom-v2/blob/master/bld/clib/math/c/rand.c
37
        *seed = *seed * 1103515245L + 12345L;
38
        return (*seed >> 16) & 0x7fff; /* Scale between 0 and RAND_MAX */
39
}
40
 
293 daniel-mar 41
void xorshift(unsigned char** p, uint32_t* x32, size_t num) {
292 daniel-mar 42
        size_t i;
43
        unsigned char* x = *p;
44
        for (i = 0; i < num; i++) {
45
                // https://de.wikipedia.org/wiki/Xorshift
46
                *x32 ^= *x32 << 13;
47
                *x32 ^= *x32 >> 17;
48
                *x32 ^= *x32 << 5;
49
                *x++ ^= *x32;
50
        }
51
        *p = x;
52
}
53
 
348 daniel-mar 54
#ifndef CHAR_BIT
55
#define CHAR_BIT 8
56
#endif
57
 
58
uint64_t rol_u64(uint64_t value, uint64_t by) {
59
        return value << by | value >> (sizeof(uint64_t) * CHAR_BIT - by);
60
}
61
 
62
void rolshift(unsigned char** p, uint64_t* x64, size_t num) {
63
        size_t i;
64
        unsigned char* x = *p;
65
        for (i = 0; i < num; i++) {
66
                *x++ ^= *x64;
67
                *x64 = rol_u64(*x64, 1);
68
        }
69
        *p = x;
70
}
71
 
311 daniel-mar 72
uint32_t crc32b(char *data, int nLength) {
73
        int i, j, k;
318 daniel-mar 74
        uint32_t crc, mask;
75
        char byte;
311 daniel-mar 76
 
77
        i = 0;
78
        crc = 0xFFFFFFFF;
79
 
80
        for(k=0;k<nLength;k++) {
81
                byte = data[k];
82
                crc = crc ^ byte;
83
                for (j = 7; j >= 0; j--) {
318 daniel-mar 84
                        mask = (-1) * (crc & 1);
311 daniel-mar 85
                        crc = (crc >> 1) ^ (0xEDB88320 & mask);
86
                }
87
                i++;
88
        }
89
        return ~crc;
90
}
91
 
349 daniel-mar 92
static const uint64_t crc64_tab[256] = {
93
        0x0000000000000000ULL, 0x42F0E1EBA9EA3693ULL, 0x85E1C3D753D46D26ULL,
94
        0xC711223CFA3E5BB5ULL, 0x493366450E42ECDFULL, 0x0BC387AEA7A8DA4CULL,
95
        0xCCD2A5925D9681F9ULL, 0x8E224479F47CB76AULL, 0x9266CC8A1C85D9BEULL,
96
        0xD0962D61B56FEF2DULL, 0x17870F5D4F51B498ULL, 0x5577EEB6E6BB820BULL,
97
        0xDB55AACF12C73561ULL, 0x99A54B24BB2D03F2ULL, 0x5EB4691841135847ULL,
98
        0x1C4488F3E8F96ED4ULL, 0x663D78FF90E185EFULL, 0x24CD9914390BB37CULL,
99
        0xE3DCBB28C335E8C9ULL, 0xA12C5AC36ADFDE5AULL, 0x2F0E1EBA9EA36930ULL,
100
        0x6DFEFF5137495FA3ULL, 0xAAEFDD6DCD770416ULL, 0xE81F3C86649D3285ULL,
101
        0xF45BB4758C645C51ULL, 0xB6AB559E258E6AC2ULL, 0x71BA77A2DFB03177ULL,
102
        0x334A9649765A07E4ULL, 0xBD68D2308226B08EULL, 0xFF9833DB2BCC861DULL,
103
        0x388911E7D1F2DDA8ULL, 0x7A79F00C7818EB3BULL, 0xCC7AF1FF21C30BDEULL,
104
        0x8E8A101488293D4DULL, 0x499B3228721766F8ULL, 0x0B6BD3C3DBFD506BULL,
105
        0x854997BA2F81E701ULL, 0xC7B97651866BD192ULL, 0x00A8546D7C558A27ULL,
106
        0x4258B586D5BFBCB4ULL, 0x5E1C3D753D46D260ULL, 0x1CECDC9E94ACE4F3ULL,
107
        0xDBFDFEA26E92BF46ULL, 0x990D1F49C77889D5ULL, 0x172F5B3033043EBFULL,
108
        0x55DFBADB9AEE082CULL, 0x92CE98E760D05399ULL, 0xD03E790CC93A650AULL,
109
        0xAA478900B1228E31ULL, 0xE8B768EB18C8B8A2ULL, 0x2FA64AD7E2F6E317ULL,
110
        0x6D56AB3C4B1CD584ULL, 0xE374EF45BF6062EEULL, 0xA1840EAE168A547DULL,
111
        0x66952C92ECB40FC8ULL, 0x2465CD79455E395BULL, 0x3821458AADA7578FULL,
112
        0x7AD1A461044D611CULL, 0xBDC0865DFE733AA9ULL, 0xFF3067B657990C3AULL,
113
        0x711223CFA3E5BB50ULL, 0x33E2C2240A0F8DC3ULL, 0xF4F3E018F031D676ULL,
114
        0xB60301F359DBE0E5ULL, 0xDA050215EA6C212FULL, 0x98F5E3FE438617BCULL,
115
        0x5FE4C1C2B9B84C09ULL, 0x1D14202910527A9AULL, 0x93366450E42ECDF0ULL,
116
        0xD1C685BB4DC4FB63ULL, 0x16D7A787B7FAA0D6ULL, 0x5427466C1E109645ULL,
117
        0x4863CE9FF6E9F891ULL, 0x0A932F745F03CE02ULL, 0xCD820D48A53D95B7ULL,
118
        0x8F72ECA30CD7A324ULL, 0x0150A8DAF8AB144EULL, 0x43A04931514122DDULL,
119
        0x84B16B0DAB7F7968ULL, 0xC6418AE602954FFBULL, 0xBC387AEA7A8DA4C0ULL,
120
        0xFEC89B01D3679253ULL, 0x39D9B93D2959C9E6ULL, 0x7B2958D680B3FF75ULL,
121
        0xF50B1CAF74CF481FULL, 0xB7FBFD44DD257E8CULL, 0x70EADF78271B2539ULL,
122
        0x321A3E938EF113AAULL, 0x2E5EB66066087D7EULL, 0x6CAE578BCFE24BEDULL,
123
        0xABBF75B735DC1058ULL, 0xE94F945C9C3626CBULL, 0x676DD025684A91A1ULL,
124
        0x259D31CEC1A0A732ULL, 0xE28C13F23B9EFC87ULL, 0xA07CF2199274CA14ULL,
125
        0x167FF3EACBAF2AF1ULL, 0x548F120162451C62ULL, 0x939E303D987B47D7ULL,
126
        0xD16ED1D631917144ULL, 0x5F4C95AFC5EDC62EULL, 0x1DBC74446C07F0BDULL,
127
        0xDAAD56789639AB08ULL, 0x985DB7933FD39D9BULL, 0x84193F60D72AF34FULL,
128
        0xC6E9DE8B7EC0C5DCULL, 0x01F8FCB784FE9E69ULL, 0x43081D5C2D14A8FAULL,
129
        0xCD2A5925D9681F90ULL, 0x8FDAB8CE70822903ULL, 0x48CB9AF28ABC72B6ULL,
130
        0x0A3B7B1923564425ULL, 0x70428B155B4EAF1EULL, 0x32B26AFEF2A4998DULL,
131
        0xF5A348C2089AC238ULL, 0xB753A929A170F4ABULL, 0x3971ED50550C43C1ULL,
132
        0x7B810CBBFCE67552ULL, 0xBC902E8706D82EE7ULL, 0xFE60CF6CAF321874ULL,
133
        0xE224479F47CB76A0ULL, 0xA0D4A674EE214033ULL, 0x67C58448141F1B86ULL,
134
        0x253565A3BDF52D15ULL, 0xAB1721DA49899A7FULL, 0xE9E7C031E063ACECULL,
135
        0x2EF6E20D1A5DF759ULL, 0x6C0603E6B3B7C1CAULL, 0xF6FAE5C07D3274CDULL,
136
        0xB40A042BD4D8425EULL, 0x731B26172EE619EBULL, 0x31EBC7FC870C2F78ULL,
137
        0xBFC9838573709812ULL, 0xFD39626EDA9AAE81ULL, 0x3A28405220A4F534ULL,
138
        0x78D8A1B9894EC3A7ULL, 0x649C294A61B7AD73ULL, 0x266CC8A1C85D9BE0ULL,
139
        0xE17DEA9D3263C055ULL, 0xA38D0B769B89F6C6ULL, 0x2DAF4F0F6FF541ACULL,
140
        0x6F5FAEE4C61F773FULL, 0xA84E8CD83C212C8AULL, 0xEABE6D3395CB1A19ULL,
141
        0x90C79D3FEDD3F122ULL, 0xD2377CD44439C7B1ULL, 0x15265EE8BE079C04ULL,
142
        0x57D6BF0317EDAA97ULL, 0xD9F4FB7AE3911DFDULL, 0x9B041A914A7B2B6EULL,
143
        0x5C1538ADB04570DBULL, 0x1EE5D94619AF4648ULL, 0x02A151B5F156289CULL,
144
        0x4051B05E58BC1E0FULL, 0x87409262A28245BAULL, 0xC5B073890B687329ULL,
145
        0x4B9237F0FF14C443ULL, 0x0962D61B56FEF2D0ULL, 0xCE73F427ACC0A965ULL,
146
        0x8C8315CC052A9FF6ULL, 0x3A80143F5CF17F13ULL, 0x7870F5D4F51B4980ULL,
147
        0xBF61D7E80F251235ULL, 0xFD913603A6CF24A6ULL, 0x73B3727A52B393CCULL,
148
        0x31439391FB59A55FULL, 0xF652B1AD0167FEEAULL, 0xB4A25046A88DC879ULL,
149
        0xA8E6D8B54074A6ADULL, 0xEA16395EE99E903EULL, 0x2D071B6213A0CB8BULL,
150
        0x6FF7FA89BA4AFD18ULL, 0xE1D5BEF04E364A72ULL, 0xA3255F1BE7DC7CE1ULL,
151
        0x64347D271DE22754ULL, 0x26C49CCCB40811C7ULL, 0x5CBD6CC0CC10FAFCULL,
152
        0x1E4D8D2B65FACC6FULL, 0xD95CAF179FC497DAULL, 0x9BAC4EFC362EA149ULL,
153
        0x158E0A85C2521623ULL, 0x577EEB6E6BB820B0ULL, 0x906FC95291867B05ULL,
154
        0xD29F28B9386C4D96ULL, 0xCEDBA04AD0952342ULL, 0x8C2B41A1797F15D1ULL,
155
        0x4B3A639D83414E64ULL, 0x09CA82762AAB78F7ULL, 0x87E8C60FDED7CF9DULL,
156
        0xC51827E4773DF90EULL, 0x020905D88D03A2BBULL, 0x40F9E43324E99428ULL,
157
        0x2CFFE7D5975E55E2ULL, 0x6E0F063E3EB46371ULL, 0xA91E2402C48A38C4ULL,
158
        0xEBEEC5E96D600E57ULL, 0x65CC8190991CB93DULL, 0x273C607B30F68FAEULL,
159
        0xE02D4247CAC8D41BULL, 0xA2DDA3AC6322E288ULL, 0xBE992B5F8BDB8C5CULL,
160
        0xFC69CAB42231BACFULL, 0x3B78E888D80FE17AULL, 0x7988096371E5D7E9ULL,
161
        0xF7AA4D1A85996083ULL, 0xB55AACF12C735610ULL, 0x724B8ECDD64D0DA5ULL,
162
        0x30BB6F267FA73B36ULL, 0x4AC29F2A07BFD00DULL, 0x08327EC1AE55E69EULL,
163
        0xCF235CFD546BBD2BULL, 0x8DD3BD16FD818BB8ULL, 0x03F1F96F09FD3CD2ULL,
164
        0x41011884A0170A41ULL, 0x86103AB85A2951F4ULL, 0xC4E0DB53F3C36767ULL,
165
        0xD8A453A01B3A09B3ULL, 0x9A54B24BB2D03F20ULL, 0x5D45907748EE6495ULL,
166
        0x1FB5719CE1045206ULL, 0x919735E51578E56CULL, 0xD367D40EBC92D3FFULL,
167
        0x1476F63246AC884AULL, 0x568617D9EF46BED9ULL, 0xE085162AB69D5E3CULL,
168
        0xA275F7C11F7768AFULL, 0x6564D5FDE549331AULL, 0x279434164CA30589ULL,
169
        0xA9B6706FB8DFB2E3ULL, 0xEB46918411358470ULL, 0x2C57B3B8EB0BDFC5ULL,
170
        0x6EA7525342E1E956ULL, 0x72E3DAA0AA188782ULL, 0x30133B4B03F2B111ULL,
171
        0xF7021977F9CCEAA4ULL, 0xB5F2F89C5026DC37ULL, 0x3BD0BCE5A45A6B5DULL,
172
        0x79205D0E0DB05DCEULL, 0xBE317F32F78E067BULL, 0xFCC19ED95E6430E8ULL,
173
        0x86B86ED5267CDBD3ULL, 0xC4488F3E8F96ED40ULL, 0x0359AD0275A8B6F5ULL,
174
        0x41A94CE9DC428066ULL, 0xCF8B0890283E370CULL, 0x8D7BE97B81D4019FULL,
175
        0x4A6ACB477BEA5A2AULL, 0x089A2AACD2006CB9ULL, 0x14DEA25F3AF9026DULL,
176
        0x562E43B4931334FEULL, 0x913F6188692D6F4BULL, 0xD3CF8063C0C759D8ULL,
177
        0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL, 0xD80C07CD676F8394ULL,
178
        0x9AFCE626CE85B507ULL
179
};
180
 
181
/*
182
 * ECMA 182 CRC64, taken from https://searchcode.com/file/68313281/lib/crc64.c/
183
 */
184
uint64_t crc64(const unsigned char* data, size_t len)
185
{
186
        uint64_t crc = 0;
187
 
188
        while (len--) {
189
                int i = ((int)(crc >> 56) ^ *data++) & 0xFF;
190
                crc = crc64_tab[i] ^ (crc << 8);
191
        }
192
 
193
        return crc;
194
}
195
 
352 daniel-mar 196
 
197
int obfuscation_version(PARM_T* pparm) {
198
        uint32_t obfusc_info = pparm->unknown2;
199
 
200
        if (obfusc_info == 0x00000000) { // 00 00 00 00
201
                // Photoshop FilterFactory default initialization of field "unknown2"
202
                // (no obfuscation)
203
                return 0;
204
        }
205
        else if (obfusc_info == 0x00000001) { // 01 00 00 00
206
                // Premiere FilterFactory default initialization of field "unknown1" (it is at the offset of Photoshop's "unknown2")
207
                // (no obfuscation)
208
                return 0;
209
        }
210
        else if (obfusc_info == 0x90E364A3) { // A3 64 E3 90
211
                // Version 1 obfuscation (Filter Foundry 1.4b8,9,10)
212
                return 1;
213
        }
214
        else if (obfusc_info == 0xE2CFCA34) { // 34 CA CF E2
215
                // Version 2 obfuscation (Filter Foundry 1.7b1)
216
                return 2;
217
        }
218
        else if ((obfusc_info >= 4) && (obfusc_info <= 0xFF)) { // xx 00 00 00
219
                // Version 4 obfuscation (Filter Foundry 1.7.0.7)
220
                // Version 5 obfuscation (Filter Foundry 1.7.0.8)
221
                // Version 6 obfuscation (Filter Foundry 1.7.0.10)
489 daniel-mar 222
                // Future: Version 7, 8, ... 255
352 daniel-mar 223
                return obfusc_info;
224
        }
225
        else {
226
                // Version 3 obfuscation (Filter Foundry 1.7.0.5)
227
                // obfusc_info is the srand() seed and is equal to the time(0) build timestamp
228
                return 3;
229
        }
230
}
231
 
347 daniel-mar 232
uint64_t obfusc(PARM_T* pparm) {
233
        // Version 6 obfuscation (Introduced in Filter Foundry 1.7.0.10)
292 daniel-mar 234
 
235
        unsigned char* p;
348 daniel-mar 236
        uint64_t initial_seed, rolseed;
350 daniel-mar 237
        uint32_t xorseed;
347 daniel-mar 238
 
349 daniel-mar 239
        pparm->unknown1 = 0;
240
        pparm->unknown2 = 0;
241
        pparm->unknown3 = 0;
242
 
292 daniel-mar 243
#ifdef MAC_ENV
347 daniel-mar 244
        // Currently, make_mac.c does not implement modifying the executable code (TODO),
245
        // so we will use the default initial_seed!
348 daniel-mar 246
        initial_seed = cObfuscSeed;
292 daniel-mar 247
#else
347 daniel-mar 248
        // Give always the same seed if the parameters are the same. No random values.
249
        // This initial seed will be returned and built into the executable code by make_win.c
350 daniel-mar 250
        initial_seed = crc64((unsigned char*)pparm, sizeof(PARM_T));
292 daniel-mar 251
#endif
252
 
347 daniel-mar 253
        // AFTER unknown1-3 have been set to 0, calculate the checksum!
254
        pparm->unknown1 = crc32b((char*)pparm, sizeof(PARM_T));
309 daniel-mar 255
 
350 daniel-mar 256
        xorseed = initial_seed & 0xFFFFFFFF;
292 daniel-mar 257
        p = (unsigned char*)pparm;
350 daniel-mar 258
        xorshift(&p, &xorseed, sizeof(PARM_T));
292 daniel-mar 259
 
348 daniel-mar 260
        rolseed = initial_seed;
347 daniel-mar 261
        p = (unsigned char*)pparm;
348 daniel-mar 262
        rolshift(&p, &rolseed, sizeof(PARM_T));
347 daniel-mar 263
 
264
        pparm->unknown2 = 6; // obfusc version
265
 
292 daniel-mar 266
        return initial_seed;
267
}
268
 
269
void deobfusc(PARM_T* pparm) {
309 daniel-mar 270
        uint32_t obfusc_version;
292 daniel-mar 271
        size_t size = sizeof(PARM_T);
272
 
293 daniel-mar 273
        obfusc_version = obfuscation_version(pparm);
292 daniel-mar 274
 
275
        switch (obfusc_version) {
276
                case 0:
277
                        // no obfuscation
278
                        return;
279
                case 1: {
280
                        // Version 1 obfuscation (Filter Foundry 1.4b8,9,10)
281
                        // Filter built with VC++ (official release by Toby Thain)
282
 
283
                        unsigned char* p;
284
                        size_t i;
309 daniel-mar 285
                        uint32_t seed;
292 daniel-mar 286
 
287
                        seed = 0xdc43df3c;
288
 
289
                        for (i = size, p = (unsigned char*)pparm; i--;) {
290
                                *p++ ^= rand_msvcc(&seed);
291
                        }
292
                        break;
293
                }
294
                case 2: {
295
                        // Version 2 obfuscation (Filter Foundry 1.7b1)
296
                        // Compiler independent
297
 
298
                        unsigned char* p;
299
                        size_t i;
309 daniel-mar 300
                        uint32_t seed;
292 daniel-mar 301
 
302
                        seed = 0x95d4a68f;
303
 
304
                        for (i = size, p = (unsigned char*)pparm; i--;) {
305
                                seed ^= seed << 13;
306
                                seed ^= seed >> 17;
307
                                seed ^= seed << 5;
308
                                *p++ ^= seed;
309
                        }
310
                        break;
311
                }
312
                case 3: {
313
                        // Version 3 obfuscation (Filter Foundry 1.7.0.5)
314
                        // NO loading of other implementation supported, but that doesn't matter since
315
                        // obfuscation and protection is combined in Filter Factory >= 1.7.0.5.
316
                        // Using rand() is more secure, because it differs from compiler to compiler, so
317
                        // it is harder to read a protected 8BF plugin.
318
                        // Note that rand() in combination with srand() is deterministic, so it is safe
319
                        // to use it: https://stackoverflow.com/questions/55438293/does-rand-function-in-c-follows-non-determinstc-algorithm
320
                        // Note: 32-Bit FF is built using OpenWatcom (to support Win95), while 64-Bit FF is built using Microsoft Visual C++
321
 
322
                        unsigned char* p;
323
                        size_t i;
309 daniel-mar 324
                        uint32_t seed;
292 daniel-mar 325
                        size_t seed_position;
326
 
327
                        seed = pparm->unknown2;
328
                        seed_position = offsetof(PARM_T, unknown2); // = offsetof(PARM_T_PREMIERE, unknown1)
329
 
330
                        srand(seed);
329 daniel-mar 331
 
292 daniel-mar 332
                        p = (unsigned char*)pparm;
351 daniel-mar 333
                        for (i = 0; i < seed_position; i++) {
334
                                *p++ ^= (int)(rand() * 1.0 / ((double)RAND_MAX + 1) * 256);
335
                        }
309 daniel-mar 336
                        *((uint32_t*)p) = 0; // here was the seed. Fill it with 0x00000000
292 daniel-mar 337
                        p += 4;
351 daniel-mar 338
                        for (i = 0; i < size - seed_position - 4; i++) {
339
                                *p++ ^= (int)(rand() * 1.0 / ((double)RAND_MAX + 1) * 256);
340
                        }
329 daniel-mar 341
 
292 daniel-mar 342
                        break;
343
                }
344
                case 4:
345
                case 5: {
346
                        // Version 4 obfuscation (Filter Foundry 1.7.0.7)
347
                        // Version 5 obfuscation (Filter Foundry 1.7.0.8)
489 daniel-mar 348
                        // Not compiler dependent, but individual for each standalone filter
292 daniel-mar 349
                        // It is important that this code works for both x86 and x64 indepdently from the used compiler,
350
                        // otherwise, the cross-make x86/x64 won't work!
351
                        // Version 5 contains a seed requirement (checksum).
352
 
353
                        unsigned char* p;
354
                        size_t seed_position;
309 daniel-mar 355
                        uint32_t seed, initial_seed;
292 daniel-mar 356
 
347 daniel-mar 357
                        initial_seed = cObfuscSeed & 0xFFFFFFFF; // this value will be manipulated during the building of each individual filter (see make_win.c)
309 daniel-mar 358
 
359
                        seed = initial_seed;
292 daniel-mar 360
                        seed_position = offsetof(PARM_T, unknown2); // = offsetof(PARM_T_PREMIERE, unknown1)
361
 
309 daniel-mar 362
                        if (obfusc_version == 5) {
363
                                // make v4 and v5 intentionally incompatible to avoid a downgrade-attack
364
                                seed ^= 0xFFFFFFFF;
365
                        }
366
 
292 daniel-mar 367
                        p = (unsigned char*)pparm;
293 daniel-mar 368
                        xorshift(&p, &seed, seed_position);
329 daniel-mar 369
                        *((uint32_t*)p) = 0; // here was the version info. Fill it with 0x00000000
370
                        p += 4; // obfusc info was 4 or 5
293 daniel-mar 371
                        xorshift(&p, &seed, size - seed_position - 4);
292 daniel-mar 372
 
373
                        if (obfusc_version == 5) {
318 daniel-mar 374
                                pparm->unknown2 = 0; // make sure crc32b matches always
347 daniel-mar 375
                                if (crc32b((char*)pparm, sizeof(PARM_T)) != initial_seed) {
292 daniel-mar 376
                                        // Integrity check failed!
309 daniel-mar 377
                                        memset(pparm, 0, sizeof(PARM_T)); // invalidate everything
292 daniel-mar 378
                                }
379
                        }
380
 
381
                        break;
382
                }
347 daniel-mar 383
                case 6: {
384
                        // Version 6 obfuscation (Filter Foundry 1.7.0.10)
489 daniel-mar 385
                        // Not compiler dependent, but individual for each standalone filter
347 daniel-mar 386
                        // It is important that this code works for both x86 and x64 indepdently from the used compiler,
387
                        // otherwise, the cross-make x86/x64 won't work!
388
 
389
                        unsigned char* p;
350 daniel-mar 390
                        uint32_t xorseed, checksum;
348 daniel-mar 391
                        uint64_t initial_seed, rolseed;
503 daniel-mar 392
 
348 daniel-mar 393
                        initial_seed = cObfuscSeed; // this value will be manipulated during the building of each individual filter (see make_win.c)
347 daniel-mar 394
 
348 daniel-mar 395
                        rolseed = initial_seed;
347 daniel-mar 396
                        p = (unsigned char*)pparm;
348 daniel-mar 397
                        rolshift(&p, &rolseed, sizeof(PARM_T));
347 daniel-mar 398
 
350 daniel-mar 399
                        xorseed = initial_seed & 0xFFFFFFFF;
347 daniel-mar 400
                        p = (unsigned char*)pparm;
350 daniel-mar 401
                        xorshift(&p, &xorseed, sizeof(PARM_T));
347 daniel-mar 402
 
403
                        checksum = pparm->unknown1;
404
 
405
                        pparm->unknown1 = 0;
406
                        pparm->unknown2 = 0;
407
                        pparm->unknown3 = 0;
408
 
409
                        if (checksum != crc32b((char*)pparm, sizeof(PARM_T))) {
410
                                // Integrity check failed!
411
                                memset(pparm, 0, sizeof(PARM_T)); // invalidate everything
412
                        }
413
 
414
                        break;
415
                }
292 daniel-mar 416
                default: {
417
                        // Obfuscation version unexpected!
309 daniel-mar 418
                        memset(pparm, 0, sizeof(PARM_T)); // invalidate everything
311 daniel-mar 419
 
420
                        // If "return" is present: Calling function will receive an invalid cbSize value, hence showing "incompatible obfuscation"
421
                        // If "return" is not present: Then the code below will set a correct cbSize and iProtect flag if obfusc_version>=3, which will raise the error "filter is protected"
422
                        return;
292 daniel-mar 423
                }
424
        }
425
 
309 daniel-mar 426
        if ((pparm->cbSize != PARM_SIZE) &&
351 daniel-mar 427
                (pparm->cbSize != PARM_SIZE_PREMIERE) &&
309 daniel-mar 428
                (pparm->cbSize != PARM_SIG_MAC)) {
429
                memset(pparm, 0, sizeof(PARM_T)); // invalidate everything
430
        }
503 daniel-mar 431
 
292 daniel-mar 432
        if (obfusc_version >= 3) {
489 daniel-mar 433
                // Filter Foundry >= 1.7.0.5 combines obfuscation and protection
292 daniel-mar 434
                // when a standalone filter is built. Theoretically, you can un-protect a
435
                // plugin, even if it is obfuscated, just by bit-flipping the LSB of byte 0x164.
436
                // Therefore, we enforce that the plugin is protected!
437
                pparm->iProtected = 1;
438
 
439
                // Furthermore, if obfuscation 3+ failed (since the seed is individual for each 8BF file),
293 daniel-mar 440
                // we still want that load_*.c is able to detect pparm->iProtected instead
441
                // of throwing the error "Incompatible obfuscation".
292 daniel-mar 442
                pparm->cbSize = PARM_SIZE;
408 daniel-mar 443
                pparm->standalone = 1;
292 daniel-mar 444
        }
312 daniel-mar 445
 
446
        if (obfusc_version >= 1) {
447
                // information was lost due to obfuscation. Make sure it is zero.
448
                pparm->unknown2 = 0;
449
        }
351 daniel-mar 450
 
451
        if (obfusc_version >= 6) {
452
                // information was lost due to checksum. Make sure it is zero.
453
                pparm->unknown1 = 0;
454
        }
292 daniel-mar 455
}