Subversion Repositories filter_foundry

Rev

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

Rev Author Line No. Line
184 dmarschall 1
/*
247 daniel-mar 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
184 dmarschall 5
 
247 daniel-mar 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.
184 dmarschall 10
 
247 daniel-mar 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.
184 dmarschall 15
 
247 daniel-mar 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
184 dmarschall 19
*/
20
 
21
#include <stddef.h>
22
#include <stdint.h>
185 dmarschall 23
#include <assert.h>
255 daniel-mar 24
#include <time.h>
184 dmarschall 25
 
26
#include "ff.h"
27
#include "symtab.h"
28
 
210 daniel-mar 29
#include "scripting.h"
184 dmarschall 30
#include "PIActions.h"
31
#include "PITerminology.h"
32
 
33
#include "compat_string.h"
34
 
207 daniel-mar 35
//#define PRINTABLE_HASH_FF16
212 daniel-mar 36
#define ENABLE_APPLESCRIPT
207 daniel-mar 37
 
184 dmarschall 38
/*
207 daniel-mar 39
Find a printable 4-character key, remembering (see Photoshop API guide):
40
- All IDs starting with an uppercase letter are reserved by Adobe.
41
- All IDs that are all uppercase are reserved by Apple.
42
- All IDs that are all lowercase are reserved by Apple.
43
- This leaves all IDs that begin with a lowercase letter and have at least
44
  one uppercase letter for you and other plug-in developers.
45
Note: It is questionable if "a!!!" or "A!!!" are also reseved by Apple. We don't risk it.
184 dmarschall 46
*/
47
unsigned long printablehash(unsigned long hash) {
268 daniel-mar 48
        #ifdef PRINTABLE_HASH_FF16
49
 
247 daniel-mar 50
        // FilterFoundry version 1.6 hashing by Toby Thain
51
        // Only accepts upper case at the last character
52
        // 0       = 'a  A'
53
        // 6100899 = 'z~~Z'
54
        unsigned long key = 'a' + (hash % 26);  hash /= 26; // first lower case
55
        key = (key << 8) | (' ' + (hash % 95)); hash /= 95; // any printable
56
        key = (key << 8) | (' ' + (hash % 95)); hash /= 95; // any printable
57
        return  (key << 8) | ('A' + (hash % 26));           // last upper case
268 daniel-mar 58
 
59
        #else
60
 
247 daniel-mar 61
        // FilterFoundry version 1.7 hashing by Daniel Marschall
62
        // Accepts upper case at character 2, 3 or 4
63
        // Spaces are only set the right as padding to make a code shorter
64
        // 0        = 'aA  '
65
        // 13530139 = 'zZZZ'
66
        // The key-space is ~2.22 times larger
67
        long lowlim;
68
        long uplim;
69
        int upperCaseInfo;
70
        int length;
71
        int lastThreeCharInfo;
72
        int firstChar;
73
        unsigned long key;
74
        int found;
75
        int i,j,k;
207 daniel-mar 76
 
247 daniel-mar 77
        uplim = 0;
78
        for (k=1; k<4; k++) {
79
                int mask;
80
                if (k == 1) mask = 1;//0b1;
81
                if (k == 2) mask = 2;//0b11;
82
                if (k == 3) mask = 4;//0b111;
83
                for (i=1; i<=mask; i++) {
84
                        // 'k' characters
85
                        long test = 1;
86
                        for (j=0; j<k; ++j) {
87
                                test *= ((i&(1<<j)) != 0) ? 26 : 94-26;
88
                        }
89
                        uplim += test;
90
                }
91
        }
207 daniel-mar 92
 
247 daniel-mar 93
        lastThreeCharInfo = hash % uplim; hash /= uplim;
94
        firstChar = hash%26; hash /= 26;
207 daniel-mar 95
 
247 daniel-mar 96
        lowlim = 0;
97
        uplim = 0;
98
        found = 0;
99
        length = -1; // avoid compiler warning
100
        upperCaseInfo = -1; // avoid compiler warning
101
        for (k=1; k<4; k++) {
102
                int mask;
103
                if (k == 1) mask = 1;//0b1;
104
                if (k == 2) mask = 2;//0b11;
105
                if (k == 3) mask = 4;//0b111;
106
                if (!found) for (i=1; i<=mask; i++) {
107
                        // 'k' characters
108
                        long test = 1;
109
                        for (j=0; j<k; ++j) {
110
                                test *= ((i&(1<<j)) != 0) ? 26 : 94-26;
111
                        }
112
                        uplim += test;
113
                        if ((lastThreeCharInfo >= lowlim) && (lastThreeCharInfo < uplim)) {
114
                                lastThreeCharInfo -= lowlim;
115
                                found = 1;
116
                                length = k;
117
                                upperCaseInfo = i;
118
                                break;
119
                        }
120
                        lowlim = uplim;
121
                }
122
        }
207 daniel-mar 123
 
247 daniel-mar 124
        key = ('a' + firstChar) << 24; // first char is lower-case
125
        for (i=0; i<length; ++i) {
126
                char res;
127
                if ((upperCaseInfo&(1<<i)) == 0) {
128
                        res = '!' + (lastThreeCharInfo % (94-26));
129
                        if (res >= 'A') res += 26;
130
                        lastThreeCharInfo /= (94-26);
131
                } else {
132
                        res = 'A' + (lastThreeCharInfo % 26);
133
                        lastThreeCharInfo /= 26;
134
                }
135
                key |= res << (8*(i+(4-length-1))); // 2nd, 3rd, 4th char are either upper-case or any printable char
136
        }
137
        if (length == 1) {
138
                key &= 0xFFFF0000;
139
                key |= ' ' << 8;
140
                key |= ' ';
141
        }
142
        if (length == 2) {
143
                key &= 0xFFFFFF00;
144
                key |= ' ';
145
        }
146
        return key;
268 daniel-mar 147
 
148
        #endif
184 dmarschall 149
}
150
 
238 daniel-mar 151
size_t roundToNext4(size_t x) {
247 daniel-mar 152
        int pad = 4 - (x % 4);
153
        if (pad == 0) pad = 4;
154
        return x + pad;
184 dmarschall 155
}
156
 
208 daniel-mar 157
size_t fixpipl(PIPropertyList *pipl, size_t origsize, StringPtr title, long *event_id) {
247 daniel-mar 158
        PIProperty *prop;
159
        char *p;
160
        struct hstm_data {
161
                /* this structure must be 14+1 bytes long, to match PiPL structure */
162
                long version; /* = 0 */
163
                long class_id;
164
                long event_id;
165
                short aete_resid;
166
                char scope[1];
167
        };
168
        struct hstm_data *hstm;
169
        int scopelen;
170
        unsigned long hash;
171
        size_t realLength;
172
        size_t roundedLength;
173
        char* scope;
184 dmarschall 174
 
247 daniel-mar 175
        pipl->count += 3; // 3 more keys in PiPL: name, catg, hstm
184 dmarschall 176
 
247 daniel-mar 177
        p = (char*)pipl + origsize;
178
        prop = (PIProperty*)p;
184 dmarschall 179
 
247 daniel-mar 180
        /* add Title/Name property key */
184 dmarschall 181
 
247 daniel-mar 182
        prop->vendorID = kPhotoshopSignature;
183
        prop->propertyKey = PINameProperty;
184
        prop->propertyID = 0;
185
        prop->propertyLength = (SPInt32)roundToNext4((size_t)title[0] + 1);
186
        memset(prop->propertyData, 0x00, prop->propertyLength); // fill padding with 00h bytes (cosmetics)
187
        PLstrcpy((StringPtr)prop->propertyData, title);
184 dmarschall 188
 
247 daniel-mar 189
        // skip past new property record, and any padding
190
        p += offsetof(PIProperty, propertyData) + prop->propertyLength;
191
        prop = (PIProperty*)p;
184 dmarschall 192
 
247 daniel-mar 193
        /* add Category property key */
184 dmarschall 194
 
247 daniel-mar 195
        prop->vendorID = kPhotoshopSignature;
196
        prop->propertyKey = PICategoryProperty;
197
        prop->propertyID = 0;
218 daniel-mar 198
 
247 daniel-mar 199
        prop->propertyLength = (SPInt32)roundToNext4((size_t)gdata->parm.category[0] + 1);
200
        memset(prop->propertyData, 0x00, prop->propertyLength); // fill padding with 00h bytes (cosmetics)
201
        PLstrcpy((StringPtr)prop->propertyData, gdata->parm.category);
184 dmarschall 202
 
247 daniel-mar 203
        p += offsetof(PIProperty, propertyData) + prop->propertyLength;
204
        prop = (PIProperty*)p;
184 dmarschall 205
 
247 daniel-mar 206
        /* add HasTerminology property key */
184 dmarschall 207
 
247 daniel-mar 208
        hstm = (struct hstm_data*)prop->propertyData;
212 daniel-mar 209
 
247 daniel-mar 210
        scope = (char*)malloc(0x300);
211
        if (!scope) return -1;
212
        sprintf(scope, "%s %s",
213
            INPLACEP2CSTR(gdata->parm.category),
214
            INPLACEP2CSTR(title));
228 daniel-mar 215
 
247 daniel-mar 216
        #ifdef ENABLE_APPLESCRIPT
217
        // If the uniqueString/scope is set, the plugin will only communicate with Photoshop.
218
        // Otherwise it can be accessed with AppleScript, but the AETE keys need to be unique then.
219
        // This is achieved with getAeteKey().
220
        scopelen = 0;
221
        hstm->scope[0] = '\0';
222
        #else
223
        // Construct scope string by concatenating Category and Title - hopefully unique!
224
        // Note: In doresources() we malloc'ed 300h additional bytes,
225
        // and in the build dialog, title and category are size-limited,
226
        // so we can write here without malloc.
227
        scopelen = strlen(scope);
228
        memcpy(&hstm->scope, scope, scopelen);
229
        #endif
184 dmarschall 230
 
247 daniel-mar 231
        /* make up a new event ID for this aete, based on printable base-95 hash of scope */
232
        hash = djb2(scope);
233
        *event_id = printablehash(hash); /* this is used by aete_generate() later... */
184 dmarschall 234
 
247 daniel-mar 235
        prop->vendorID = kPhotoshopSignature;
236
        prop->propertyKey = PIHasTerminologyProperty;
237
        prop->propertyID = 0;
184 dmarschall 238
 
247 daniel-mar 239
        realLength = offsetof(struct hstm_data, scope) + scopelen + 1/*null-term*/;
240
        roundedLength = roundToNext4(realLength);
241
        prop->propertyLength = (SPInt32)roundedLength;
242
        memset(prop->propertyData + realLength, 0x00, roundedLength - realLength); // fill padding with 00h bytes (cosmetics)
218 daniel-mar 243
 
247 daniel-mar 244
        hstm->version = 0;
245
        hstm->class_id = plugInClassID;
246
        hstm->event_id = *event_id;
247
        hstm->aete_resid = AETE_ID;
184 dmarschall 248
 
247 daniel-mar 249
        p += offsetof(PIProperty, propertyData) + prop->propertyLength;
184 dmarschall 250
 
247 daniel-mar 251
        return p - (char*)pipl;  // figure how many bytes were added
184 dmarschall 252
}
253
 
187 dmarschall 254
void _aete_write_byte(void** aeteptr, uint8_t val) {
247 daniel-mar 255
        uint8_t* tmp = *((uint8_t**)aeteptr);
256
        *tmp = val;
257
        *aeteptr = (void*)((unsigned char*)tmp + 1);
187 dmarschall 258
}
259
#define AETE_WRITE_BYTE(i) _aete_write_byte(&aeteptr, (i));
184 dmarschall 260
 
187 dmarschall 261
void _aete_write_word(void** aeteptr, uint16_t val) {
247 daniel-mar 262
        uint16_t* tmp = *((uint16_t**)aeteptr);
263
        *tmp = val;
264
        *aeteptr = (void*)((unsigned char*)tmp + 2);
187 dmarschall 265
}
266
#define AETE_WRITE_WORD(i) _aete_write_word(&aeteptr, (i));
267
 
268
void _aete_write_dword(void** aeteptr, uint32_t val) {
247 daniel-mar 269
        uint32_t* tmp = *((uint32_t**)aeteptr);
270
        *tmp = val;
271
        *aeteptr = (void*)((unsigned char*)tmp + 4);
187 dmarschall 272
}
273
#define AETE_WRITE_DWORD(i) _aete_write_dword(&aeteptr, (i));
274
 
229 daniel-mar 275
void _aete_write_c2pstr(void** aeteptr, char* str) {
247 daniel-mar 276
        char* tmp;
187 dmarschall 277
 
247 daniel-mar 278
        assert(strlen(str) <= 255);
187 dmarschall 279
 
247 daniel-mar 280
        _aete_write_byte(aeteptr, (uint8_t)strlen(str));
187 dmarschall 281
 
247 daniel-mar 282
        tmp = *((char**)aeteptr);
283
        strcpy(tmp, str);
284
        *aeteptr = (void*)((unsigned char*)tmp + strlen(str));
187 dmarschall 285
}
229 daniel-mar 286
#define AETE_WRITE_C2PSTR(s) _aete_write_c2pstr(&aeteptr, (s));
268 daniel-mar 287
 
229 daniel-mar 288
void _aete_write_p2pstr(void** aeteptr, char* str) {
289
    char* tmp;
187 dmarschall 290
 
229 daniel-mar 291
    if (strlen(str) == 0) {
247 daniel-mar 292
        _aete_write_byte(aeteptr, 0);
229 daniel-mar 293
    } else {
247 daniel-mar 294
        tmp = *((char**)aeteptr);
295
        strcpy(tmp, str);
296
        *aeteptr = (void*)((unsigned char*)tmp + strlen(str));
229 daniel-mar 297
    }
298
}
299
#define AETE_WRITE_P2PSTR(s) _aete_write_p2pstr(&aeteptr, (s));
300
 
187 dmarschall 301
void _aete_align_word(void** aeteptr) {
247 daniel-mar 302
        #ifdef MAC_ENV
303
        unsigned char* tmp = *((unsigned char**)aeteptr);
304
        tmp += (intptr_t)tmp & 1;
305
        *aeteptr = (void*)tmp;
306
        #endif
187 dmarschall 307
}
308
#define AETE_ALIGN_WORD() _aete_align_word(&aeteptr);
309
 
185 dmarschall 310
void* _aete_property(void* aeteptr, PARM_T *pparm, int ctlidx, int mapidx, OSType key) {
247 daniel-mar 311
        char tmp[256];
185 dmarschall 312
 
247 daniel-mar 313
        if (pparm->ctl_used[ctlidx] || pparm->map_used[mapidx]) {
314
                if (pparm->map_used[mapidx]) {
315
                        if (ctlidx & 1) {
316
                                sprintf(tmp, "... %s", (char*)pparm->map[mapidx]);
317
                        } else {
318
                                sprintf(tmp, "%s ...", (char*)pparm->map[mapidx]);
319
                        }
320
                        AETE_WRITE_C2PSTR(tmp);
321
                } else {
322
                        AETE_WRITE_P2PSTR((char*)pparm->ctl[ctlidx]);
323
                }
324
                AETE_ALIGN_WORD();
325
                AETE_WRITE_DWORD(key);
326
                AETE_WRITE_DWORD(typeSInt32);
327
                AETE_WRITE_C2PSTR(_strdup(""));
328
                AETE_ALIGN_WORD();
329
                AETE_WRITE_WORD(0x8000); /* FLAGS_1_OPT_PARAM / flagsOptionalSingleParameter */
330
        }
185 dmarschall 331
 
247 daniel-mar 332
        return aeteptr;
185 dmarschall 333
}
334
 
208 daniel-mar 335
size_t aete_generate(void* aeteptr, PARM_T *pparm, long event_id) {
247 daniel-mar 336
        // TODO: Can't we use the PI SDK to create an AETE?
337
        int numprops;
338
        void *beginptr = aeteptr;
228 daniel-mar 339
 
247 daniel-mar 340
        // Attention!
341
        // - On some systems (e.g. ARM based CPUs) this will cause an unaligned memory access exception.
342
        //   For X86, memory access just becomes slower.
343
        // - If you change something here, please also change it in Scripting.rc (Windows) and scripting.r (Mac OS)
184 dmarschall 344
 
247 daniel-mar 345
        // Note:
346
        // - The 'aete' resource for Mac OS has word alignments after strings (but not if the next element is also a string)
347
        //   see https://developer.apple.com/library/archive/documentation/mac/pdf/Interapplication_Communication/AE_Term_Resources.pdf page 8-9
184 dmarschall 348
 
268 daniel-mar 349
        #ifdef WIN_ENV
247 daniel-mar 350
        AETE_WRITE_WORD(0x0001); /* Reserved (for Photoshop) */
268 daniel-mar 351
        #endif
352
 
247 daniel-mar 353
        AETE_WRITE_BYTE(0x01); /* aete version */
354
        AETE_WRITE_BYTE(0x00); /* aete version */
355
        AETE_WRITE_WORD(english); /* language specifiers */
356
        AETE_WRITE_WORD(roman);
357
        AETE_WRITE_WORD(1); /* 1 suite */
358
        {
359
                AETE_WRITE_P2PSTR((char*)pparm->author); /* vendor suite name */
360
                AETE_WRITE_C2PSTR(_strdup("")); /* optional description */
361
                AETE_ALIGN_WORD();
362
                AETE_WRITE_DWORD(plugInSuiteID); /* suite ID */
363
                AETE_WRITE_WORD(1); /* suite code, must be 1. Attention: Filters like 'Pointillize' have set this to 0! */
364
                AETE_WRITE_WORD(1); /* suite level, must be 1. Attention: Filters like 'Pointillize' have set this to 0! */
365
                AETE_WRITE_WORD(1); /* 1 event (structure for filters) */
366
                {
367
                        AETE_WRITE_P2PSTR((char*)pparm->title); /* event name */
368
                        AETE_WRITE_C2PSTR(_strdup("")); /* event description */
369
                        AETE_ALIGN_WORD();
370
                        AETE_WRITE_DWORD(plugInClassID); /* event class */
371
                        AETE_WRITE_DWORD(/*plugInEventID*/event_id); /* event ID */
372
                        /* NO_REPLY: */
373
                        AETE_WRITE_DWORD(noReply); /* noReply='null' */
374
                        AETE_WRITE_C2PSTR(_strdup("")); /* reply description */
375
                        AETE_ALIGN_WORD();
376
                        AETE_WRITE_WORD(0);
377
                        /* IMAGE_DIRECT_PARAM: */
378
                        AETE_WRITE_DWORD(typeImageReference); /* typeImageReference='#ImR' */
379
                        AETE_WRITE_C2PSTR(_strdup("")); /* direct parm description */
380
                        AETE_ALIGN_WORD();
381
                        AETE_WRITE_WORD(0xB000);
184 dmarschall 382
 
247 daniel-mar 383
                        numprops = 0;
384
                        if (pparm->ctl_used[0] || pparm->map_used[0]) numprops++;
385
                        if (pparm->ctl_used[1] || pparm->map_used[0]) numprops++;
386
                        if (pparm->ctl_used[2] || pparm->map_used[1]) numprops++;
387
                        if (pparm->ctl_used[3] || pparm->map_used[1]) numprops++;
388
                        if (pparm->ctl_used[4] || pparm->map_used[2]) numprops++;
389
                        if (pparm->ctl_used[5] || pparm->map_used[2]) numprops++;
390
                        if (pparm->ctl_used[6] || pparm->map_used[3]) numprops++;
391
                        if (pparm->ctl_used[7] || pparm->map_used[3]) numprops++;
392
                        AETE_WRITE_WORD(numprops);
393
                        {
394
                                // Standalone filters don't need RGBA expressions
395
                                /*
396
                                AETE_WRITE_C2PSTR(_strdup("R"));
397
                                AETE_ALIGN_WORD();
398
                                AETE_WRITE_DWORD(PARAM_R_KEY);
399
                                AETE_WRITE_DWORD(typeText);
400
                                AETE_WRITE_C2PSTR(_strdup("R channel expression"));
401
                                AETE_ALIGN_WORD();
402
                                AETE_WRITE_WORD(0x8000);
184 dmarschall 403
 
247 daniel-mar 404
                                AETE_WRITE_C2PSTR(_strdup("G"));
405
                                AETE_ALIGN_WORD();
406
                                AETE_WRITE_DWORD(PARAM_G_KEY);
407
                                AETE_WRITE_DWORD(typeText);
408
                                AETE_WRITE_C2PSTR(_strdup("G channel expression"));
409
                                AETE_ALIGN_WORD();
410
                                AETE_WRITE_WORD(0x8000);
184 dmarschall 411
 
247 daniel-mar 412
                                AETE_WRITE_C2PSTR(_strdup("B"));
413
                                AETE_ALIGN_WORD();
414
                                AETE_WRITE_DWORD(PARAM_B_KEY);
415
                                AETE_WRITE_DWORD(typeText);
416
                                AETE_WRITE_C2PSTR(_strdup("B channel expression"));
417
                                AETE_ALIGN_WORD();
418
                                AETE_WRITE_WORD(0x8000);
184 dmarschall 419
 
247 daniel-mar 420
                                AETE_WRITE_C2PSTR(_strdup("A"));
421
                                AETE_ALIGN_WORD();
422
                                AETE_WRITE_DWORD(PARAM_A_KEY);
423
                                AETE_WRITE_DWORD(typeText);
424
                                AETE_WRITE_C2PSTR(_strdup("A channel expression"));
425
                                AETE_ALIGN_WORD();
426
                                AETE_WRITE_WORD(0x8000);
427
                                */
184 dmarschall 428
 
247 daniel-mar 429
                                aeteptr = _aete_property(aeteptr, pparm, 0, 0, getAeteKey('0', pparm));
430
                                aeteptr = _aete_property(aeteptr, pparm, 1, 0, getAeteKey('1', pparm));
431
                                aeteptr = _aete_property(aeteptr, pparm, 2, 1, getAeteKey('2', pparm));
432
                                aeteptr = _aete_property(aeteptr, pparm, 3, 1, getAeteKey('3', pparm));
433
                                aeteptr = _aete_property(aeteptr, pparm, 4, 2, getAeteKey('4', pparm));
434
                                aeteptr = _aete_property(aeteptr, pparm, 5, 2, getAeteKey('5', pparm));
435
                                aeteptr = _aete_property(aeteptr, pparm, 6, 3, getAeteKey('6', pparm));
436
                                aeteptr = _aete_property(aeteptr, pparm, 7, 3, getAeteKey('7', pparm));
437
                        }
438
                }
184 dmarschall 439
 
247 daniel-mar 440
                /* non-filter plug-in class here */
441
                AETE_WRITE_WORD(0); /* 0 classes */
442
                {}
443
                AETE_WRITE_WORD(0); /* 0 comparison ops (not supported) */
444
                {}
445
                AETE_WRITE_WORD(0); /* 0 enumerations */
446
                {}
447
        }
448
        AETE_WRITE_DWORD(0); /* padding (FIXME: do we need that? Adobe's Windows filters don't) */
184 dmarschall 449
 
247 daniel-mar 450
        return (unsigned char*)aeteptr - (unsigned char*)beginptr; // length of stuff written
184 dmarschall 451
}
452
 
256 daniel-mar 453
// Using rand() is more secure, because it differs from compiler to compiler, so
454
// it is harder to read a protected 8BF plugin.
455
// Note that rand() in combination with srand() is deterministic, so it is safe
456
// to use it: https://stackoverflow.com/questions/55438293/does-rand-function-in-c-follows-non-determinstc-algorithm
457
int randInRange(int min, int max) {
458
        // https://stackoverflow.com/questions/15621764/generate-a-random-byte-stream
459
        double scale = 1.0 / (RAND_MAX + 1);
460
        double range = (double)max - (double)min + 1;
461
        return min + (int)(rand() * scale * range);
184 dmarschall 462
}
211 daniel-mar 463
 
255 daniel-mar 464
void obfusc(unsigned char* pparm, size_t size, size_t seed_position) {
465
        unsigned char* p;
256 daniel-mar 466
        size_t i;
255 daniel-mar 467
        unsigned int seed;
468
 
469
        seed = (unsigned int)time(0);
256 daniel-mar 470
        srand(seed);
255 daniel-mar 471
 
472
        p = pparm;
256 daniel-mar 473
        for (i = 0; i < seed_position; i++) *p++ ^= randInRange(0,255);
255 daniel-mar 474
        *((unsigned int*)p) = seed; // seed is placed at this position. data will lost! (in deobfusc, it will be set to 0x00000000)
475
        p += 4;
256 daniel-mar 476
        for (i = 0; i < size - seed_position - 4; i++) *p++ ^= randInRange(0, 255);
232 daniel-mar 477
}
255 daniel-mar 478
 
479
void deobfusc(unsigned char* pparm, size_t size, size_t seed_position) {
480
        unsigned char* p;
256 daniel-mar 481
        size_t i;
255 daniel-mar 482
        unsigned int seed;
483
 
484
        seed = *((unsigned int*)(pparm + seed_position));
256 daniel-mar 485
        srand(seed);
255 daniel-mar 486
 
487
        p = pparm;
256 daniel-mar 488
        for (i = 0; i < seed_position; i++) *p++ ^= randInRange(0, 255);
255 daniel-mar 489
        *((unsigned int*)p) = 0; // here was the seed. Fill it with 0x00000000
490
        p += 4;
256 daniel-mar 491
        for (i = 0; i < size - seed_position - 4; i++) *p++ ^= randInRange(0, 255);
255 daniel-mar 492
}