source: trunk/CrypPlugins/KeySearcher/KeySearcher.cs @ 865

Last change on this file since 865 was 865, checked in by Sven Rech, 12 years ago

some big optimizations to the keypattern mechanism of the keysearcher.
The keysearcher itself should have zero performace overhead now.
But bruteforcing AES and DES is still very slow.
By profiling, we found out that the Microsoft Crypto implementations are to blame, because they aren't optimized for speed.
So the next step would be to replace those implementations....

File size: 37.4 KB
Line 
1using System;
2using System.Linq;
3using System.Text;
4using Cryptool.PluginBase.Analysis;
5using Cryptool.PluginBase;
6using System.Windows.Controls;
7using System.ComponentModel;
8using Cryptool.PluginBase.Control;
9using System.Collections;
10using System.Collections.Generic;
11using System.Threading;
12using System.Windows.Threading;
13
14namespace KeySearcher
15{
16    public class KeyPattern
17    {
18        private class Wildcard
19        {
20            private char[] values = new char[256];
21            private int length;
22            private int counter;
23            public bool isSplit
24            {
25                get;
26                private set;
27            }
28           
29            public Wildcard(string valuePattern)
30            {
31                isSplit = false;
32                counter = 0;
33                length = 0;
34                int i = 1;
35                while (valuePattern[i] != ']')
36                {
37                    if (valuePattern[i + 1] == '-')
38                    {
39                        for (char c = valuePattern[i]; c <= valuePattern[i + 2]; c++)
40                            values[length++] = c;
41                        i += 2;
42                    }
43                    else
44                        values[length++] = valuePattern[i];
45                    i++;
46                }
47            }
48
49            public Wildcard(Wildcard wc)
50            {
51                isSplit = wc.isSplit;
52                length = wc.length;
53                counter = wc.counter;
54                for (int i = 0; i < 256; i++)
55                    values[i] = wc.values[i];
56            }
57
58            private Wildcard()
59            {
60            }
61
62            public Wildcard[] split()
63            {
64                int length = this.length - this.counter;
65                Wildcard[] wcs = new Wildcard[2];
66                wcs[0] = new Wildcard();
67                wcs[0].counter = 0;
68                wcs[0].length = length / 2;
69                wcs[1] = new Wildcard();
70                wcs[1].counter = 0;
71                wcs[1].length = length - wcs[0].length;
72                for (int i = 0; i < wcs[0].length; i++)
73                    wcs[0].values[i] = values[this.counter + i];
74                for (int i = 0; i < wcs[1].length; i++)
75                    wcs[1].values[i] = values[i + this.counter + wcs[0].length];
76                wcs[0].isSplit = true;
77                wcs[1].isSplit = true;
78                return wcs;
79            }
80
81            public char getChar()
82            {
83                return values[counter];
84            }
85
86            public char getChar(int add)
87            {
88                return values[(counter+add)%length];
89            }
90
91            public bool succ()
92            {
93                counter++;
94                if (counter >= length)
95                {
96                    counter = 0;
97                    return true;
98                }
99                return false;
100            }
101
102            public int size()
103            {
104                return length;
105            }
106
107
108            public int count()
109            {
110                return counter;
111            }
112
113            public void resetCounter()
114            {
115                counter = 0;
116            }
117        }
118
119        private string pattern;
120        private string key;       
121        private ArrayList wildcardList;
122
123        public KeyPattern(string pattern)
124        {
125            this.pattern = pattern;
126        }
127
128        public KeyPattern[] split()
129        {
130            KeyPattern[] patterns = new KeyPattern[2];
131            for (int i = 0; i < 2; i++)
132            {
133                patterns[i] = new KeyPattern(pattern);
134                patterns[i].key = key;
135                patterns[i].wildcardList = new ArrayList();
136            }
137            bool s = false;
138            for (int i = 0; i < wildcardList.Count; i++)
139            {
140                Wildcard wc = ((Wildcard)wildcardList[i]);
141                if (!s && (wc.size() - wc.count()) > 1)
142                {
143                    Wildcard[] wcs = wc.split();
144                    patterns[0].wildcardList.Add(wcs[0]);
145                    patterns[1].wildcardList.Add(wcs[1]);
146                    s = true;
147                }
148                else
149                {
150                    patterns[0].wildcardList.Add(new Wildcard(wc));
151                    Wildcard copy = new Wildcard(wc);
152                    if (s)
153                        copy.resetCounter();
154                    patterns[1].wildcardList.Add(copy);
155                }
156            }
157            if (!s)
158                throw new Exception("Can't be split!");
159            return patterns;
160        }
161
162        public string giveWildcardKey()
163        {
164            string res = "";
165            int i = 0;
166            while (i < pattern.Length)
167            {
168                if (pattern[i] != '[')
169                    res += pattern[i];
170                else
171                {
172                    res += '*';
173                    while (pattern[i] != ']')
174                        i++;
175                }
176                i++;
177            }
178            return res;
179        }
180
181        public bool testKey(string key)
182        {
183            int kcount = 0;
184            int pcount = 0;
185            while (kcount < key.Length && pcount < pattern.Length)
186            {
187                if (pattern[pcount] != '[')
188                {
189                    if (key[kcount] != '*' && pattern[pcount] != key[kcount])
190                        return false;
191                    kcount++;
192                    pcount++;
193                }
194                else
195                {
196                    bool contains = false;
197                    pcount++;
198                    while (pattern[pcount] != ']')
199                    {
200                        if (key[kcount] != '*')
201                        {
202                            if (pattern[pcount + 1] == '-')
203                            {
204                                if (key[kcount] >= pattern[pcount] && key[kcount] <= pattern[pcount + 2])
205                                    contains = true;
206                                pcount += 2;
207                            }
208                            else
209                                if (pattern[pcount] == key[kcount])
210                                    contains = true;
211                        }
212                        pcount++;
213                    }
214                    if (!contains && !(key[kcount] == '*'))
215                        return false;
216                    kcount++;
217                    pcount++;
218                }               
219            }
220            if (pcount != pattern.Length || kcount != key.Length)
221                return false;
222            return true;
223        }
224
225        public long initKeyIteration(string key)
226        {
227            long counter = 1;
228            this.key = key;
229            int pcount = 0;
230            wildcardList = new ArrayList();
231            for (int i = 0; i < key.Length; i++)
232            {
233                if (key[i] == '*')
234                {
235                    Wildcard wc = new Wildcard(pattern.Substring(pcount, pattern.IndexOf(']', pcount) + 1 - pcount));
236                    wildcardList.Add(wc);
237                    counter *= wc.size();
238                }
239
240                if (pattern[pcount] == '[')
241                    while (pattern[pcount] != ']')
242                        pcount++;
243                pcount++;
244            }
245            return counter;
246        }
247
248        public long size()
249        {
250            if (wildcardList == null)
251                return 0;
252            long counter = 1;
253            foreach (Wildcard wc in wildcardList)
254                    counter *= wc.size();
255            return counter;
256        }
257
258        /** used to jump to the next Key.         
259         * if nextWildcard == -1, we return false
260         * if nextWildcard == -2, we return true
261         * if nextWildcard == -3, we increase the rightmost wildcard
262         * if nextWildcard >= 0, we increase the wildcard on the position 'nextWildcard'
263         * returns false if there is no key left.
264         */
265        public bool nextKey(int nextWildcard)
266        {
267            if (nextWildcard == -2)
268                return true;
269            if (nextWildcard == -1)
270                return false;
271
272            int wildcardCount;
273            if (nextWildcard == -3)
274                wildcardCount = wildcardList.Count - 1;
275            else
276                wildcardCount = nextWildcard;
277            bool overflow = ((Wildcard)wildcardList[wildcardCount]).succ();
278            wildcardCount--;
279            while (overflow && (wildcardCount >= 0))
280                overflow = ((Wildcard)wildcardList[wildcardCount--]).succ();
281            return !overflow;
282        }
283
284        public string getKey()
285        {
286            string res = "";
287            int wildcardCount = 0;
288            for (int i = 0; i < key.Length; i++)
289            {
290                if (key[i] != '*')
291                    res += key[i];
292                else
293                {
294                    Wildcard wc = (Wildcard)wildcardList[wildcardCount++];
295                    res += wc.getChar();
296                }
297            }
298            return res;
299        }
300
301        public string getKey(int add)
302        {
303            string res = "";
304            int div = 1;
305            int wildcardCount = wildcardList.Count-1;
306            for (int i = key.Length-1; i >= 0; i--)
307            {
308                if (key[i] != '*')
309                    res += key[i];
310                else
311                {
312                    Wildcard wc = (Wildcard)wildcardList[wildcardCount--];
313                    if (add < div)
314                        res += wc.getChar();
315                    else
316                    {
317                        res += wc.getChar((add / div) % wc.size());
318                        div *= wc.size();
319                    }
320                }
321            }
322            char[] r = res.ToCharArray();
323            Array.Reverse(r);
324            return new string(r);
325        }
326
327        public string getKeyBlock(ref int blocksize, ref int nextWildcard)
328        {
329            const int MAXSIZE = 65536;
330            //find out how many wildcards we can group together:
331            blocksize = 1;
332            int pointer;
333            for (pointer = wildcardList.Count - 1; pointer >= 0; pointer--)
334            {
335                Wildcard wc = (Wildcard)wildcardList[pointer];
336                if (wc.isSplit || wc.count() != 0 || blocksize*wc.size() > MAXSIZE)               
337                    break;
338                else
339                    blocksize *= wc.size();
340            }           
341
342            if (pointer >= wildcardList.Count)
343                return null;
344
345            nextWildcard = pointer;           
346
347            //generate key:
348            string res = "";
349            int wildcardCount = 0;
350            for (int i = 0; i < key.Length; i++)
351            {
352                if (key[i] != '*')
353                    res += key[i];
354                else
355                {
356                    if (pointer < wildcardCount)
357                        res += "*";
358                    else
359                    {
360                        Wildcard wc = (Wildcard)wildcardList[wildcardCount++];
361                        res += wc.getChar();
362                    }
363                }
364            }
365            return res;
366        }
367
368    }
369   
370    [Author("Thomas Schmid", "thomas.schmid@cryptool.org", "Uni Siegen", "http://www.uni-siegen.de")]
371    //[Author("Sven Rech", "rech@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
372    [PluginInfo(true, "KeySearcher", "Bruteforces a decryption algorithm.", null, "KeySearcher/Images/icon.png")]
373    public class KeySearcher : IAnalysisMisc
374    {
375        private Queue valuequeue;
376        private double value_threshold;
377        private int maxThread;  //the thread with the most keys left
378        private Mutex maxThreadMutex = new Mutex();
379
380        private KeyPattern pattern = null;
381        public KeyPattern Pattern
382        {
383            get
384            {
385                return pattern;
386            }
387            set
388            {
389                pattern = value;
390                if ((settings.Key == null) ||((settings.Key != null) && !pattern.testKey(settings.Key)))
391                    settings.Key = pattern.giveWildcardKey();
392            }
393        }
394
395        private bool stop;
396
397        #region IPlugin Members
398
399        public event StatusChangedEventHandler OnPluginStatusChanged;
400
401        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
402
403        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
404
405        private KeySearcherSettings settings;
406
407        public KeySearcher()
408        {
409            settings = new KeySearcherSettings(this);
410            QuickWatchPresentation = new KeySearcherQuickWatchPresentation();
411        }
412
413        public ISettings Settings
414        {
415            get { return settings; }
416        }
417
418        public UserControl Presentation
419        {
420            get { return null; }
421        }
422
423        public UserControl QuickWatchPresentation
424        {
425            get;
426            private set;
427        }
428
429        public void PreExecution()
430        {
431        }
432
433        public void Execute()
434        {
435        }
436
437        private class ThreadStackElement
438        {
439            public AutoResetEvent ev;
440            public int threadid;
441        }
442
443        private void KeySearcherJob(object param)
444        {
445            object[] parameters = (object[])param;
446            KeyPattern[] patterns = (KeyPattern[])parameters[0];
447            int threadid = (int)parameters[1];
448            Int64[] doneKeysArray = (Int64[])parameters[2];
449            Int64[] keycounterArray = (Int64[])parameters[3];
450            Int64[] keysLeft = (Int64[])parameters[4];
451            IControlEncryption sender = (IControlEncryption)parameters[5];           
452            int bytesToUse = (int)parameters[6];
453            Stack threadStack = (Stack)parameters[7];
454
455            KeyPattern pattern = patterns[threadid];
456
457            bool useKeyblocks = true;
458
459            try
460            {
461                while (pattern != null)
462                {
463                    long size = pattern.size();
464                    keysLeft[threadid] = size;
465                    int nextWildcard;
466
467                    do
468                    {
469                        //if we are the thread with most keys left, we have to share them:
470                        if (maxThread == threadid && threadStack.Count != 0)
471                        {
472                            maxThreadMutex.WaitOne();
473                            if (maxThread == threadid && threadStack.Count != 0)
474                            {
475                                try
476                                {
477                                    KeyPattern[] split = pattern.split();
478                                    patterns[threadid] = split[0];
479                                    pattern = split[0];
480                                    ThreadStackElement elem = (ThreadStackElement)threadStack.Pop();
481                                    patterns[elem.threadid] = split[1];
482                                    elem.ev.Set();    //wake the other thread up                                   
483                                    size = pattern.size();
484                                    keysLeft[threadid] = size;
485                                }
486                                catch (Exception e)
487                                {
488                                    //pattern can't be split? who cares :)
489                                }
490                                maxThread = -1;
491                            }
492                            maxThreadMutex.ReleaseMutex();
493                        }
494
495
496                        ValueKey valueKey = new ValueKey();
497                        int blocksize = 0;
498                        nextWildcard = -3;
499                        try
500                        {
501                            string key = "";
502                            if (useKeyblocks)
503                                key = pattern.getKeyBlock(ref blocksize, ref nextWildcard);
504                            if (key == null)
505                                useKeyblocks = false;
506                            if (!useKeyblocks)
507                                key = pattern.getKey();
508                            valueKey.key = key;
509                        }
510                        catch (Exception ex)
511                        {
512                            GuiLogMessage("Could not get next key: " + ex.Message, NotificationLevel.Error);
513                            return;
514                        }
515
516                        int[] arrayPointers = null;
517                        int[] arraySuccessors = null;
518                        int[] arrayUppers = null;
519                        byte[] keya = ControlMaster.getKeyFromString(valueKey.key, ref arrayPointers, ref arraySuccessors, ref arrayUppers);
520                        if (keya == null)
521                        {
522                            useKeyblocks = false;
523                            nextWildcard = -2;
524                            continue;   //try again
525                        }
526
527                        if (arrayPointers == null)  //decrypt only one key
528                        {
529                            if (!decryptAndCalculate(sender, bytesToUse, ref valueKey, keya, 0, null))
530                                return;                           
531                            doneKeysArray[threadid]++;
532                            keycounterArray[threadid]++;
533                            keysLeft[threadid]--;
534                        }
535                        else  //decrypt several keys
536                        {
537                            int counter = 0;
538                            if (!bruteforceBlock(sender, bytesToUse, ref valueKey, keya, arrayPointers, arraySuccessors, arrayUppers, 0, ref counter, pattern))
539                                return;
540                            doneKeysArray[threadid] += blocksize;
541                            keycounterArray[threadid] += blocksize;
542                            keysLeft[threadid] -= blocksize;
543                        }
544                    } while (pattern.nextKey(nextWildcard) && !stop);
545
546                    if (stop)
547                        return;
548
549                    //Let's wait until another thread is willing to share with us:
550                    pattern = null;
551                    ThreadStackElement el = new ThreadStackElement();
552                    el.ev = new AutoResetEvent(false);
553                    el.threadid = threadid;
554                    patterns[threadid] = null;
555                    threadStack.Push(el);
556                    GuiLogMessage("Thread waiting for new keys.", NotificationLevel.Debug);
557                    el.ev.WaitOne();
558                    GuiLogMessage("Thread waking up with new keys.", NotificationLevel.Debug);
559                    pattern = patterns[threadid];
560                }
561            }
562            finally
563            {
564                sender.Dispose();
565            }
566        }
567       
568        private bool bruteforceBlock(IControlEncryption sender, int bytesToUse, ref ValueKey valueKey, byte[] keya, int[] arrayPointers, 
569            int[] arraySuccessors, int[] arrayUppers, int arrayPointer, ref int counter, KeyPattern pattern)
570        {
571            byte store = keya[arrayPointers[arrayPointer]];
572            while (!stop)
573            {
574                if (arrayPointer+1 < arrayPointers.Length && arrayPointers[arrayPointer+1] != -1)
575                {
576                    if (!bruteforceBlock(sender, bytesToUse, ref valueKey, keya, arrayPointers, arraySuccessors, arrayUppers, arrayPointer + 1, ref counter, pattern))
577                        return false;
578                }
579                else
580                {
581                    if (!decryptAndCalculate(sender, bytesToUse, ref valueKey, keya, counter, pattern))
582                        return false;
583                }
584
585                if (keya[arrayPointers[arrayPointer]] + arraySuccessors[arrayPointer] <= arrayUppers[arrayPointer])
586                {
587                    keya[arrayPointers[arrayPointer]] += (byte)arraySuccessors[arrayPointer];
588                    counter++;
589                }
590                else
591                    break;
592            }
593            keya[arrayPointers[arrayPointer]] = store;
594            if (stop)
595                return false;
596            return true;
597        }
598
599        private bool decryptAndCalculate(IControlEncryption sender, int bytesToUse, ref ValueKey valueKey, byte[] keya, int counter, KeyPattern pattern)
600        {
601            try
602            {
603                valueKey.decryption = sender.Decrypt(keya, bytesToUse);
604            }
605            catch (Exception ex)
606            {
607                GuiLogMessage("Decryption is not possible: " + ex.Message, NotificationLevel.Error);
608                GuiLogMessage("Stack Trace: " + ex.StackTrace, NotificationLevel.Error);
609                return false;
610            }
611
612            try
613            {
614                valueKey.value = CostMaster.calculateCost(valueKey.decryption);
615            }
616            catch (Exception ex)
617            {
618                GuiLogMessage("Cost calculation is not possible: " + ex.Message, NotificationLevel.Error);
619                return false;
620            }
621
622            if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
623            {
624                if (valueKey.value > value_threshold)
625                {
626                    if (pattern != null)
627                        valueKey.key = pattern.getKey(counter);
628                    valuequeue.Enqueue(valueKey);
629                }
630            }
631            else
632            {
633                if (valueKey.value < value_threshold)
634                {
635                    if (pattern != null)
636                        valueKey.key = pattern.getKey(counter);
637                    valuequeue.Enqueue(valueKey);
638                }
639            }
640            return true;
641        }
642
643        public void process(IControlEncryption sender)
644        {
645            if (sender != null && costMaster != null)
646            {
647                int maxInList = 10;
648                LinkedList<ValueKey> costList = new LinkedList<ValueKey>();
649                ValueKey valueKey = new ValueKey();
650                if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
651                    valueKey.value = double.MaxValue;
652                else
653                    valueKey.value = double.MinValue;
654                valueKey.key = "dummykey";
655                valueKey.decryption = new byte[0];
656                value_threshold = valueKey.value;
657                LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
658                for (int i = 1; i < maxInList; i++)
659                {
660                    node = costList.AddAfter(node, valueKey);
661                }
662
663                stop = false;
664                if (!Pattern.testKey(settings.Key))
665                {
666                    GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
667                    return;
668                }
669
670                int bytesToUse = 0;
671
672                try
673                {
674                    bytesToUse = CostMaster.getBytesToUse();
675                }
676                catch (Exception ex)
677                {
678                    GuiLogMessage("Bytes used not valid: " + ex.Message, NotificationLevel.Error);
679                    return;
680                }
681
682                LinkedListNode<ValueKey> linkedListNode;
683
684                KeyPattern[] patterns = new KeyPattern[settings.CoresUsed+1];
685                long size = Pattern.initKeyIteration(settings.Key);
686               
687                if (settings.CoresUsed > 0)
688                {
689                    KeyPattern[] patterns2 = Pattern.split();                   
690                    patterns[0] = patterns2[0];
691                    patterns[1] = patterns2[1];
692                    int p = 1;
693                    int threads = settings.CoresUsed - 1;
694                    while (threads > 0)
695                    {
696                        int maxPattern = -1;
697                        long max = 0;
698                        for (int i = 0; i <= p; i++)
699                            if (patterns[i].size() > max)
700                            {
701                                max = patterns[i].size();
702                                maxPattern = i;
703                            }
704                        KeyPattern[] patterns3 = patterns[maxPattern].split();
705                        patterns[maxPattern] = patterns3[0];
706                        patterns[++p] = patterns3[1];
707                        threads--;
708                    }
709                }
710                else
711                    patterns[0] = Pattern;
712
713                valuequeue = Queue.Synchronized(new Queue());
714
715                Int64[] doneKeysA = new Int64[patterns.Length];
716                Int64[] keycounters = new Int64[patterns.Length];
717                Int64[] keysleft = new Int64[patterns.Length];
718                Stack threadStack = Stack.Synchronized(new Stack());
719                for (int i = 0; i < patterns.Length; i++)
720                {
721                    WaitCallback worker = new WaitCallback(KeySearcherJob);
722                    doneKeysA[i] = new Int64();
723                    keycounters[i] = new Int64();
724                    ThreadPool.QueueUserWorkItem(worker, new object[] { patterns, i, doneKeysA, keycounters, keysleft, sender.clone(), bytesToUse, threadStack });
725                }
726               
727                //update message:
728                while (!stop)
729                {
730                    Thread.Sleep(1000);
731
732                    //update toplist:
733                    while (valuequeue.Count != 0)
734                    {
735                        ValueKey vk = (ValueKey)valuequeue.Dequeue();
736                        if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
737                        {
738                            if (vk.value > costList.Last().value)
739                            {
740                                node = costList.First;
741                                while (node != null)
742                                {
743                                    if (vk.value > node.Value.value)
744                                    {
745                                        costList.AddBefore(node, vk);
746                                        costList.RemoveLast();
747                                        value_threshold = costList.Last.Value.value;
748                                        break;
749                                    }
750                                    node = node.Next;
751                                }//end while
752                            }//end if
753                        }
754                        else
755                        {
756                            node = costList.First;
757                            if (vk.value < costList.Last().value)
758                            {
759                                while (node != null)
760                                {
761
762                                    if (vk.value < node.Value.value)
763                                    {
764                                        costList.AddBefore(node, vk);
765                                        costList.RemoveLast();
766                                        value_threshold = costList.Last.Value.value;
767                                        break;
768                                    }
769                                    node = node.Next;
770                                }//end while
771                            }//end if
772                        }
773                    }
774
775                    long keycounter = 0;
776                    long doneKeys = 0;
777                    foreach (Int64 dk in doneKeysA)
778                        doneKeys += dk;
779                    foreach (Int64 kc in keycounters)
780                        keycounter += kc;
781
782                    if (keycounter > size)
783                        GuiLogMessage("There must be an error, because we bruteforced too much keys...", NotificationLevel.Error);
784
785                    //Let's determine which thread has the most keys to share:
786                    if (size - keycounter > 1000)
787                    {
788                        maxThreadMutex.WaitOne();
789                        long max = 0;
790                        int id = -1;
791                        for (int i = 0; i < patterns.Length; i++)
792                            if (keysleft[i] > max)
793                            {
794                                max = keysleft[i];
795                                id = i;
796                            }
797                        maxThread = id;
798                        maxThreadMutex.ReleaseMutex();
799                    }
800
801                    ProgressChanged(keycounter, size);
802
803                    if (QuickWatchPresentation.IsVisible && doneKeys != 0 && !stop)
804                    {
805                        double time = ((size - keycounter) / doneKeys);
806                        TimeSpan timeleft = new TimeSpan(-1);
807
808                        try
809                        {
810                            if (time / (24 * 60 * 60) <= int.MaxValue)
811                            {
812                                int days = (int)(time / (24 * 60 * 60));
813                                time = time - (days * 24 * 60 * 60);
814                                int hours = (int)(time / (60 * 60));
815                                time = time - (hours * 60 * 60);
816                                int minutes = (int)(time / 60);
817                                time = time - (minutes * 60);
818                                int seconds = (int)time;
819
820                                timeleft = new TimeSpan(days, hours, minutes, (int)seconds, 0);
821                            }
822                        }
823                        catch
824                        {
825                            //can not calculate time span
826                        }
827
828                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
829                        {
830                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).keysPerSecond.Text = "" + doneKeys;
831                            if (timeleft != new TimeSpan(-1))
832                            {
833                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "" + timeleft;
834                                try
835                                {
836                                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "" + DateTime.Now.Add(timeleft);
837                                }
838                                catch
839                                {
840                                    ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "in a galaxy far, far away...";
841                                }
842                            }
843                            else
844                            {
845                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).timeLeft.Text = "incalculable :-)";
846                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).endTime.Text = "in a galaxy far, far away...";
847                            }
848
849                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).listbox.Items.Clear();
850                            linkedListNode = costList.First;
851                            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
852                            int i = 0;
853                            while (linkedListNode != null)
854                            {
855                                i++;
856                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).listbox.Items.Add(i + ") " + Math.Round(linkedListNode.Value.value, 4) + " = " + linkedListNode.Value.key + " : \"" +
857                                    enc.GetString(linkedListNode.Value.decryption).Replace("\n", "").Replace("\r", "").Replace("\t", "") + "\"");
858                                linkedListNode = linkedListNode.Next;
859                            }
860                        }
861                        , null);
862                    }//end if
863                    doneKeys = 0;
864                    for (int i = 0; i < doneKeysA.Length; i++)
865                        doneKeysA[i] = 0;
866
867                    if (!stop && QuickWatchPresentation.IsVisible)
868                    {
869
870                        ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
871                        {
872                            ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).listbox.Items.Clear();
873                            linkedListNode = costList.First;
874                            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
875                            int i = 0;
876                            while (linkedListNode != null)
877                            {
878                                i++;
879                                ((KeySearcherQuickWatchPresentation)QuickWatchPresentation).listbox.Items.Add(i + ") " + Math.Round(linkedListNode.Value.value, 4) + " = " + linkedListNode.Value.key + " : \"" +
880                                    enc.GetString(linkedListNode.Value.decryption).Replace("\n", "").Replace("\r", "").Replace("\t", "") + "\"");
881                                linkedListNode = linkedListNode.Next;
882                            }
883                        }
884                        , null);
885                    }
886
887                    if (keycounter >= size)
888                        break;
889                }//end while
890
891                //wake up all sleeping threads:
892                while (threadStack.Count != 0)
893                    ((ThreadStackElement)threadStack.Pop()).ev.Set();
894            }//end if
895
896            if (!stop)
897                ProgressChanged(1, 1);
898        }
899
900        public void PostExecution()
901        {
902        }
903
904        public void Pause()
905        {
906        }
907
908        public void Stop()
909        {
910            stop = true;
911        }
912
913        public void Initialize()
914        {
915        }
916
917        public void Dispose()
918        {
919        }
920
921        #endregion
922
923        #region INotifyPropertyChanged Members
924
925        public event PropertyChangedEventHandler PropertyChanged;
926
927        public void OnPropertyChanged(string name)
928        {
929            if (PropertyChanged != null)
930            {
931                PropertyChanged(this, new PropertyChangedEventArgs(name));
932            }
933        }
934
935        #endregion
936
937        private void keyPatternChanged()
938        {
939            Pattern = new KeyPattern(controlMaster.getKeyPattern());
940        }
941
942        private void onStatusChanged(IControl sender, bool readyForExecution)
943        {
944            if (readyForExecution)
945            {
946                this.process((IControlEncryption)sender);
947            }
948        }
949
950        #region IControlEncryption Members
951
952        private IControlEncryption controlMaster;
953        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
954        public IControlEncryption ControlMaster
955        {
956            get { return controlMaster; }
957            set
958            {
959                if (controlMaster != null)
960                {
961                    controlMaster.keyPatternChanged -= keyPatternChanged;
962                    controlMaster.OnStatusChanged -= onStatusChanged;
963                }
964                if (value != null)
965                {
966                    Pattern = new KeyPattern(value.getKeyPattern());
967                    value.keyPatternChanged += keyPatternChanged;
968                    value.OnStatusChanged += onStatusChanged;
969                    controlMaster = value;
970                    OnPropertyChanged("ControlMaster");
971                   
972                }
973                else
974                    controlMaster = null;
975            }
976        }
977
978        #endregion
979
980        #region IControlCost Members
981
982        private IControlCost costMaster;
983        [PropertyInfo(Direction.ControlMaster, "Cost Master", "Used for cost calculation", "", DisplayLevel.Beginner)]
984        public IControlCost CostMaster
985        {
986            get { return costMaster; }
987            set
988            {
989                costMaster = value;
990            }
991        }
992
993        #endregion
994
995        public void GuiLogMessage(string message, NotificationLevel loglevel)
996        {
997            if (OnGuiLogNotificationOccured != null)
998                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
999        }
1000
1001        public void ProgressChanged(double value, double max)
1002        {
1003            if (OnPluginProgressChanged != null)
1004            {
1005                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
1006
1007            }
1008        }
1009
1010        private struct ValueKey
1011        {
1012            public double value;
1013            public String key;
1014            public byte[] decryption;
1015        };
1016    }
1017}
Note: See TracBrowser for help on using the repository browser.