Subversion Repositories filter_foundry

Rev

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