1 /*
2 29/12/2006 - 13/10/2014
3 XORSearch V1.11.1, search for a XOR, ROL, ROT, SHIFT or ADD encoded string in a file
4 Use -s to save the XOR, ROL, ROT, SHIFT or ADD encoded file containing the string
5 Use -l length to limit the number of printed characters (50 by default)
6 Use -i to ignore the case when searching
7 Use -u to search for Unicode strings (limited support)
8 Use -f to provide a file with search strings
9 Use -n length to print the length neighbouring charaters (before & after the found keyword)
10 Use -h to search for hex strings
11 Use -k to decode with embedded keys
12 Source code put in public domain by Didier Stevens, no Copyright
13 https://DidierStevens.com
14 Use at your own risk
15
16 Shortcommings, or todo's ;-)
17 - optimize embedded keys algos for speed
18 - no pipe support (file redirection)
19 - file must fit in memory
20
21 History:
22 15/01/2007: multiple hits, only printable characters, length argument
23 08/08/2007: 1.2: added ROL 1 to 7 encoding
24 17/12/2007: 1.3: findfile
25 18/04/2009: 1.4: ROT encoding
26 12/01/2010: 1.5: added (limited) Unicode support; -n option
27 15/01/2010: 1.6: added hex support
28 29/10/2012: 1.7: Dropped malloc.h
29 16/02/2013: 1.8: Added SHIFT encoding
30 15/06/2013: 1.9: Added embedded keys decoding
31 16/06/2013: Continued embedded keys decoding
32 10/07/2013: Added InsertSorted to optimize embedded keys algos for speed
33 11/07/2013: Continued InsertSorted
34 19/07/2013: 1.9.1: code cleanup, refactoring
35 13/10/2013: 1.9.2: Added ucOffset to PrintFinds
36 14/02/2014: 1.10.0: Added option -p and -e
37 17/02/2014: Compatibility checking of option -p with other options
38 20/03/2014: changed ulE_lfanew (unsigned long) to uiE_lfanew (unsigned int)
39 23/03/2014: 1.10.0: fixes for xcode gcc warnings
40 27/08/2014: 1.11.0 added ADD encoding, bugfix ParseNumericArg, wildcards search engine
41 29/08/2014: XORSearch returns 0 when strings are found, 1 when nothing is found, and -1 if error
42 30/08/2014: added wildcard rules parsing, score, option -d
43 04/09/2014: added support for jumps in rules (J;?)
44 15/09/2014: added Realloc
45 27/09/2014: added option -L
46 11/10/2014: 1.11.1: fixes for xcode gcc warnings
47 13/10/2014: added option -x
48
49 */
50
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <sys/stat.h>
54 #include <string.h>
55 #include <ctype.h>
56 #include <limits.h>
57
58 #define countof(array) (sizeof(array) / sizeof(array[0]))
59
60 #define XSIZE 1024
61
62 #define OPR_XOR "XOR"
63 #define OPR_ROL "ROL"
64 #define OPR_ROT "ROT"
65 #define OPR_SHIFT "SHIFT"
66 #define OPR_XOR32 "XOR32"
67 #define OPR_ADD "ADD"
68
69 #define SEARCHTYPE_STOP 0
70 #define SEARCHTYPE_ASCII 1
71 #define SEARCHTYPE_UNICODE 2
72 #define SEARCHTYPE_HEX 3
73 #define SEARCHTYPE_WILDCARD 4
74
75 #define WILDCARD_MODE_BYTE 0
76 #define WILDCARD_MODE_BITS 1
77 #define WILDCARD_MODE_JUMP 2
78 #define WILDCARD_MODE_STOP 3
79
80 typedef struct
81 {
82 unsigned char ucMode; //WILDCARD_MODE_
83 unsigned char ucByte;
84 unsigned char ucMaskFixed;
85 unsigned char ucBitsFixed;
86 unsigned char ucMaskVariable1;
87 char cVariableName1;
88 unsigned char ucMaskVariable2;
89 char cVariableName2;
90 unsigned char ucJumpBytes;
91 } WILDCARD;
92
93 typedef struct
94 {
95 int iSearchType;
96 char *pcSearchString;
97 int iSearchLength;
98 char *pcWildcardName;
99 int iScore;
100 WILDCARD *pWildcards;
101 int iPrintASCII;
102 } SEARCH;
103
104 int *piFoundIndex;
105 int *piFoundSize;
106
StartsWith(char * szString,char * szPrefix)107 int StartsWith(char *szString, char *szPrefix)
108 {
109 if (strlen(szString) < strlen(szPrefix))
110 return 0;
111 return !strncmp(szString, szPrefix, strlen(szPrefix));
112 }
113
compare(char cX,char cY,int iFlagIgnoreCase)114 int compare(char cX, char cY, int iFlagIgnoreCase)
115 {
116 if (iFlagIgnoreCase && isalpha(cX) && isalpha(cY))
117 return tolower(cX) == tolower(cY);
118 else
119 return cX == cY;
120 }
121
122 // Search algorithm: http://www-igm.univ-mlv.fr/~lecroq/string/node8.html#SECTION0080
PreKMP(char * pcX,int iXLength,int aiKMPNext[],int iFlagIgnoreCase)123 void PreKMP(char *pcX, int iXLength, int aiKMPNext[], int iFlagIgnoreCase)
124 {
125 int iIter1, iIter2;
126
127 iIter1 = 0;
128 iIter2 = aiKMPNext[0] = -1;
129 while (iIter1 < iXLength)
130 {
131 while (iIter2 > -1 && !compare(pcX[iIter1], pcX[iIter2], iFlagIgnoreCase))
132 iIter2 = aiKMPNext[iIter2];
133 iIter1++;
134 iIter2++;
135 if (compare(pcX[iIter1], pcX[iIter2], iFlagIgnoreCase))
136 aiKMPNext[iIter1] = aiKMPNext[iIter2];
137 else
138 aiKMPNext[iIter1] = iIter2;
139 }
140 }
141
KMP(char * pcX,int iXLength,char * pcY,int iYLength,int iFlagIgnoreCase)142 int KMP(char *pcX, int iXLength, char *pcY, int iYLength, int iFlagIgnoreCase)
143 {
144 int iIter1, iIter2, aiKMPNext[XSIZE];
145 int iCountFinds = 0;
146
147 if (iXLength > XSIZE)
148 {
149 fprintf(stderr, "KMP size error\n");
150 return 0;
151 }
152
153 /* Preprocessing */
154 PreKMP(pcX, iXLength, aiKMPNext, iFlagIgnoreCase);
155
156 /* Searching */
157 iIter1 = iIter2 = 0;
158 while (iIter2 < iYLength)
159 {
160 while (iIter1 > -1 && !compare(pcX[iIter1], pcY[iIter2], iFlagIgnoreCase))
161 iIter1 = aiKMPNext[iIter1];
162 iIter1++;
163 iIter2++;
164 if (iIter1 >= iXLength)
165 {
166 piFoundIndex[iCountFinds] = iIter2-iIter1;
167 piFoundSize[iCountFinds++] = iXLength;
168 iIter1 = aiKMPNext[iIter1];
169 }
170 }
171 return iCountFinds;
172 }
173
WildcardSearch(SEARCH * pSearch,unsigned char * pucBuffer,long lSize,char * sOperation,unsigned char ucOffset,unsigned int uiOperand,int iMaxLength,int * piScore)174 int WildcardSearch(SEARCH *pSearch, unsigned char *pucBuffer, long lSize, char *sOperation, unsigned char ucOffset, unsigned int uiOperand, int iMaxLength, int *piScore)
175 {
176 int iFound;
177 unsigned char *pucFoundCharFirst;
178 unsigned char *pucSearchBuffer;
179 int iIter;
180 int iPosition;
181 unsigned char *pucLastByteInBuffer;
182 int aiVariables[26];
183
184 pucSearchBuffer = pucBuffer;
185 pucLastByteInBuffer = pucBuffer + lSize - 1;
186 iFound = 0;
187 while(1)
188 {
189 pucFoundCharFirst = memchr(pucSearchBuffer, pSearch->pWildcards[0].ucByte, lSize - (pucSearchBuffer - pucBuffer));
190 if (pucFoundCharFirst == NULL)
191 break;
192 for (iIter = 0; iIter < 26; iIter ++)
193 aiVariables[iIter] = -1;
194 iIter = 1;
195 iPosition = 1;
196 while (pSearch->pWildcards[iIter].ucMode != WILDCARD_MODE_STOP)
197 {
198 if (pSearch->pWildcards[iIter].ucMode == WILDCARD_MODE_BYTE)
199 {
200 if ((pucFoundCharFirst + iPosition) > pucLastByteInBuffer || pSearch->pWildcards[iIter].ucByte != *(pucFoundCharFirst + iPosition))
201 break;
202 iIter++;
203 iPosition++;
204 }
205 else if (pSearch->pWildcards[iIter].ucMode == WILDCARD_MODE_BITS)
206 {
207 if ((pucFoundCharFirst + iPosition) > pucLastByteInBuffer || pSearch->pWildcards[iIter].ucBitsFixed != (*(pucFoundCharFirst + iPosition) & pSearch->pWildcards[iIter].ucMaskFixed))
208 break;
209 if (pSearch->pWildcards[iIter].ucMaskVariable1 != 0)
210 {
211 unsigned char ucMask = pSearch->pWildcards[iIter].ucMaskVariable1;
212 unsigned char ucValue = *(pucFoundCharFirst + iPosition) & ucMask;
213 while ((ucMask & 0x01) == 0)
214 {
215 ucMask = ucMask >> 1;
216 ucValue = ucValue >> 1;
217 }
218 if (aiVariables[pSearch->pWildcards[iIter].cVariableName1] == -1)
219 aiVariables[pSearch->pWildcards[iIter].cVariableName1] = ucValue;
220 else if (aiVariables[pSearch->pWildcards[iIter].cVariableName1] != ucValue)
221 break;
222 }
223 if (pSearch->pWildcards[iIter].ucMaskVariable2 != 0)
224 {
225 unsigned char ucMask = pSearch->pWildcards[iIter].ucMaskVariable2;
226 unsigned char ucValue = *(pucFoundCharFirst + iPosition) & ucMask;
227 while ((ucMask & 0x01) == 0)
228 {
229 ucMask = ucMask >> 1;
230 ucValue = ucValue >> 1;
231 }
232 if (aiVariables[pSearch->pWildcards[iIter].cVariableName2] == -1)
233 aiVariables[pSearch->pWildcards[iIter].cVariableName2] = ucValue;
234 else if (aiVariables[pSearch->pWildcards[iIter].cVariableName2] != ucValue)
235 break;
236 }
237 iIter++;
238 iPosition++;
239 }
240 else if (pSearch->pWildcards[iIter].ucMode == WILDCARD_MODE_JUMP)
241 {
242 if (4 == pSearch->pWildcards[iIter].ucJumpBytes && (pucFoundCharFirst + iPosition + 3) > pucLastByteInBuffer)
243 break;
244 switch (pSearch->pWildcards[iIter].ucJumpBytes)
245 {
246 case 1:
247 iPosition += 1 + *(char *)(pucFoundCharFirst + iPosition);
248 break;
249 case 4:
250 iPosition += 4 + *(int *)(pucFoundCharFirst + iPosition);
251 break;
252 }
253 //a// fix for integer overflow
254 if ((pucFoundCharFirst + iPosition) < pucBuffer || (pucFoundCharFirst + iPosition) > pucLastByteInBuffer)
255 break;
256 iIter++;
257 }
258 }
259 if (pSearch->pWildcards[iIter].ucMode == WILDCARD_MODE_STOP)
260 {
261 iFound = 1;
262 *piScore += pSearch->iScore;
263 if (!strcmp(sOperation, OPR_XOR32))
264 printf("Found %s %08X offset +%d position %08lX: %s ", sOperation, uiOperand, ucOffset, pucFoundCharFirst - pucBuffer, pSearch->pcWildcardName);
265 else if (strcmp(sOperation, OPR_ROT))
266 printf("Found %s %02X position %08lX: %s ", sOperation, uiOperand, pucFoundCharFirst - pucBuffer, pSearch->pcWildcardName);
267 else
268 printf("Found %s %02d position %08lX: %s ", sOperation, uiOperand, pucFoundCharFirst - pucBuffer, pSearch->pcWildcardName);
269 for (iIter = 0; iIter < iMaxLength && pSearch->pWildcards[iIter].ucMode != WILDCARD_MODE_STOP && pucFoundCharFirst + iIter <= pucLastByteInBuffer; iIter++)
270 if (pSearch->pWildcards[iIter].ucMode == WILDCARD_MODE_JUMP)
271 {
272 int iIter2;
273 for (iIter2 = 0; iIter2 < pSearch->pWildcards[iIter].ucJumpBytes; iIter2++)
274 printf("%02X", ((unsigned char *)pucFoundCharFirst)[iIter + iIter2]);
275 break;
276 }
277 else if (pSearch->iPrintASCII)
278 putchar(((unsigned char *)pucFoundCharFirst)[iIter]);
279 else
280 printf("%02X", ((unsigned char *)pucFoundCharFirst)[iIter]);
281 putchar('\n');
282 }
283 pucSearchBuffer = pucFoundCharFirst + 1;
284 }
285
286 return iFound;
287 }
288
WildcardSearches(SEARCH * pSearch,unsigned char * pucBuffer,long lSize,char * sOperation,unsigned char ucOffset,unsigned int uiOperand,int iMaxLength,int * piScore)289 int WildcardSearches(SEARCH *pSearch, unsigned char *pucBuffer, long lSize, char *sOperation, unsigned char ucOffset, unsigned int uiOperand, int iMaxLength, int *piScore)
290 {
291 int iFound = 0;
292 int iIter;
293
294 for (iIter = 0; pSearch[iIter].iSearchType != SEARCHTYPE_STOP; iIter++)
295 {
296 if (WildcardSearch(&pSearch[iIter], pucBuffer, lSize, sOperation, ucOffset, uiOperand, iMaxLength, piScore))
297 iFound = 1;
298 }
299 return iFound;
300 }
301
ParseIntegerArg(const char * szArg)302 long ParseIntegerArg(const char *szArg)
303 {
304 char *szError;
305 long lResult;
306
307 lResult = strtol(szArg, &szError, 0);
308 if (*szError != '\0' || lResult == LONG_MIN || lResult == LONG_MAX)
309 return -1;
310 else
311 return lResult;
312 }
313
ParseHexArg(const char * szArg)314 long ParseHexArg(const char *szArg)
315 {
316 long lResult = 0;
317
318 while (*szArg != '\0')
319 {
320 if (*szArg >= '0' && *szArg <= '9')
321 lResult = lResult * 0x10 + *szArg - '0';
322 else if (*szArg >= 'a' && *szArg <= 'f')
323 lResult = lResult * 0x10 + *szArg - 'a' + 10;
324 else if (*szArg >= 'A' && *szArg <= 'F')
325 lResult = lResult * 0x10 + *szArg - 'A' + 10;
326 else
327 return -1;
328 if (lResult == LONG_MIN || lResult == LONG_MAX)
329 return -1;
330 szArg++;
331 }
332 return lResult;
333 }
334
ParseNumericArg(const char * szArg)335 long ParseNumericArg(const char *szArg)
336 {
337 if (!strncmp(szArg, "0x", 2))
338 return(ParseHexArg(szArg + 2));
339 else
340 return(ParseIntegerArg(szArg));
341 }
342
ParseArgs(int argc,char ** argv,int * piSave,int * piMaxLength,int * piIgnoreCase,char ** ppcFile,char ** ppcSearch,char ** ppcSearchFile,int * piUnicode,int * piNeighbourgLength,int * piHex,int * piKeys,int * piPEFile,int * piExcludeByte,int * piWildcard,int * piWildcardEmbedded,char ** ppcDisable,int * piList,int * piHexFile)343 int ParseArgs(int argc, char **argv, int *piSave, int *piMaxLength, int *piIgnoreCase, char **ppcFile, char **ppcSearch, char **ppcSearchFile, int *piUnicode, int *piNeighbourgLength, int *piHex, int *piKeys, int *piPEFile, int *piExcludeByte, int *piWildcard, int *piWildcardEmbedded, char **ppcDisable, int *piList, int *piHexFile)
344 {
345 int iIterArgv;
346 int iCountParameters;
347 int iFlagMaxLength;
348 int iFlagNeighbourgLength;
349 int iFlagSearchFile;
350 int iFlagExcludeByte;
351 int iFlagDisable;
352 char *pcFlags;
353
354 iCountParameters = 0;
355 iFlagMaxLength = 0;
356 iFlagNeighbourgLength = 0;
357 iFlagSearchFile = 0;
358 iFlagExcludeByte = 0;
359 iFlagDisable = 0;
360 *piSave = 0;
361 *piMaxLength = -1;
362 *piNeighbourgLength = -1;
363 *piIgnoreCase = 0;
364 *ppcSearch = NULL;
365 *ppcSearchFile = NULL;
366 *piUnicode = 0;
367 *piHex = 0;
368 *piKeys = 0;
369 *piPEFile = 0;
370 *piExcludeByte = -1;
371 *piWildcard = 0;
372 *piWildcardEmbedded = 0;
373 *ppcDisable = NULL;
374 *piList = 0;
375 *piHexFile = 0;
376
377 for (iIterArgv = 1; iIterArgv < argc; iIterArgv++)
378 {
379 if (argv[iIterArgv][0] == '-')
380 {
381 if (iFlagMaxLength || iFlagSearchFile || iFlagDisable)
382 return 1;
383 pcFlags = argv[iIterArgv] + 1;
384 while (*pcFlags)
385 switch (*pcFlags++)
386 {
387 case 's':
388 *piSave = 1;
389 break;
390 case 'i':
391 *piIgnoreCase = 1;
392 break;
393 case 'l':
394 iFlagMaxLength = 1;
395 break;
396 case 'f':
397 iFlagSearchFile = 1;
398 break;
399 case 'u':
400 *piUnicode = 1;
401 break;
402 case 'n':
403 iFlagNeighbourgLength = 1;
404 break;
405 case 'h':
406 *piHex = 1;
407 break;
408 case 'k':
409 *piKeys = 1;
410 break;
411 case 'p':
412 *piPEFile = 1;
413 break;
414 case 'e':
415 iFlagExcludeByte = 1;
416 break;
417 case 'w':
418 *piWildcard = 1;
419 break;
420 case 'W':
421 *piWildcardEmbedded = 1;
422 break;
423 case 'd':
424 iFlagDisable = 1;
425 break;
426 case 'L':
427 *piList = 1;
428 break;
429 case 'x':
430 *piHexFile = 1;
431 break;
432 default:
433 return 1;
434 }
435 }
436 else if (iFlagMaxLength)
437 {
438 *piMaxLength = ParseNumericArg(argv[iIterArgv]);
439 if (*piMaxLength < 1)
440 return 1;
441 iFlagMaxLength = 0;
442 }
443 else if (iFlagExcludeByte)
444 {
445 *piExcludeByte = ParseNumericArg(argv[iIterArgv]);
446 if (*piExcludeByte < 0x00 || *piExcludeByte > 0xFF)
447 return 1;
448 iFlagExcludeByte = 0;
449 }
450 else if (iFlagNeighbourgLength)
451 {
452 *piNeighbourgLength = ParseNumericArg(argv[iIterArgv]);
453 if (*piNeighbourgLength < 1)
454 return 1;
455 iFlagNeighbourgLength = 0;
456 }
457 else if (iFlagSearchFile)
458 {
459 *ppcSearchFile = argv[iIterArgv];
460 iFlagSearchFile = 0;
461 }
462 else if (iFlagDisable)
463 {
464 *ppcDisable = argv[iIterArgv];
465 iFlagDisable = 0;
466 }
467 else if (iCountParameters == 0)
468 {
469 *ppcFile = argv[iIterArgv];
470 iCountParameters++;
471 }
472 else if (iCountParameters == 1)
473 {
474 *ppcSearch = argv[iIterArgv];
475 iCountParameters++;
476 }
477 else
478 iCountParameters++;
479 }
480 if (1 == *piList)
481 return iCountParameters == 0 ? 0 : 1;
482 else if (iCountParameters != 2 && *ppcSearchFile == NULL && *piPEFile == 0 && *piWildcardEmbedded == 0)
483 return 1;
484 else if (iCountParameters != 1 && *ppcSearchFile != NULL)
485 return 1;
486 else if (iCountParameters != 1 && *piPEFile != 0)
487 return 1;
488 else if (iCountParameters != 1 && *piWildcardEmbedded != 0)
489 return 1;
490 else if (*piMaxLength != -1 && *piNeighbourgLength != -1)
491 return 1;
492 else if ((*piUnicode && *piHex) || (*piUnicode && (*piWildcard || *piWildcardEmbedded)) || (*piHex && (*piWildcard || *piWildcardEmbedded)) || (*piWildcard && *piWildcardEmbedded))
493 return 1;
494 else if (*piKeys && *piExcludeByte != -1)
495 return 1;
496 else if (*piPEFile != 0 && *ppcSearchFile != NULL)
497 return 1;
498 else if (*piPEFile != 0 && *piIgnoreCase != 0)
499 return 1;
500 else if (*piPEFile != 0 && *piUnicode != 0)
501 return 1;
502 else if (*piPEFile != 0 && *piHex != 0)
503 return 1;
504 else if (*piPEFile != 0 && *piNeighbourgLength != -1)
505 return 1;
506 else if (*piWildcardEmbedded != 0 && *ppcSearchFile != NULL)
507 return 1;
508 else
509 return 0;
510 }
511
XOR(unsigned char * pcBuffer,long lSize,unsigned char cXOR,int iExcludeByte)512 void XOR(unsigned char *pcBuffer, long lSize, unsigned char cXOR, int iExcludeByte)
513 {
514 unsigned char *pucLastByteInBuffer;
515
516 pucLastByteInBuffer = pcBuffer + lSize - 1;
517 while (pcBuffer <= pucLastByteInBuffer)
518 {
519 if (iExcludeByte < 0 || iExcludeByte != *pcBuffer)
520 *pcBuffer ^= cXOR;
521 pcBuffer++;
522 }
523 }
524
XOR32(unsigned int * puiBuffer,long lSize,unsigned int uiOffset,unsigned int uiXOR)525 void XOR32(unsigned int *puiBuffer, long lSize, unsigned int uiOffset, unsigned int uiXOR)
526 {
527 unsigned int *pucLastUIntInBuffer;
528
529 pucLastUIntInBuffer = ((unsigned int *)((unsigned char *)puiBuffer + lSize)) - 1;
530 puiBuffer = (unsigned int *)((unsigned char *)puiBuffer + uiOffset);
531 while (puiBuffer <= pucLastUIntInBuffer)
532 *puiBuffer++ ^= uiXOR;
533 }
534
ROL(unsigned char * pcBuffer,long lSize,int iExcludeByte)535 void ROL(unsigned char *pcBuffer, long lSize, int iExcludeByte)
536 {
537 unsigned char *pucLastByteInBuffer;
538
539 pucLastByteInBuffer = pcBuffer + lSize - 1;
540 while (pcBuffer <= pucLastByteInBuffer)
541 {
542 if (iExcludeByte < 0 || iExcludeByte != *pcBuffer)
543 *pcBuffer = *pcBuffer << 1 | *pcBuffer >> 7;
544 pcBuffer++;
545 }
546 }
547
ROT(unsigned char * pcBuffer,long lSize,int iExcludeByte)548 void ROT(unsigned char *pcBuffer, long lSize, int iExcludeByte)
549 {
550 unsigned char *pucLastByteInBuffer;
551
552 pucLastByteInBuffer = pcBuffer + lSize - 1;
553 while (pcBuffer <= pucLastByteInBuffer)
554 {
555 if (iExcludeByte < 0 || iExcludeByte != *pcBuffer)
556 {
557 if ((*pcBuffer >= 'a' && *pcBuffer < 'z') || (*pcBuffer >= 'A' && *pcBuffer < 'Z'))
558 (*pcBuffer)++;
559 else if (*pcBuffer == 'z')
560 *pcBuffer = 'a';
561 else if (*pcBuffer == 'Z')
562 *pcBuffer = 'A';
563 }
564 pcBuffer++;
565 }
566 }
567
SHIFT(unsigned char * pcBuffer,long lSize,int iExcludeByte)568 void SHIFT(unsigned char *pcBuffer, long lSize, int iExcludeByte)
569 {
570 unsigned char *pucLastByteInBuffer;
571 unsigned char ucFirstBit;
572
573 pucLastByteInBuffer = pcBuffer + lSize - 1;
574 ucFirstBit = *pcBuffer >> 7;
575 while (pcBuffer <= pucLastByteInBuffer - 1)
576 {
577 if (iExcludeByte < 0 || iExcludeByte != *pcBuffer)
578 *pcBuffer = *pcBuffer << 1 | *(pcBuffer + 1) >> 7;
579 pcBuffer++;
580 }
581 if (iExcludeByte < 0 || iExcludeByte != *pucLastByteInBuffer)
582 *pucLastByteInBuffer = *pucLastByteInBuffer << 1 | ucFirstBit;
583 }
584
ADD(unsigned char * pcBuffer,long lSize,int iExcludeByte)585 void ADD(unsigned char *pcBuffer, long lSize, int iExcludeByte)
586 {
587 unsigned char *pucLastByteInBuffer;
588
589 pucLastByteInBuffer = pcBuffer + lSize - 1;
590 while (pcBuffer <= pucLastByteInBuffer)
591 {
592 if (iExcludeByte < 0 || iExcludeByte != *pcBuffer)
593 *pcBuffer = *pcBuffer + 1;
594 pcBuffer++;
595 }
596 }
597
SaveFile(char * pcFile,char * sOperation,unsigned char ucXOR,void * pBuffer,long lSize)598 void SaveFile(char *pcFile, char *sOperation, unsigned char ucXOR, void *pBuffer, long lSize)
599 {
600 char szFileNameSave[XSIZE];
601 FILE *fOut;
602
603 snprintf(szFileNameSave, XSIZE, "%s.%s.%02X", pcFile, sOperation, ucXOR);
604 if ((fOut = fopen(szFileNameSave, "wb")) == NULL)
605 fprintf(stderr, "error opening file %s\n", szFileNameSave);
606 else
607 {
608 if (fwrite(pBuffer, lSize, 1, fOut) != 1)
609 fprintf(stderr, "error writing file %s\n", szFileNameSave);
610 fclose(fOut);
611 }
612 }
613
PrintFinds(int iCountFinds,int iMaxLength,char * sOperation,unsigned char ucOffset,unsigned int uiOperand,off_t otFileSize,void * pBuffer,int iSearchType,int iNeighbourgLength)614 void PrintFinds(int iCountFinds, int iMaxLength, char *sOperation, unsigned char ucOffset, unsigned int uiOperand, off_t otFileSize, void *pBuffer, int iSearchType, int iNeighbourgLength)
615 {
616 int iIter1, iIter2;
617 int iMaxPrint;
618 int iStart;
619 int iStop;
620 int iStep;
621
622 for (iIter1 = 0; iIter1 < iCountFinds; iIter1++)
623 {
624 if (!strcmp(sOperation, OPR_XOR32))
625 printf("Found %s %08X offset +%d position %04X", sOperation, uiOperand, ucOffset, piFoundIndex[iIter1]);
626 else if (strcmp(sOperation, OPR_ROT))
627 printf("Found %s %02X position %04X", sOperation, uiOperand, piFoundIndex[iIter1]);
628 else
629 printf("Found %s %02d position %04X", sOperation, uiOperand, piFoundIndex[iIter1]);
630 if (iNeighbourgLength > 0)
631 printf("(-%d): ", iNeighbourgLength);
632 else
633 printf(": ");
634 if (iNeighbourgLength > 0)
635 {
636 iStep = iSearchType == SEARCHTYPE_UNICODE ? 2 : 1;
637 iStart = piFoundIndex[iIter1] - iNeighbourgLength * iStep;
638 if (iStart < 0)
639 iStart = 0;
640 iStop = piFoundIndex[iIter1] + piFoundSize[iIter1] + iNeighbourgLength * iStep;
641 if (iStop > otFileSize)
642 iStop = otFileSize;
643 for (iIter2 = iStart; iIter2 < iStop; iIter2 += iStep)
644 if (SEARCHTYPE_HEX == iSearchType)
645 printf("%02X", ((unsigned char *)pBuffer)[iIter2]);
646 else
647 if (isprint(((unsigned char *)pBuffer)[iIter2]))
648 putchar(((unsigned char *)pBuffer)[iIter2]);
649 else
650 putchar('.');
651 }
652 else
653 {
654 iMaxPrint = iMaxLength;
655 iStep = iSearchType == SEARCHTYPE_UNICODE ? 2 : 1;
656 for (iIter2 = piFoundIndex[iIter1]; iIter2 < otFileSize && (SEARCHTYPE_HEX == iSearchType || ((unsigned char *)pBuffer)[iIter2]); iIter2 += iStep)
657 {
658 if (SEARCHTYPE_HEX == iSearchType)
659 printf("%02X", ((unsigned char *)pBuffer)[iIter2]);
660 else
661 if (isprint(((unsigned char *)pBuffer)[iIter2]))
662 putchar(((unsigned char *)pBuffer)[iIter2]);
663 else
664 putchar('.');
665 if (iMaxLength > 0 && --iMaxPrint == 0)
666 break;
667 }
668 }
669 putchar('\n');
670 }
671 }
672
673
strncpy0(char * pszDestination,char * pszSource,size_t stNum)674 char *strncpy0(char *pszDestination, char *pszSource, size_t stNum)
675 {
676 strncpy(pszDestination, pszSource, stNum);
677 pszDestination[stNum - 1] = '\0';
678 return pszDestination;
679 }
680
IsHexDigit(char cHexDigit)681 int IsHexDigit(char cHexDigit)
682 {
683 return (cHexDigit >= '0' && cHexDigit <= '9') || (cHexDigit >= 'A' && cHexDigit <= 'F') || (cHexDigit >= 'a' && cHexDigit <= 'f');
684 }
685
HexDigitToNibble(char cHexDigit)686 int HexDigitToNibble(char cHexDigit)
687 {
688 if (cHexDigit >= '0' && cHexDigit <= '9')
689 return cHexDigit - '0';
690 if (cHexDigit >= 'A' && cHexDigit <= 'F')
691 return cHexDigit - 'A' + 10;
692 if (cHexDigit >= 'a' && cHexDigit <= 'f')
693 return cHexDigit - 'a' + 10;
694 return -1;
695 }
696
Hexstring2Binary(char * pcHexString,char * pcBinary)697 int Hexstring2Binary(char *pcHexString, char *pcBinary)
698 {
699 int iCount = 0;
700
701 while ('\0' != *pcHexString && '\0' != *(pcHexString + 1) && iCount < XSIZE)
702 if (IsHexDigit(*pcHexString) && IsHexDigit(*(pcHexString + 1)))
703 {
704 pcBinary[iCount++] = (char) HexDigitToNibble(*pcHexString) * 0x10 + HexDigitToNibble(*(pcHexString + 1));
705 pcHexString += 2;
706 }
707 else
708 return -1;
709 if ('\0' != *pcHexString)
710 return -2;
711 else
712 return iCount;
713 }
714
GetSearchString(char * pcArgSearch,char * pcArgSearchFile,int iSearchType,int * piLength)715 char *GetSearchString(char *pcArgSearch, char *pcArgSearchFile, int iSearchType, int *piLength)
716 {
717 static char szSearch[XSIZE+1];
718 static int iArgSearchReturned;
719 static FILE *fSearchFile;
720 int iIter;
721
722 if (iArgSearchReturned)
723 {
724 iArgSearchReturned = 0;
725 return NULL;
726 }
727
728 if (pcArgSearch == NULL)
729 {
730 if (fSearchFile == NULL)
731 if ((fSearchFile = fopen(pcArgSearchFile, "r")) == NULL)
732 {
733 fprintf(stderr, "error opening file %s\n", pcArgSearchFile);
734 exit(-1);
735 }
736 if (fgets(szSearch, XSIZE, fSearchFile) == NULL)
737 {
738 fclose(fSearchFile);
739 fSearchFile = NULL;
740 return NULL;
741 }
742 else
743 {
744 if (strlen(szSearch) > 0 && szSearch[strlen(szSearch) - 1] == '\n')
745 szSearch[strlen(szSearch) - 1] = '\0';
746 switch (iSearchType)
747 {
748 case SEARCHTYPE_ASCII:
749 *piLength = strlen(szSearch);
750 break;
751 case SEARCHTYPE_UNICODE:
752 *piLength = 2 * strlen(szSearch);
753 for (iIter = XSIZE / 2; iIter > 0; iIter--)
754 szSearch[2 * iIter] = szSearch[iIter];
755 for (iIter = 1; iIter <= XSIZE; iIter += 2)
756 szSearch[iIter] = '\0';
757 break;
758 case SEARCHTYPE_HEX:
759 *piLength = Hexstring2Binary(szSearch, szSearch);
760 if (*piLength < 0)
761 {
762 fprintf(stderr, "Error parsing hex string\n");
763 exit(-1);
764 }
765 break;
766 default:
767 fprintf(stderr, "Panic: 0001\n");
768 exit(-1);
769 }
770 return szSearch;
771 }
772 }
773 else
774 {
775 iArgSearchReturned = 1;
776 switch (iSearchType)
777 {
778 case SEARCHTYPE_ASCII:
779 strncpy0(szSearch, pcArgSearch, XSIZE);
780 *piLength = strlen(szSearch);
781 break;
782 case SEARCHTYPE_UNICODE:
783 strncpy0(szSearch, pcArgSearch, XSIZE / 2);
784 *piLength = 2 * strlen(szSearch);
785 for (iIter = XSIZE / 2; iIter > 0; iIter--)
786 szSearch[2 * iIter] = szSearch[iIter];
787 for (iIter = 1; iIter <= XSIZE; iIter += 2)
788 szSearch[iIter] = '\0';
789 break;
790 case SEARCHTYPE_HEX:
791 *piLength = Hexstring2Binary(pcArgSearch, szSearch);
792 if (*piLength < 0)
793 {
794 fprintf(stderr, "Error parsing hex string: %s\n", pcArgSearch);
795 exit(-1);
796 }
797 break;
798 case SEARCHTYPE_WILDCARD:
799 break;
800 default:
801 fprintf(stderr, "Panic: 0002\n");
802 exit(-1);
803 }
804 return szSearch;
805 }
806 }
807
BinarySearch(unsigned int * puiArray,unsigned int uiElement,int iMinimum,int iMaximum,unsigned int * puiIndex)808 int BinarySearch(unsigned int *puiArray, unsigned int uiElement, int iMinimum, int iMaximum, unsigned int *puiIndex)
809 {
810 int iMiddle;
811
812 if (iMaximum < iMinimum)
813 {
814 *puiIndex = iMinimum;
815 return 0;
816 }
817 else
818 {
819 iMiddle = iMinimum + ((iMaximum - iMinimum) / 2);
820 if (puiArray[iMiddle] > uiElement)
821 return BinarySearch(puiArray, uiElement, iMinimum, iMiddle - 1, puiIndex);
822 else if (puiArray[iMiddle] < uiElement)
823 return BinarySearch(puiArray, uiElement, iMiddle + 1, iMaximum, puiIndex);
824 else
825 {
826 *puiIndex = iMiddle;
827 return 1;
828 }
829 }
830 }
831
InsertSorted(unsigned int uiElement,unsigned int * puiArray,unsigned int uiArraySize,unsigned int * uiArrayCount)832 void InsertSorted(unsigned int uiElement, unsigned int *puiArray, unsigned int uiArraySize, unsigned int *uiArrayCount)
833 {
834 unsigned int uiIndex;
835 unsigned int uiIter;
836
837 if (*uiArrayCount >= uiArraySize)
838 return;
839 if (*uiArrayCount == 0)
840 {
841 puiArray[(*uiArrayCount)++] = uiElement;
842 return;
843 }
844
845 if (BinarySearch(puiArray, uiElement, 0, *uiArrayCount - 1, &uiIndex))
846 return;
847
848 if (uiIndex == *uiArrayCount)
849 {
850 if (puiArray[*uiArrayCount - 1] != uiElement)
851 puiArray[(*uiArrayCount)++] = uiElement;
852 }
853 else
854 {
855 for (uiIter = *uiArrayCount + 1; uiIndex < uiIter; uiIter--)
856 puiArray[uiIter] = puiArray[uiIter - 1];
857 puiArray[uiIndex] = uiElement;
858 (*uiArrayCount)++;
859 }
860 }
861
SearchForPEFile(unsigned char * pucBuffer,long lSize,char * sOperation,unsigned char ucOffset,unsigned int uiOperand,int iMaxLength)862 int SearchForPEFile(unsigned char *pucBuffer, long lSize, char *sOperation, unsigned char ucOffset, unsigned int uiOperand, int iMaxLength)
863 {
864 int iFound;
865 unsigned char *pucFoundCharM;
866 unsigned char *pucSearchBuffer;
867 unsigned char *pucLastByteInBuffer;
868 unsigned int uiE_lfanew;
869 unsigned char *pucPEHeader;
870 int iIter;
871
872 iFound = 0;
873 pucSearchBuffer = pucBuffer;
874 pucLastByteInBuffer = pucBuffer + lSize - 1;
875 while(1)
876 {
877 pucFoundCharM = memchr(pucSearchBuffer, 'M', lSize - (pucSearchBuffer - pucBuffer));
878 if (pucFoundCharM == NULL)
879 break;
880 if (pucFoundCharM + 0x40 - 1 > pucLastByteInBuffer) // Is the size OK for a IMAGE_DOS_HEADER?
881 break;
882 pucSearchBuffer = pucFoundCharM + 1;
883 if (*(pucFoundCharM + 1) != 'Z')
884 continue;
885 uiE_lfanew = *(unsigned int *)(pucFoundCharM + 0x3C);
886 pucPEHeader = pucFoundCharM + uiE_lfanew;
887 if (pucPEHeader < pucBuffer || pucPEHeader + 0x01 > pucLastByteInBuffer) // Can we check for "PE" without buffer underrun/overrun?
888 continue;
889 if (*(pucPEHeader) != 'P' || *(pucPEHeader + 0x01) != 'E')
890 continue;
891
892 iFound = 1;
893 if (!strcmp(sOperation, OPR_XOR32))
894 printf("Found %s %08X offset +%d position %08lX: %08X ", sOperation, uiOperand, ucOffset, pucFoundCharM - pucBuffer, uiE_lfanew);
895 else if (strcmp(sOperation, OPR_ROT))
896 printf("Found %s %02X position %08lX: %08X ", sOperation, uiOperand, pucFoundCharM - pucBuffer, uiE_lfanew);
897 else
898 printf("Found %s %02d position %08lX: %08X ", sOperation, uiOperand, pucFoundCharM - pucBuffer, uiE_lfanew);
899 for (iIter = 0; iIter < iMaxLength && pucFoundCharM + 0x40 + iIter <= pucLastByteInBuffer; iIter++)
900 {
901 if (isprint(*(pucFoundCharM + 0x40 + iIter)))
902 putchar(*(pucFoundCharM + 0x40 + iIter));
903 else
904 putchar('.');
905 }
906 putchar('\n');
907 }
908
909 return iFound;
910 }
911
AllocAndCopyString(char * szArg,int iLength)912 char *AllocAndCopyString(char *szArg, int iLength)
913 {
914 char *szReturn;
915 szReturn = calloc(iLength + 1, 1);
916
917 if (NULL == szReturn)
918 return NULL;
919 return strncpy0(szReturn, szArg, iLength + 1);
920 }
921
Realloc(void * pvData,size_t sElement,int * piCount,int iIncrement)922 void *Realloc(void* pvData, size_t sElement, int *piCount, int iIncrement)
923 {
924 void *pvResult;
925 size_t sOld;
926 size_t sNew;
927
928 sOld = sElement * *piCount;
929 *piCount += iIncrement;
930 sNew = sElement * *piCount;
931 pvResult = realloc(pvData, sNew);
932 if (NULL == pvResult)
933 return NULL;
934 memset((void *)((unsigned char *)pvResult + sOld), 0, sNew - sOld);
935 return pvResult;
936 }
937
CheckHexDigit(char cDigit)938 int CheckHexDigit(char cDigit)
939 {
940 if (cDigit >= '0' && cDigit <= '9')
941 return cDigit - '0';
942 else if (cDigit >= 'a' && cDigit <= 'f')
943 return cDigit - 'a' + 10;
944 else if (cDigit >= 'A' && cDigit <= 'F')
945 return cDigit - 'A' + 10;
946 else
947 return -1;
948 }
949
ParseBits(char * szBits,WILDCARD * pWildcard)950 int ParseBits(char *szBits, WILDCARD *pWildcard)
951 {
952 int iIter;
953 int iCountVariable = 0;
954
955 pWildcard->ucMode = WILDCARD_MODE_BITS;
956 pWildcard->ucMaskFixed = 0;
957 pWildcard->ucBitsFixed = 0;
958 pWildcard->ucMaskVariable1 = 0;
959 pWildcard->cVariableName1 = 0;
960 pWildcard->ucMaskVariable2 = 0;
961 pWildcard->cVariableName2 = 0;
962
963 for (iIter = 0; iIter < 8; iIter++)
964 {
965 if ('0' == szBits[iIter])
966 {
967 pWildcard->ucMaskFixed |= 1 << (7 - iIter);
968 }
969 else if ('1' == szBits[iIter])
970 {
971 pWildcard->ucMaskFixed |= 1 << (7 - iIter);
972 pWildcard->ucBitsFixed |= (szBits[iIter] - '0') * 1 << (7 - iIter);
973 }
974 else if ('?' == szBits[iIter])
975 {
976 if (1 == iCountVariable)
977 pWildcard->ucMaskVariable1 |= 1 << (7 - iIter);
978 else if (2 == iCountVariable)
979 pWildcard->ucMaskVariable2 |= 1 << (7 - iIter);
980 }
981 else if (szBits[iIter] >= 'A' && szBits[iIter] <= 'Z')
982 {
983 if (0 == iCountVariable)
984 {
985 pWildcard->ucMaskVariable1 |= 1 << (7 - iIter);
986 pWildcard->cVariableName1 = szBits[iIter] - 'A';
987 iCountVariable++;
988 }
989 else if (1 == iCountVariable)
990 {
991 pWildcard->ucMaskVariable2 |= 1 << (7 - iIter);
992 pWildcard->cVariableName2 = szBits[iIter] - 'A';
993 iCountVariable++;
994 }
995 else
996 return -1;
997 }
998 else
999 return -1;
1000 }
1001
1002 return 0;
1003 }
1004
ParseJump(char * szJump,WILDCARD * pWildcard)1005 int ParseJump(char *szJump, WILDCARD *pWildcard)
1006 {
1007 pWildcard->ucMode = WILDCARD_MODE_JUMP;
1008 pWildcard->ucJumpBytes = 0;
1009
1010 if ('1' == szJump[0] || '4' == szJump[0])
1011 {
1012 pWildcard->ucJumpBytes = szJump[0] - '0';
1013 return 0;
1014 }
1015 else
1016 return -1;
1017 }
1018
1019 #define PREFIX_STRE "str="
1020
ParseWildcards(char * szWildcard)1021 WILDCARD *ParseWildcards(char *szWildcard)
1022 {
1023 WILDCARD *pWildcards;
1024 char *pcWildcard;
1025 int iIter;
1026 int iSizeBuffer;
1027
1028 iSizeBuffer = 0x100;
1029 iIter = 0;
1030 pWildcards = calloc(sizeof(WILDCARD), iSizeBuffer);
1031 if (NULL == pWildcards)
1032 return NULL;
1033
1034 pcWildcard = szWildcard;
1035 if (strlen(pcWildcard) > strlen(PREFIX_STRE) && StartsWith(pcWildcard, PREFIX_STRE))
1036 {
1037 pcWildcard += strlen(PREFIX_STRE);
1038 while (strlen(pcWildcard) != 0)
1039 {
1040 pWildcards[iIter].ucMode = WILDCARD_MODE_BYTE;
1041 pWildcards[iIter++].ucByte = pcWildcard[0];
1042 pcWildcard++;
1043 if (iIter == iSizeBuffer)
1044 {
1045 pWildcards = Realloc(pWildcards, sizeof(WILDCARD), &iSizeBuffer, 0x100);
1046 if (NULL == pWildcards)
1047 return NULL;
1048 }
1049 }
1050 }
1051 else
1052 while (strlen(pcWildcard) != 0)
1053 {
1054 if (strlen(pcWildcard) >= 2 && -1 != CheckHexDigit(pcWildcard[0]) && -1 != CheckHexDigit(pcWildcard[1]))
1055 {
1056 pWildcards[iIter].ucMode = WILDCARD_MODE_BYTE;
1057 pWildcards[iIter++].ucByte = CheckHexDigit(pcWildcard[0]) * 0x10 + CheckHexDigit(pcWildcard[1]);
1058 pcWildcard += 2;
1059 }
1060 else if ('(' == *pcWildcard && strlen(pcWildcard) >= 12 && 'B' == pcWildcard[1] && ';' == pcWildcard[2] && ')' == pcWildcard[11])
1061 {
1062 if (0 == iIter)
1063 return 0;
1064 if (-1 == ParseBits(AllocAndCopyString(pcWildcard + 3, 8), &pWildcards[iIter++]))
1065 return NULL;
1066 pcWildcard += 12;
1067 }
1068 else if ('(' == *pcWildcard && strlen(pcWildcard) >= 5 && 'J' == pcWildcard[1] && ';' == pcWildcard[2] && ')' == pcWildcard[4])
1069 {
1070 if (0 == iIter)
1071 return 0;
1072 if (-1 == ParseJump(AllocAndCopyString(pcWildcard + 3, 1), &pWildcards[iIter++]))
1073 return NULL;
1074 pcWildcard += 5;
1075 }
1076 else
1077 return NULL;
1078 if (iIter == iSizeBuffer)
1079 {
1080 pWildcards = Realloc(pWildcards, sizeof(WILDCARD), &iSizeBuffer, 0x100);
1081 if (NULL == pWildcards)
1082 return NULL;
1083 }
1084 }
1085
1086 pWildcards[iIter].ucMode = WILDCARD_MODE_STOP;
1087
1088 pWildcards = realloc(pWildcards, sizeof(WILDCARD) * (iIter + 1));
1089 if (NULL == pWildcards)
1090 return NULL;
1091
1092 return pWildcards;
1093 }
1094
ParseRule(char * pcRule,char ** ppcName,int * piScore,char ** ppcWildcards,WILDCARD ** ppWildcards)1095 unsigned int ParseRule(char *pcRule, char **ppcName, int *piScore, char **ppcWildcards, WILDCARD **ppWildcards)
1096 {
1097 char *pcSeparator1;
1098 char *pcSeparator2;
1099 char *pcSeparator3;
1100 char *szScore;
1101
1102 pcSeparator1 = strchr(pcRule, ':');
1103 if (NULL == pcSeparator1)
1104 return -1;
1105 pcSeparator2 = strchr(pcSeparator1 + 1, ':');
1106 if (NULL == pcSeparator2)
1107 return -1;
1108 pcSeparator3 = strchr(pcSeparator2 + 1, ':');
1109 if (NULL != pcSeparator3)
1110 return -1;
1111
1112 *ppcName = AllocAndCopyString(pcRule, pcSeparator1 - pcRule);
1113 if (NULL == *ppcName)
1114 return -1;
1115 szScore = AllocAndCopyString(pcSeparator1 + 1, pcSeparator2 - pcSeparator1 - 1);
1116 if (NULL == szScore)
1117 return -1;
1118 *piScore = (int) ParseIntegerArg(szScore);
1119 if (-1 == *piScore)
1120 return -1;
1121 *ppcWildcards = AllocAndCopyString(pcSeparator2 + 1, strlen(pcSeparator2 + 1));
1122 if (NULL == *ppcWildcards)
1123 return -1;
1124
1125 *ppWildcards = ParseWildcards(pcSeparator2 + 1);
1126 if (NULL == *ppWildcards)
1127 return -1;
1128
1129 return 0;
1130 }
1131
AddRule(SEARCH ** ppSearch,int * piSize,int * piIndex,char * pcRule)1132 int AddRule(SEARCH **ppSearch, int *piSize, int *piIndex, char *pcRule)
1133 {
1134 char *pcName;
1135 int iScore;
1136 char *pcWildcards;
1137 WILDCARD *pWildcards;
1138
1139 if (0 == *piSize)
1140 {
1141 *piSize = 10;
1142 *ppSearch = calloc(sizeof(SEARCH), *piSize);
1143 if (NULL == *ppSearch)
1144 return -1;
1145 }
1146
1147 if (*piIndex >= *piSize - 1)
1148 {
1149 *ppSearch = Realloc(*ppSearch, sizeof(SEARCH), piSize, 10);
1150 if (NULL == *ppSearch)
1151 return -1;
1152 }
1153
1154 if (ParseRule(pcRule, &pcName, &iScore, &pcWildcards, &pWildcards))
1155 return -1;
1156
1157 (*ppSearch)[*piIndex].iSearchType = SEARCHTYPE_WILDCARD;
1158 (*ppSearch)[*piIndex].pcWildcardName = pcName;
1159 (*ppSearch)[*piIndex].iScore = iScore;
1160 (*ppSearch)[*piIndex].iPrintASCII = StartsWith(pcWildcards, PREFIX_STRE);
1161 (*ppSearch)[(*piIndex)++].pWildcards = pWildcards;
1162
1163 (*ppSearch)[*piIndex].iSearchType = SEARCHTYPE_STOP;
1164
1165 return 0;
1166 }
1167
InitializeSearch(char * pcRule,char * szFile,int iFlagEmbedded)1168 SEARCH *InitializeSearch(char *pcRule, char *szFile, int iFlagEmbedded)
1169 {
1170 SEARCH *pSearch;
1171 int iSize;
1172 int iIndex;
1173 int iIter;
1174 FILE *fRules;
1175 char szLine[1024];
1176 char *aszEmbeddedRules[] =
1177 {
1178 "Function prolog signature:10:558bec83c4",
1179 "Function prolog signature:10:558bec81ec",
1180 "Function prolog signature:10:558beceb",
1181 "Function prolog signature:10:558bece8",
1182 "Function prolog signature:10:558bece9",
1183 "Indirect function call tris:10:FFB7(B;????????)(B;????????)(B;????????)(B;????????)FF57(B;????????)",
1184 "GetEIP method 4 FLDZ/FSTENV [esp-12]:10:D9EED97424F4(B;01011???)",
1185 "GetEIP method 1:10:E800000000(B;01011???)",
1186 "GetEIP method 2:10:EB(J;1)E8(J;4)(B;01011???)",
1187 "GetEIP method 3:10:E9(J;4)E8(J;4)(B;01011???)",
1188 "GetEIP method 4:10:D9EE9BD97424F4(B;01011???)",
1189 "Find kernel32 base method 1:10:648B(B;00???101)30000000",
1190 "Find kernel32 base method 1bis:10:64A130000000",
1191 "Find kernel32 base method 2:10:31(B;11A??A??)(B;10100A??)30648B(B;00B??A??)",
1192 "Find kernel32 base method 3:10:6830000000(B;01011A??)648B(B;00B??A??)",
1193 "Structured exception handling :10:648B(B;00???101)00000000",
1194 "Structured exception handling bis:10:64A100000000",
1195 "API Hashing:10:AC84C07407C1CF0D01C7EBF481FF",
1196 "API Hashing bis:10:AC84C07407C1CF0701C7EBF481FF",
1197 // "API-Hashing signature:10:74(B;????????)c1(B;????????)0d(B;????????)(B;????????)(B;????????)(B;????????), // too many false positives
1198 // "API-Hashing signature:10:74(B;????????)c1(B;????????)07(B;????????)(B;????????)(B;????????)(B;????????), // too many false positives
1199 // "API-Hashing signature:10:74(B;????????)c1(B;????????)0b03(B;????????)(B;????????)(B;????????)(B;????????), // too many false positives
1200 "Indirect function call:10:FF75(B;A???????)FF55(B;A???????)",
1201 "Indirect function call bis:10:FFB5(B;A???????)(B;B???????)(B;C???????)(B;D???????)FF95(B;A???????)(B;B???????)(B;C???????)(B;D???????)",
1202 "OLE file magic number:10:D0CF11E0",
1203 "Suspicious strings:2:str=UrlDownloadToFile",
1204 "Suspicious strings:2:str=GetTempPath",
1205 "Suspicious strings:2:str=GetWindowsDirectory",
1206 "Suspicious strings:2:str=GetSystemDirectory",
1207 "Suspicious strings:2:str=WinExec",
1208 "Suspicious strings:2:str=ShellExecute",
1209 "Suspicious strings:2:str=IsBadReadPtr",
1210 "Suspicious strings:2:str=IsBadWritePtr",
1211 "Suspicious strings:2:str=CreateFile",
1212 "Suspicious strings:2:str=CloseHandle",
1213 "Suspicious strings:2:str=ReadFile",
1214 "Suspicious strings:2:str=WriteFile",
1215 "Suspicious strings:2:str=SetFilePointer",
1216 "Suspicious strings:2:str=VirtualAlloc",
1217 "Suspicious strings:2:str=GetProcAddr",
1218 "Suspicious strings:2:str=LoadLibrary",
1219 };
1220
1221 pSearch = NULL;
1222 iSize = 0;
1223 iIndex = 0;
1224
1225 if (iFlagEmbedded)
1226 {
1227 for (iIter = 0; iIter < countof(aszEmbeddedRules); iIter++)
1228 if (AddRule(&pSearch, &iSize, &iIndex, aszEmbeddedRules[iIter]) != 0)
1229 return NULL;
1230 }
1231 else if (NULL != szFile)
1232 {
1233 if ((fRules = fopen(szFile, "r")) == NULL)
1234 {
1235 fprintf(stderr, "error opening file %s\n", szFile);
1236 exit(-1);
1237 }
1238 while (fgets(szLine, sizeof(szLine), fRules) != NULL)
1239 {
1240 if (strlen(szLine) > 0 && szLine[strlen(szLine) - 1] == '\n')
1241 szLine[strlen(szLine) - 1] = '\0';
1242 if (strlen(szLine) > 0 && szLine[0] != '#')
1243 if (AddRule(&pSearch, &iSize, &iIndex, szLine) != 0)
1244 {
1245 fclose(fRules);
1246 return NULL;
1247 }
1248 }
1249 fclose(fRules);
1250 }
1251 else
1252 {
1253 if (AddRule(&pSearch, &iSize, &iIndex, pcRule) != 0)
1254 return NULL;
1255 }
1256
1257 return pSearch;
1258 }
1259
List(SEARCH * pSearch)1260 void List(SEARCH *pSearch)
1261 {
1262 int iIter1;
1263 int iIter2;
1264 int iIter3;
1265 int iVariable1WasPrinted;
1266 int iVariable2WasPrinted;
1267
1268 for (iIter1 = 0; pSearch[iIter1].iSearchType != SEARCHTYPE_STOP; iIter1++)
1269 {
1270 printf("%s:%d:", pSearch[iIter1].pcWildcardName, pSearch[iIter1].iScore);
1271 if (1 == pSearch[iIter1].iPrintASCII)
1272 {
1273 printf("str=");
1274 for (iIter2 = 0; pSearch[iIter1].pWildcards[iIter2].ucMode != WILDCARD_MODE_STOP; iIter2++)
1275 printf("%c", pSearch[iIter1].pWildcards[iIter2].ucByte);
1276 }
1277 else
1278 {
1279 for (iIter2 = 0; pSearch[iIter1].pWildcards[iIter2].ucMode != WILDCARD_MODE_STOP; iIter2++)
1280 switch (pSearch[iIter1].pWildcards[iIter2].ucMode)
1281 {
1282 case WILDCARD_MODE_BYTE:
1283 printf("%02X", pSearch[iIter1].pWildcards[iIter2].ucByte);
1284 break;
1285 case WILDCARD_MODE_BITS:
1286 iVariable1WasPrinted = 0;
1287 iVariable2WasPrinted = 0;
1288 printf("(B;");
1289 for (iIter3 = 7; iIter3 >= 0; iIter3--)
1290 if ((pSearch[iIter1].pWildcards[iIter2].ucMaskFixed >> iIter3) & 0x01)
1291 printf("%d", (pSearch[iIter1].pWildcards[iIter2].ucBitsFixed >> iIter3) & 0x01);
1292 else if ((pSearch[iIter1].pWildcards[iIter2].ucMaskVariable1 >> iIter3) & 0x01)
1293 {
1294 if (0 == iVariable1WasPrinted)
1295 {
1296 printf("%c", pSearch[iIter1].pWildcards[iIter2].cVariableName1 + 'A');
1297 iVariable1WasPrinted = 1;
1298 }
1299 else
1300 printf("?");
1301 }
1302 else if ((pSearch[iIter1].pWildcards[iIter2].ucMaskVariable2 >> iIter3) & 0x01)
1303 {
1304 if (0 == iVariable2WasPrinted)
1305 {
1306 printf("%c", pSearch[iIter1].pWildcards[iIter2].cVariableName2 + 'A');
1307 iVariable2WasPrinted = 1;
1308 }
1309 else
1310 printf("?");
1311 }
1312 else
1313 printf("?");
1314 printf(")");
1315 break;
1316 case WILDCARD_MODE_JUMP:
1317 printf("(J;%d)", pSearch[iIter1].pWildcards[iIter2].ucJumpBytes);
1318 break;
1319 }
1320 }
1321 printf("\n");
1322 }
1323 }
1324
ReadFile(char * pcArgFile,off_t * potFileSize,void ** ppBuffer)1325 int ReadFile(char *pcArgFile, off_t *potFileSize, void **ppBuffer)
1326 {
1327 struct stat statFile;
1328 FILE *fIn;
1329
1330 if (stat(pcArgFile, &statFile) != 0)
1331 {
1332 fprintf(stderr, "error opening file %s\n", pcArgFile);
1333 return -1;
1334 }
1335
1336 *potFileSize = statFile.st_size;
1337 if (*potFileSize == 0)
1338 {
1339 fprintf(stderr, "file %s is empty\n", pcArgFile);
1340 return -1;
1341 }
1342 if ((*ppBuffer = malloc(*potFileSize)) == NULL)
1343 {
1344 fprintf(stderr, "file %s is too large %lld\n", pcArgFile, *potFileSize);
1345 return -1;
1346 }
1347
1348 if ((fIn = fopen(pcArgFile, "rb")) == NULL)
1349 {
1350 fprintf(stderr, "error opening file %s\n", pcArgFile);
1351 free(*ppBuffer);
1352 return -1;
1353 }
1354 if (fread(*ppBuffer, *potFileSize, 1, fIn) != 1)
1355 {
1356 fprintf(stderr, "error reading file %s\n", pcArgFile);
1357 fclose(fIn);
1358 free(*ppBuffer);
1359 return -1;
1360 }
1361 fclose(fIn);
1362
1363 return 0;
1364 }
1365
IsWhitespace(char cHexDigit)1366 int IsWhitespace(char cHexDigit)
1367 {
1368 return (cHexDigit >= 0x09 && cHexDigit <= 0x0D) || (cHexDigit == 0x20);
1369 }
1370
ReadHexFile(char * pcArgFile,off_t * potFileSize,void ** ppBuffer)1371 int ReadHexFile(char *pcArgFile, off_t *potFileSize, void **ppBuffer)
1372 {
1373 FILE *fIn;
1374 int iChar;
1375 int iFirstNibble;
1376 int iCountCharacters;
1377 off_t otBufferSize;
1378 void *pBuffer;
1379
1380 otBufferSize = 1024*1024;
1381 if ((*ppBuffer = malloc(otBufferSize)) == NULL)
1382 {
1383 fprintf(stderr, "file %s is too large\n", pcArgFile);
1384 return -1;
1385 }
1386
1387 if ((fIn = fopen(pcArgFile, "r")) == NULL)
1388 {
1389 fprintf(stderr, "error opening file %s\n", pcArgFile);
1390 free(*ppBuffer);
1391 return -1;
1392 }
1393
1394 iFirstNibble = -1;
1395 *potFileSize = 0;
1396 iCountCharacters = 0;
1397 do
1398 {
1399 if (EOF != (iChar = fgetc(fIn)) && !IsWhitespace(iChar))
1400 {
1401 iCountCharacters++;
1402 if (IsHexDigit(iChar))
1403 {
1404 if (-1 == iFirstNibble)
1405 iFirstNibble = HexDigitToNibble(iChar);
1406 else
1407 {
1408 if (*potFileSize < otBufferSize)
1409 {
1410 *((char *)(*ppBuffer) + *potFileSize) = iFirstNibble * 0x10 + HexDigitToNibble(iChar);
1411 (*potFileSize)++;
1412 iFirstNibble = -1;
1413 }
1414 else
1415 {
1416 otBufferSize = otBufferSize + 1024*1024;
1417 pBuffer = realloc(*ppBuffer, otBufferSize);
1418 if (NULL == pBuffer)
1419 {
1420 fprintf(stderr, "file %s is too large\n", pcArgFile);
1421 free(*ppBuffer);
1422 fclose(fIn);
1423 return -1;
1424 }
1425 *ppBuffer = pBuffer;
1426 *((char *)(*ppBuffer) + *potFileSize) = iFirstNibble * 0x10 + HexDigitToNibble(iChar);
1427 (*potFileSize)++;
1428 iFirstNibble = -1;
1429 }
1430 }
1431 }
1432 else
1433 {
1434 fprintf(stderr, "file %s contains unexpected character at 0x%X (not hex digit and not whitespace): 0x%02X\n", pcArgFile, iCountCharacters, iChar);
1435 free(*ppBuffer);
1436 fclose(fIn);
1437 return -1;
1438 }
1439 }
1440 } while (EOF != iChar);
1441 fclose(fIn);
1442
1443 if (-1 != iFirstNibble)
1444 {
1445 fprintf(stderr, "file %s contains uneven number of hex digits\n", pcArgFile);
1446 free(*ppBuffer);
1447 return -1;
1448 }
1449
1450 if (*potFileSize == 0)
1451 {
1452 fprintf(stderr, "file %s is empty\n", pcArgFile);
1453 free(*ppBuffer);
1454 return -1;
1455 }
1456
1457 return 0;
1458 }
1459
main(int argc,char ** argv)1460 int main(int argc, char **argv)
1461 {
1462 struct stat statFile;
1463 void *pBuffer;
1464 void *pBufferCopy;
1465 unsigned char ucOPRIter;
1466 char *pcArgFile;
1467 char *pcArgSearch;
1468 char *pcArgSearchFile;
1469 char *pcSearch;
1470 char *pcDisable;
1471 int iFlagSave;
1472 int iFlagIgnoreCase;
1473 int iMaxLength;
1474 int iCountFinds;
1475 int iFound;
1476 int iFlagUnicode;
1477 int iSearchLength;
1478 int iNeighbourgLength;
1479 int iFlagHex;
1480 int iFlagKeys;
1481 int iFlagPEFile;
1482 int iSearchType;
1483 int iExcludeByte;
1484 int iFlagWildcard;
1485 int iFlagWildcardEmbedded;
1486 int iFlagList;
1487 int iFlagHexFile;
1488 unsigned int *pui32bitKeys;
1489 unsigned int uiSize32bitKeys;
1490 unsigned int uiCount32bitKeys;
1491 unsigned int uiIter32bitKeys;
1492 int iIterBuffer;
1493 int iScore;
1494 union
1495 {
1496 unsigned int uiKey;
1497 unsigned char ucKey[4];
1498 } uk1, uk2;
1499 SEARCH *pSearch;
1500 int iFoundSomething;
1501 off_t otFileSize;
1502 int iResult;
1503
1504 if (ParseArgs(argc, argv, &iFlagSave, &iMaxLength, &iFlagIgnoreCase, &pcArgFile, &pcArgSearch, &pcArgSearchFile, &iFlagUnicode, &iNeighbourgLength, &iFlagHex, &iFlagKeys, &iFlagPEFile, &iExcludeByte, &iFlagWildcard, &iFlagWildcardEmbedded, &pcDisable, &iFlagList, &iFlagHexFile))
1505 {
1506 fprintf(stderr, "Usage: XORSearch [-siuhkpwWLx] [-l length] [-n length] [-f search-file] [-e byte] [-d encodings] file string|hex|rule\n"
1507 "XORSearch V1.11.1, search for a XOR, ROL, ROT, SHIFT or ADD encoded string in a file\n"
1508 "Use -x when the file to search is a hexdump\n"
1509 "Use -s to save the XOR, ROL, ROT, SHIFT or ADD encoded file containing the string\n"
1510 "Use -l length to limit the number of printed characters (50 by default, 38 with option -p)\n"
1511 "Use -i to ignore the case when searching\n"
1512 "Use -u to search for Unicode strings (limited support)\n"
1513 "Use -f to provide a file with search strings\n"
1514 "Use -n length to print the length neighbouring charaters (before & after the found keyword)\n"
1515 "Use -h to search for hex strings\n"
1516 "Use -k to decode with embedded keys\n"
1517 "Use -p to search for PE-files\n"
1518 "Use -w to search with wildcards\n"
1519 "Use -W to search with embedded wildcards\n"
1520 "Use -L to list embedded wildcards\n"
1521 "Use -e to exclude a particular byte-value from encoding\n"
1522 "Use -d to disable encoding(s) 1: XOR 2: ROL 3: ROT 4: SHIFT 5: ADD\n"
1523 "Options -l and -n are mutually exclusive\n"
1524 "Options -u and -h are mutually exclusive\n"
1525 "Options -k and -e are mutually exclusive\n"
1526 "Option -p is not compatible with options -i, -u, -h and -n\n"
1527 "When using -p, do not provide a search string or use -f\n"
1528 "When using -W, do not provide a search string or use -f\n"
1529 "Use option -L without arguments or other options\n"
1530 "Source code put in the public domain by Didier Stevens, no Copyright\n"
1531 "Use at your own risk\n"
1532 "https://DidierStevens.com\n");
1533 return -1;
1534 }
1535 if (iMaxLength == -1)
1536 {
1537 if (iFlagPEFile)
1538 iMaxLength = 38;
1539 else
1540 iMaxLength = 50;
1541 }
1542
1543 if (iFlagList)
1544 {
1545 pSearch = InitializeSearch(NULL, NULL, 1);
1546 if (NULL == pSearch)
1547 {
1548 fprintf(stderr, "Error: parsing rule\n");
1549 return -1;
1550 }
1551
1552 List(pSearch);
1553
1554 return 0;
1555 }
1556
1557 if (iFlagUnicode)
1558 iSearchType = SEARCHTYPE_UNICODE;
1559 else if (iFlagHex)
1560 iSearchType = SEARCHTYPE_HEX;
1561 else if (iFlagWildcard || iFlagWildcardEmbedded)
1562 iSearchType = SEARCHTYPE_WILDCARD;
1563 else
1564 iSearchType = SEARCHTYPE_ASCII;
1565
1566 if (iFlagWildcard || iFlagWildcardEmbedded)
1567 {
1568 pSearch = InitializeSearch(pcArgSearch, pcArgSearchFile, iFlagWildcardEmbedded);
1569 if (NULL == pSearch)
1570 {
1571 fprintf(stderr, "Error: parsing rule\n");
1572 return -1;
1573 }
1574 }
1575
1576 if (strlen(pcArgFile) >= XSIZE-1)
1577 {
1578 fprintf(stderr, "Error: filename is too long\n");
1579 return -1;
1580 }
1581
1582 if (pcArgSearchFile != NULL)
1583 {
1584 if (stat(pcArgSearchFile, &statFile) != 0)
1585 {
1586 fprintf(stderr, "error opening file %s\n", pcArgSearchFile);
1587 return -1;
1588 }
1589 }
1590 else if (pcArgSearch != NULL && strlen(pcArgSearch) >= XSIZE-2)
1591 {
1592 fprintf(stderr, "Error: search string is too long\n");
1593 return -1;
1594 }
1595
1596 if (iFlagHexFile)
1597 iResult = ReadHexFile(pcArgFile, &otFileSize, &pBuffer);
1598 else
1599 iResult = ReadFile(pcArgFile, &otFileSize, &pBuffer);
1600 if (0 != iResult)
1601 return iResult;
1602
1603 if ((pBufferCopy = malloc(otFileSize)) == NULL)
1604 {
1605 fprintf(stderr, "file %s is too large %lld\n", pcArgFile, otFileSize);
1606 free(pBuffer);
1607 return -1;
1608 }
1609 memcpy(pBufferCopy, pBuffer, otFileSize);
1610
1611 if (iFlagKeys && otFileSize < 4)
1612 {
1613 fprintf(stderr, "file %s is too small for option -k\n", pcArgFile);
1614 free(pBuffer);
1615 free(pBufferCopy);
1616 return -1;
1617 }
1618
1619 pui32bitKeys = NULL;
1620 uiSize32bitKeys = (otFileSize - 3) * 2;
1621 if (iFlagKeys)
1622 if ((pui32bitKeys = malloc(uiSize32bitKeys * sizeof(unsigned int))) == NULL)
1623 {
1624 fprintf(stderr, "file %s is too large for copy %lld\n", pcArgFile, otFileSize);
1625 uiSize32bitKeys = 0;
1626 }
1627
1628 if (NULL != pui32bitKeys)
1629 {
1630 uiCount32bitKeys = 0;
1631 for (iIterBuffer = 0; iIterBuffer < otFileSize - 3; iIterBuffer++)
1632 {
1633 uk1.uiKey = *(unsigned int *)((unsigned char *)pBuffer + iIterBuffer);
1634 if (!(uk1.ucKey[0] == uk1.ucKey[1] && uk1.ucKey[0] == uk1.ucKey[2] && uk1.ucKey[0] == uk1.ucKey[3]))
1635 {
1636 InsertSorted(uk1.uiKey, pui32bitKeys, uiSize32bitKeys, &uiCount32bitKeys);
1637 uk2.ucKey[3] = uk1.ucKey[0];
1638 uk2.ucKey[2] = uk1.ucKey[1];
1639 uk2.ucKey[1] = uk1.ucKey[2];
1640 uk2.ucKey[0] = uk1.ucKey[3];
1641 InsertSorted(uk2.uiKey, pui32bitKeys, uiSize32bitKeys, &uiCount32bitKeys);
1642 }
1643 }
1644 }
1645
1646 if ((piFoundIndex = (int *)malloc(otFileSize * sizeof(int))) == NULL)
1647 {
1648 fprintf(stderr, "file %s is too large %lld\n", pcArgFile, otFileSize);
1649 free(pBuffer);
1650 free(pBufferCopy);
1651 return -1;
1652 }
1653
1654 if ((piFoundSize = (int *)malloc(otFileSize * sizeof(int))) == NULL)
1655 {
1656 fprintf(stderr, "file %s is too large %lld\n", pcArgFile, otFileSize);
1657 free(pBuffer);
1658 free(pBufferCopy);
1659 free(piFoundIndex);
1660 return -1;
1661 }
1662
1663 iFoundSomething = 0;
1664 iScore = 0;
1665 if (iFlagKeys)
1666 {
1667 printf("Testing %d keys\n", uiCount32bitKeys);
1668 for (uiIter32bitKeys = 0; uiIter32bitKeys < uiCount32bitKeys; uiIter32bitKeys++)
1669 {
1670 for (ucOPRIter = 0; ucOPRIter < 4; ucOPRIter++)
1671 {
1672 XOR32(pBuffer, otFileSize, ucOPRIter, pui32bitKeys[uiIter32bitKeys]);
1673
1674 iFound = 0;
1675 if (iFlagPEFile)
1676 iFound = SearchForPEFile((unsigned char *)pBuffer, otFileSize, OPR_XOR32, ucOPRIter, pui32bitKeys[uiIter32bitKeys], iMaxLength);
1677 else if (iSearchType == SEARCHTYPE_WILDCARD)
1678 iFound = WildcardSearches(pSearch, pBuffer, otFileSize, OPR_XOR32, 0, ucOPRIter, iMaxLength, &iScore);
1679 else
1680 do
1681 {
1682 pcSearch = GetSearchString(pcArgSearch, pcArgSearchFile, iSearchType, &iSearchLength);
1683 if (pcSearch && iSearchLength > 0)
1684 {
1685 iCountFinds = KMP(pcSearch, iSearchLength, pBuffer, otFileSize, iFlagIgnoreCase);
1686 if (iCountFinds > 0)
1687 {
1688 PrintFinds(iCountFinds, iMaxLength, OPR_XOR32, ucOPRIter, pui32bitKeys[uiIter32bitKeys], otFileSize, pBuffer, iSearchType, iNeighbourgLength);
1689 iFound = 1;
1690 }
1691 }
1692 } while (pcSearch);
1693
1694 if (iFound && iFlagSave)
1695 SaveFile(pcArgFile, OPR_XOR32, pui32bitKeys[uiIter32bitKeys], pBuffer, otFileSize);
1696
1697 iFoundSomething |= iFound;
1698
1699 memcpy(pBuffer, pBufferCopy, otFileSize);
1700 }
1701 }
1702 }
1703 else
1704 {
1705 ucOPRIter = 0;
1706
1707 if (NULL == pcDisable || !strchr(pcDisable, '1'))
1708 {
1709 do
1710 {
1711 XOR((unsigned char *) pBuffer, otFileSize, ucOPRIter, iExcludeByte);
1712
1713 iFound = 0;
1714 if (iFlagPEFile)
1715 iFound = SearchForPEFile((unsigned char *)pBuffer, otFileSize, OPR_XOR, 0, ucOPRIter, iMaxLength);
1716 else if (iSearchType == SEARCHTYPE_WILDCARD)
1717 iFound = WildcardSearches(pSearch, pBuffer, otFileSize, OPR_XOR, 0, ucOPRIter, iMaxLength, &iScore);
1718 else
1719 do
1720 {
1721 pcSearch = GetSearchString(pcArgSearch, pcArgSearchFile, iSearchType, &iSearchLength);
1722 if (pcSearch && iSearchLength > 0)
1723 {
1724 iCountFinds = KMP(pcSearch, iSearchLength, pBuffer, otFileSize, iFlagIgnoreCase);
1725 if (iCountFinds > 0)
1726 {
1727 PrintFinds(iCountFinds, iMaxLength, OPR_XOR, 0, ucOPRIter, otFileSize, pBuffer, iSearchType, iNeighbourgLength);
1728 iFound = 1;
1729 }
1730 }
1731 } while (pcSearch);
1732
1733 if (iFound && iFlagSave)
1734 SaveFile(pcArgFile, OPR_XOR, ucOPRIter, pBuffer, otFileSize);
1735
1736 iFoundSomething |= iFound;
1737
1738 memcpy(pBuffer, pBufferCopy, otFileSize);
1739 } while (++ucOPRIter);
1740 }
1741
1742 if (NULL == pcDisable || !strchr(pcDisable, '2'))
1743 {
1744 for (ucOPRIter = 1; ucOPRIter < 8; ucOPRIter++)
1745 {
1746 ROL((unsigned char *) pBuffer, otFileSize, iExcludeByte);
1747
1748 iFound = 0;
1749 if (iFlagPEFile)
1750 iFound = SearchForPEFile((unsigned char *)pBuffer, otFileSize, OPR_ROL, 0, ucOPRIter, iMaxLength);
1751 else if (iSearchType == SEARCHTYPE_WILDCARD)
1752 iFound = WildcardSearches(pSearch, pBuffer, otFileSize, OPR_ROL, 0, ucOPRIter, iMaxLength, &iScore);
1753 else
1754 do
1755 {
1756 pcSearch = GetSearchString(pcArgSearch, pcArgSearchFile, iSearchType, &iSearchLength);
1757 if (pcSearch && iSearchLength > 0)
1758 {
1759 iCountFinds = KMP(pcSearch, iSearchLength, pBuffer, otFileSize, iFlagIgnoreCase);
1760 if (iCountFinds > 0)
1761 {
1762 PrintFinds(iCountFinds, iMaxLength, OPR_ROL, 0, ucOPRIter, otFileSize, pBuffer, iSearchType, iNeighbourgLength);
1763 iFound = 1;
1764 }
1765 }
1766 } while (pcSearch);
1767
1768 if (iFound && iFlagSave)
1769 SaveFile(pcArgFile, OPR_ROL, ucOPRIter, pBuffer, otFileSize);
1770
1771 iFoundSomething |= iFound;
1772 }
1773 memcpy(pBuffer, pBufferCopy, otFileSize);
1774 }
1775
1776 if (NULL == pcDisable || !strchr(pcDisable, '3'))
1777 {
1778 for (ucOPRIter = 25; ucOPRIter >= 1; ucOPRIter--)
1779 {
1780 ROT((unsigned char *) pBuffer, otFileSize, iExcludeByte);
1781
1782 iFound = 0;
1783 if (iFlagPEFile)
1784 iFound = SearchForPEFile((unsigned char *)pBuffer, otFileSize, OPR_ROT, 0, ucOPRIter, iMaxLength);
1785 else if (iSearchType == SEARCHTYPE_WILDCARD)
1786 iFound = WildcardSearches(pSearch, pBuffer, otFileSize, OPR_ROT, 0, ucOPRIter, iMaxLength, &iScore);
1787 else
1788 do
1789 {
1790 pcSearch = GetSearchString(pcArgSearch, pcArgSearchFile, iSearchType, &iSearchLength);
1791 if (pcSearch && iSearchLength > 0)
1792 {
1793 iCountFinds = KMP(pcSearch, iSearchLength, pBuffer, otFileSize, iFlagIgnoreCase);
1794 if (iCountFinds > 0)
1795 {
1796 PrintFinds(iCountFinds, iMaxLength, OPR_ROT, 0, ucOPRIter, otFileSize, pBuffer, iSearchType, iNeighbourgLength);
1797 iFound = 1;
1798 }
1799 }
1800 } while (pcSearch);
1801
1802 if (iFound && iFlagSave)
1803 SaveFile(pcArgFile, OPR_ROT, ucOPRIter, pBuffer, otFileSize);
1804
1805 iFoundSomething |= iFound;
1806 }
1807 memcpy(pBuffer, pBufferCopy, otFileSize);
1808 }
1809
1810 if (NULL == pcDisable || !strchr(pcDisable, '4'))
1811 {
1812 for (ucOPRIter = 1; ucOPRIter < 8; ucOPRIter++)
1813 {
1814 SHIFT((unsigned char *) pBuffer, otFileSize, iExcludeByte);
1815
1816 iFound = 0;
1817 if (iFlagPEFile)
1818 iFound = SearchForPEFile((unsigned char *)pBuffer, otFileSize, OPR_SHIFT, 0, ucOPRIter, iMaxLength);
1819 else if (iSearchType == SEARCHTYPE_WILDCARD)
1820 iFound = WildcardSearches(pSearch, pBuffer, otFileSize, OPR_SHIFT, 0, ucOPRIter, iMaxLength, &iScore);
1821 else
1822 do
1823 {
1824 pcSearch = GetSearchString(pcArgSearch, pcArgSearchFile, iSearchType, &iSearchLength);
1825 if (pcSearch && iSearchLength > 0)
1826 {
1827 iCountFinds = KMP(pcSearch, iSearchLength, pBuffer, otFileSize, iFlagIgnoreCase);
1828 if (iCountFinds > 0)
1829 {
1830 PrintFinds(iCountFinds, iMaxLength, OPR_SHIFT, 0, ucOPRIter, otFileSize, pBuffer, iSearchType, iNeighbourgLength);
1831 iFound = 1;
1832 }
1833 }
1834 } while (pcSearch);
1835
1836 if (iFound && iFlagSave)
1837 SaveFile(pcArgFile, OPR_SHIFT, ucOPRIter, pBuffer, otFileSize);
1838
1839 iFoundSomething |= iFound;
1840 }
1841 memcpy(pBuffer, pBufferCopy, otFileSize);
1842 }
1843
1844 if (NULL == pcDisable || !strchr(pcDisable, '5'))
1845 {
1846 do
1847 {
1848 ADD((unsigned char *) pBuffer, otFileSize, iExcludeByte);
1849
1850 iFound = 0;
1851 if (iFlagPEFile)
1852 iFound = SearchForPEFile((unsigned char *)pBuffer, otFileSize, OPR_ADD, 0, ucOPRIter, iMaxLength);
1853 else if (iSearchType == SEARCHTYPE_WILDCARD)
1854 iFound = WildcardSearches(pSearch, pBuffer, otFileSize, OPR_ADD, 0, ucOPRIter, iMaxLength, &iScore);
1855 else
1856 do
1857 {
1858 pcSearch = GetSearchString(pcArgSearch, pcArgSearchFile, iSearchType, &iSearchLength);
1859 if (pcSearch && iSearchLength > 0)
1860 {
1861 iCountFinds = KMP(pcSearch, iSearchLength, pBuffer, otFileSize, iFlagIgnoreCase);
1862 if (iCountFinds > 0)
1863 {
1864 PrintFinds(iCountFinds, iMaxLength, OPR_ADD, 0, ucOPRIter, otFileSize, pBuffer, iSearchType, iNeighbourgLength);
1865 iFound = 1;
1866 }
1867 }
1868 } while (pcSearch);
1869
1870 if (iFound && iFlagSave)
1871 SaveFile(pcArgFile, OPR_ADD, ucOPRIter, pBuffer, otFileSize);
1872
1873 iFoundSomething |= iFound;
1874 } while (++ucOPRIter);
1875 }
1876 }
1877
1878 free(pBuffer);
1879 free(pBufferCopy);
1880 free(piFoundIndex);
1881 free(piFoundSize);
1882
1883 if (iSearchType == SEARCHTYPE_WILDCARD)
1884 {
1885 printf("Score: %d\n", iScore);
1886 return iScore;
1887 }
1888 else
1889 return iFoundSomething ? 0 : 1;
1890 }
1891