96 bitw szalestwa by lock3r//eVC

"I left alone, my mind was blank[..], what did I see, can I believe,
That what I saw last night was real and not just fantasy,
cause in my dreams it's always there, the evil _CODE_ that twists
my mind and brings me to despair... yeahhhhhhhhhhhhhhhhhhhhhhhh"

Okoo 0,5 roku temu na moim dysku zagocio niecodziennie chaotyczne crackme, bdce krystalicznie czystym, acz nieoszlifowanym diamentem kryptograficznym. W tym okresie podem 3 prby zamania tego arcydziea, bdcego wynikiem wytonej pracy jednego z silniej zainspirowanych przez THC modych umysw naszego maego, ale jake barwnego pwiatka crackerskiego. Z luboci wyobraaem sobie chwile, w ktrej oznajmi bd mg wiatu w jaki sposb znalazem rozwizanie niecodziennego problemu, zapocztkowanego w chorej gowie tego niedopieszczonego przez kobiety osobnika hehe. Jakkolwiek wyodrbnienie z chaosu logicznej czstki nie dla kadego jest zadaniem atwym, szczeglnie w kraju, gdzie iloraz inteligencji jest odwrotnie proporcjonalny do zajmowanego stanowiska. Jak to mawiaj "Chopin gdyby y to by pi" hehe wiate umysy, modzi geniusze ju dawno przejrzeli w jakim kierunku zmierza nasza Polska. W kadym razie uciekajc od polityki, a wracajc do amania hase, postaram si opisa, jak mona pozna rozwizania tego problemu. Jest on rwnie banalny jak wikszo zagadek z MENSY rodem, czyli dopiero poznanie rozwizania ujawnia trywialno pytania. Abstrahujc od craXorow, ktrzy ograniczeni przez (nie)dowiadczenie nie zrozumieli nawet istoty zamiany bajtw ASCII na ich reprezentacje binarna w macierzach [jake modne dzisiaj sowo macierz czyli popularny matrix, undergroundowe trendy obnaone, nie le mwi skomercjalizowane, c za ironia losu hehe], a wiem e i takowi istniej, postaram si przedstawi banalne w swojej prostocie rozwizanie. I cakowicie mnie nie obchodzi, e nie mam dziewczyny, e nie rozmawiam z ludmi, e spdzam 3 noce nad analiz jakiego kodu, e analizuje jakie gupie liczby zamiast znale sobie kobiet, z ktr mgbym spdzi reszt ycia. Przez ten cay czas crackme 4 stao si istotn czci mojego ycia, by moe dlatego, e w wielkim stopniu fascynuje mnie chaos... ktrym okrelamy to, czego nie potrafi opisa nawet najbardziej abstrakcyjna, ale i chwalebna dziedzina jak jest matematyka. Tak tak moi drodzy, to jedyna prawda, matematyka jest wszdzie. Mam takie mae schizy po ledzeniu kodu, a waciwie po jego analizie w hexedit, e widz wszdzie jakie liczby, wymylam jakie pomylone zalenoci, wiem, e to chore widzie wszdzie liczby, ale tak jest, patrz na co, a tam 0x126548Ab8, taki matrix Live. To tyle tytuem wstpu, chyba macie niewielki wgld w zakamarki mego zawiego umysu, ale dam wam rad jak daem jednemu psychologowi "Mj umys to labirynt, najlepsze wyjcie? nie wchodzi". Okej po krtkim, ale jake owocnym i interesujcym wstpie przejdziemy do amania crackme4. Tym samym koniec moczenia si w nocy, kto wie, kto wie jeszcze 2 wizyty u psychiatry i moe bd mg przej na najzwyklejsze wizyty u zwykego psychologa ;-).Chaos, tak to kocham, pikne i proste rozwizania niestety nie przychodz atwo. Po prostu znikd pojawia si myl i nagle wszystko staje si takie trywialne, jak Dowd Wielkiego Twierdzenia Fermata.

A wszystko to zaczo si pewnego pnego popoudnia, kiedy to mj kot Oliver wyskoczy ponownie przez okno w pokoju gocinnym. Tyle razy mwiem mu, e i tak jako niepenoletni nie ma szans na wpis do ksigi Gunnessa. Myl, e to wszystko przez jego psychik i to TVP. Mwiem, eby nie oglda przy nim Maysza, ale taki kot si zawsze schowa pod fotelem, zreszt sami wiecie. Jeszcze pniej mi ssiad mwi, e on woli psa, bo kot nie lduje telemarkiem. Ehh zawsze mwiem, e te reklamy KiteKat s niestosowne, taki kot myli pniej, e jest supermanem et. Np ostatnio Oliver widzia akademi powietrzn i si musia koniecznie desantowa na tyy wroga. Pniej patrz, a tam - shit - jaka plama, no nie dziwie si jak 5 kilo ywej wagi skacze na co, to pozostaje si pomodli o wstawiennictwo o. Rydzyka. Okej, bo po tym Heinekenie odbiegem od tematu. Z zamysu ma to by opis amania kryptosystemu i uwaam, e uwaczaoby godnoci zarwno mojej jak i czytelnika gdybym opisywa rzeczy oczywiste. Po zahookowaniu si do procki widzimy co takiego:

:00401502 3B1D0C304000            cmp ebx, dword ptr [0040300C]
:00401508 754B                    jne 00401555
:0040150A E806010000              call 00401615
:0040150F 6A40                    push 00000040
:00401511 6828304000              push 00403028
:00401516 FF3514304000            push dword ptr [00403014]
:0040151C E869090000              call 00401E8A
:00401521 83F80E                  cmp eax, 0000000E
:00401524 752D                    jne 00401553
:00401526 8D1528304000            lea edx, dword ptr [00403028]
:0040152C 8A1A                    mov bl, byte ptr [edx]
:0040152E 80EB30                  sub bl, 30
:00401531 84DB                    test bl, bl
:00401533 741E                    je 00401553
:00401535 0FB6DB                  movzx ebx, bl
:00401538 891D75304000            mov dword ptr [00403075], ebx
:0040153E 42                      inc edx
:0040153F 8A1A                    mov bl, byte ptr [edx]
:00401541 80FB2D                  cmp bl, 2D
:00401544 750D                    jne 00401553
:00401546 42                      inc edx
:00401547 891569304000            mov dword ptr [00403069], edx
:0040154D FF05E3104000            inc dword ptr [004010E3]

Otrzymujemy tutaj informacje, e serial musi mie form x-xxxxxxxxxxxx, ale co ciekawe po traceowaniu wychodzimy i nie ogldamy adnego kodu odpowiedzialnego za nasze obliczenia. Sugeruje wic puapk na pami np. na [00403075], albo jak kto woli depacknicie WWPacka i postawienie int 3 w miejscu rozpoczcia prawdziwej CheckProcki. Wiec teraz 1st checkpoint, czyli ogupienie SoftIce'a mamy ju za sob. Po zahookowaniu si do waciwego kodu widzimy procke wygladajc tak:

:004016B1 8B1569304000            mov edx, dword ptr [00403069]
:004016B7 50                      push eax
:004016B8 8A0C10                  mov cl, byte ptr [eax+edx]
:004016BB 86D9                    xchg cl, bl
:004016BD D2EB                    shr bl, cl
:004016BF 86D9                    xchg cl, bl
:004016C1 80E101                  and cl, 01 ; (1)
:004016C4 53                      push ebx
:004016C5 0BDB                    or ebx, ebx
:004016C7 7507                    jne 004016D0
:004016C9 BB07000000              mov ebx, 00000007
:004016CE EB4F                    jmp 0040171F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016C7(C)
|
:004016D0 83FB01                  cmp ebx, 00000001 ; (2)
:004016D3 7507                    jne 004016DC
:004016D5 BB06000000              mov ebx, 00000006
:004016DA EB43                    jmp 0040171F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016D3(C)
|
:004016DC 83FB02                  cmp ebx, 00000002
:004016DF 7507                    jne 004016E8
:004016E1 BB05000000              mov ebx, 00000005
:004016E6 EB37                    jmp 0040171F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016DF(C)
|
:004016E8 83FB03                  cmp ebx, 00000003
:004016EB 7507                    jne 004016F4
:004016ED BB04000000              mov ebx, 00000004
:004016F2 EB2B                    jmp 0040171F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016EB(C)
|
:004016F4 83FB04                  cmp ebx, 00000004
:004016F7 7507                    jne 00401700
:004016F9 BB03000000              mov ebx, 00000003
:004016FE EB1F                    jmp 0040171F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016F7(C)
|
:00401700 83FB05                  cmp ebx, 00000005
:00401703 7507                    jne 0040170C
:00401705 BB02000000              mov ebx, 00000002
:0040170A EB13                    jmp 0040171F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401703(C)
|
:0040170C 83FB06                  cmp ebx, 00000006
:0040170F 7507                    jne 00401718
:00401711 BB01000000              mov ebx, 00000001
:00401716 EB07                    jmp 0040171F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040170F(C)
|
:00401718 83FB07                  cmp ebx, 00000007
:0040171B 7502                    jne 0040171F
:0040171D 2BDB                    sub ebx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004016CE(U), :004016DA(U), :004016E6(U), :004016F2(U), :004016FE(U)
|:0040170A(U), :00401716(U), :0040171B(C)
|
:0040171F FF35D7104000            push dword ptr [004010D7]
:00401725 53                      push ebx
:00401726 50                      push eax
:00401727 E857010000              call 00401883
:0040172C 8B151C304000            mov edx, dword ptr [0040301C]
:00401732 80F901                  cmp cl, 01
:00401735 7506                    jne 0040173D
:00401737 C6041001                mov byte ptr [eax+edx], 01
:0040173B EB04                    jmp 00401741

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401735(C)
|
:0040173D C6041000                mov byte ptr [eax+edx], 00

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040173B(U)
|
:00401741 5B                      pop ebx
:00401742 58                      pop eax
:00401743 43                      inc ebx
:00401744 83FB08                  cmp ebx, 00000008 ;(3)
:00401747 0F8564FFFFFF            jne 004016B1
:0040174D 40                      inc eax
:0040174E 83F80C                  cmp eax, 0000000C
:00401751 0F8558FFFFFF            jne 004016AF

Niewdziczne moje zadanie jako piszcego, od razu przecie wida co robi zaprezentowany kod. Bajty z wpisanego seriala zostaj tutaj zamienione na swoj posta binarna i umieszczone w macierzy o rozmiarach (a jakeby inaczej) 8x12. Fragment (1) odpowiedzialny jest za wysuwanie kolejnych bitw i przepuszczenie przez bramk AND z 1. W ten prosty sposb poznajemy czy bit o numerze N jest ustawiony czy tez nie.(2) odpowiada za wysunicie (7-N) bitw dla sprawdzenie bitu N co opisaem wczeniej.(3) to instrukcje sterujce procedur. Warto jeszcze zaznaczy, e bajty s ustawiane [0,0]...[0,7],[1,0]...,[1,7] - oczywista logiczna konsekwencja, ale lepiej, eby to nie umkno niczyjej uwadze. Teraz idc dalej odnajdujemy wywoanie waciwej funkcji mieszajcej [szyfrujcej].

:00401757 8B0D75304000            mov ecx, dword ptr [00403075] (4)
                                   
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401767(C)
|
:0040175D 49                      dec ecx
:0040175E 51                      push ecx
:0040175F E831010000              call 00401895 (5)
:00401764 59                      pop ecx
:00401765 85C9                    test ecx, ecx
:00401767 75F4                    jne 0040175D
:00401769 2BC0                    sub eax, eax

W punkcie (4) ecx jest inicjalizowane przez pierwsza liczb z naszego stringa s/n. A jak si okae 0x00401895 to wanie nasza funkcja szyfrujca. Dalej oczywicie loop procki szyfrujcej zalenie od wartoci pierwszego bajtu seriala. Teraz gwna funkcja crackmesa, ze wzgldu na jej dugo i wyjtkowe samopodobiestwo, opisz tylko 1 fragment kodu. Reszta byaby marnotrawstwem twojego, a co gorsza mojego czasu. Inteligentny czytelnik rozumujc przez analogie pozna po tych wyjanieniach istot procedury.

* Referenced by a CALL at Address:
|:0040175F   
|
:00401895 8B0D6D304000            mov ecx, dword ptr [0040306D]
:0040189B 8B3D20304000            mov edi, dword ptr [00403020]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004018A9(C)
|
:004018A1 C64439FF00              mov [ecx+edi-01], 00
:004018A6 49                      dec ecx
:004018A7 85C9                    test ecx, ecx
:004018A9 75F6                    jne 004018A1
:004018AB FF0571304000            inc dword ptr [00403071]
:004018B1 8B3D1C304000            mov edi, dword ptr [0040301C]
:004018B7 8B3520304000            mov esi, dword ptr [00403020]
:004018BD 2BC0                    sub eax, eax
:004018BF 2BDB                    sub ebx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401DDE(C)
|
:004018C1 50                      push eax
:004018C2 53                      push ebx
:004018C3 FF35D7104000            push dword ptr [004010D7]
:004018C9 53                      push ebx
:004018CA 50                      push eax
:004018CB E8B3FFFFFF              call 00401883
:004018D0 8BC8                    mov ecx, eax
:004018D2 5B                      pop ebx
:004018D3 58                      pop eax
:004018D4 50                      push eax
:004018D5 53                      push ebx
:004018D6 0BC0                    or eax, eax
:004018D8 0F8554010000            jne 00401A32
:004018DE 0BDB                    or ebx, ebx
:004018E0 7552                    jne 00401934
:004018E2 50                      push eax
:004018E3 53                      push ebx
:004018E4 40                      inc eax
:004018E5 FF35D7104000            push dword ptr [004010D7]
:004018EB 53                      push ebx
:004018EC 50                      push eax
:004018ED E891FFFFFF              call 00401883
:004018F2 803C3801                cmp byte ptr [eax+edi], 01
:004018F6 7503                    jne 004018FB
:004018F8 FE0431                  inc byte ptr [ecx+esi]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004018F6(C)
|
:004018FB 5B                      pop ebx
:004018FC 58                      pop eax
:004018FD 50                      push eax
:004018FE 53                      push ebx
:004018FF 43                      inc ebx
:00401900 FF35D7104000            push dword ptr [004010D7]
:00401906 53                      push ebx
:00401907 50                      push eax
:00401908 E876FFFFFF              call 00401883
:0040190D 803C3801                cmp byte ptr [eax+edi], 01
:00401911 7503                    jne 00401916
:00401913 FE0431                  inc byte ptr [ecx+esi]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401911(C)
|
:00401916 5B                      pop ebx
:00401917 58                      pop eax
:00401918 50                      push eax
:00401919 53                      push ebx
:0040191A 40                      inc eax
:0040191B 43                      inc ebx
:0040191C FF35D7104000            push dword ptr [004010D7]
:00401922 53                      push ebx
:00401923 50                      push eax
:00401924 E85AFFFFFF              call 00401883
:00401929 803C3801                cmp byte ptr [eax+edi], 01
:0040192D 7503                    jne 00401932
:0040192F FE0431                  inc byte ptr [ecx+esi]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040192D(C)
|
:00401932 5B                      pop ebx
:00401933 58                      pop eax

Operujemy tutaj na 2 macierzach o rozmiarach 8x12 kada, czyli mieszczcych dokadnie 3 DWORDY naszego seriala te aaaabbbbcccc wystpujce po "x-". Powyszy fragment kodu sprawdza ssiedztwo bitowe tablicy uzyskanej z wejcia oraz inkrementuje warto bajtu [tak tak tutaj mwie o bajcie, bo chodzi o inna tablice, w rzeczywistoci i tak wszystko dzieje si na bajtach symulujcych tylko tablice bitowe]. Wynik zostaje umieszczony w tablicy. Tutaj mamy do czynienia ze sprawdzaniem przypadku 1. Aby przedstawi o co chodzi, zilustruje to na prostym przykadzie matrix'a 3x3:

101    131
010 -> 343 
101    131 

Miodzio podzieli ca procedur na mae przypadki, pierwszy z nich dotyczy eax=0 i ebx=0 czyli pozycjonowanie na bajcie no.0. Wypadek taki jest szczeglny, gdy ssiedztwo nie moe by opisane klasycznymi wzorami z powodu braku niektrych bitw ssiednich. W takim wypadku liczba bitw granicznych = 3. Dla bajtu [0,1]=5 , [0,2]=3, pene ssiedztwo mona w macierzy przykadowej 3x3 sprawdzi tylko w rodku, czyli dla bajtu [1,1]=8. Podobnie rzecz dzieje si z nasz macierz 8x12, myl, e wszystko jasne. To jest wanie istota tego kryptosystemu. Rwnania opisujce sumowanie bitw wygldaj nastpujco [notacja C]

     if(x-1>=0) t+=tab2[x-1][y];
     if(x+1<=wys) t+=tab2[x+1][y];
     if(y+1<=szer) t+=tab2[x][y+1];
     if(y-1>=0) t+=tab2[x][y-1];
     if(x-1>=0 && y+1<=szer) t+=tab2[x-1][y+1];
     if(x-1>=0 && y-1>=0) t+=tab2[x-1][y-1];
     if(x+1<=wys && y+1<=szer) t+=tab2[x+1][y+1];
     if(x+1<=wys && y-1<=0) t+=tab2[x+1][y-1];

Gdzie t[x,y] jest tablic dwuwymiarow, przechowujc sumy ssiedztw bitowych. Jak zapewne uwany czytelnik zauway, promie stanowicy ssiedztwo wynosi 1 wiersz/kolumn. Waciwie poprzednie moje wyjanienia, nie mwi jak dziaa system. Oto kolejna jego cz:

:00401DF7 8A0C30                  mov cl, byte ptr [eax+esi]
:00401DFA 80F903                  cmp cl, 03
:00401DFD 7506                    jne 00401E05
:00401DFF C6043801                mov byte ptr [eax+edi], 01
:00401E03 EB0E                    jmp 00401E13

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401DFD(C)
|
:00401E05 80F903                  cmp cl, 03
:00401E08 7409                    je 00401E13
:00401E0A 80F902                  cmp cl, 02
:00401E0D 7404                    je 00401E13
:00401E0F C6043800                mov byte ptr [eax+edi], 00

Tutaj sprawdzane s sumy i jeli bajt wynosi 3, to ustawienie bitu w odpowiedniej macierzy, w przeciwnym wypadku mov byte ptr[eax+edi],00. Szczegolny przypadek to 2, wtedy bit zaley od wartoci tego, ktrego ssiedztwo sprawdzamy. Zatem kontynuujc przykad 3x3 mamy szyfrowanie w sposb nastpujcy:


              101    131    010
[Decrypted]   010 -> 343 -> 101   [Encrypted]
              101    131    010

Przyzna naley, e jest to ciekawa transformacja i c by powiedzie nieodwracalna, oczywicie dla niewielkich macierzy nie problemem jest odnalezienie waciwego ustawienia "zbatek" [mwie zbatek, bo to bardzo analogiczne]. Waciwego nie oznacza jednak tutaj pocztkowego, bo wiele moliwych interpretacji rwna utrudnia analiz. Nie mwi tutaj oczywicie o przypadkach typu: 10/01, ktre mona poama w pamici. Sprawa komplikuje si jednak wraz ze zwikszeniem liczby kolumn/wierszy, ktra u nas wynosi odpowiednio 12 i 8! Dodatkowym utrudnieniem jest moliwy wpyw na wszystkie bity w zalenoci od loopa funkcji. Przykad dla N=1 [czyli bez loopa] odnajd ustawienie dla ktrego:

[Encrypted]
00010100 01010001 01000101
01000000 00000100 00000001
01010101 00010100 01000001
00000100 01000001 01010100

00000000 00000000 01000000
00000001 01000000 00000000
00000000 00000000 00000100
00000000 00000001 01010100

Mona oczywicie desperacko prbowa ustawia wszystko na kartce, ale prba taka, to waciwie to samo, co gra w toto-lotka, bo trudno mie wyobrani na wiele bitw do przodu, poniewa ustawienie caoci zalene jest od innych bitw. Taki szyfr o bloku 96 bitw to nie lada trudno dla amacza. To wanie ustawienie jest rwnie kocowym ustawieniem naszego szyfru, twoim zadaniem jako crackera jest odnalezienie wypenienia pocztkowego, ktre po przejciu przez szyfr da wynik taki jak wyej [Enc]. Trudne to zaprawd zadanie i dugo nie mogem go rozwiza. Prbowaem atakowa na wiele sposobw ten kryptosystem, ale nie udawao si. Oczywicie ze wzgldu na 2^96 moliwoci, niezbyt rozsdna wydaje si opcja Brute-Force'owania tym bardziej, e procka jest bardzo duga. Zajoby to nam kilka wiekw, do powiedzie e sprawdzenie jednego DWORDA zajmuje na Celeronie 1.7 Ghz 15 godzin. Musimy wtedy sprawdzi 256^5 moliwoci, do 5 potgi gdy 5 kolumna jest niezbdna do obliczenia ssiedztwa 4 kolumny. Kolejnym pomysem byo odnalezienie 3 * DWORD i nastpne poczenie uzyskanych wynikw, czyli sprawdzenie sum ssiedztw kolumn czcych i dopasowanie tylko tych, ktre dadz odpowiadajcy nam rezultat. Szybko dowiedziaem si, e jest to bezsensowne, poniewa dla maego K [liczba kolumn] ilo rozwiza jest ogromna, a dodatkowe pomnoenie tego przez 3 DWORDY daje ogromna ilo do sprawdzenia. Trudno te znale jak matematyczn zasad czenia, poniewa istnieje wiele moliwoci rozkadu bitu 1 chociaby

       1                                1            1
       |                                |            |
     <-1->1  mona rozoy te jako 1<-1->1 lub  1<-1->
                                              |
                                              1

Szczeglnie spraw utrudnia Suma=2, bo ona rwnie moe da 1 przykad:

11   bit [0.0]  bedzie ustawiony na 1[suma ssiedztw 2+1 za siebie =3]
10

Myl, e niezym pomysem mogoby by odwrcenie operacji, tyle e ze wzgldu na to, i 1 powsta moe na wiele sposobw, szczeglnie gdy ssiedztwo to 8 bitw (i 1 wasny) dugo oblicze byaby bardzo znaczca. Pozostawao wic wykluczenie bajtw pasywnych czyli tych, ktre nie bior udziau w tworzeniu 1 [np. te na dole 1 kolumny], okazao si oczywicie, e si myliem, gdy nawet max redukcja to 2^84 z oczywistych wzgldw nic nie da, a ponadto mimo i bajt nie wpywa bezporednio na tworzenie 1, to i tak jest istotny. Jednak byem przewiadczony, e da si to zama. Po tych prbach zrobiem sobie dug przerw i jakie 2 tygodnie temu wpadem na nowatorski pomys. Postanowiem ustawi 3 DWORDY sprawdzajc 3 kolumny w kadym z nich, a nastpnie poczenie takich, ktrych kolumny pasywne [ktrych ssiedztwa nie sprawdzam] si pokryj schemat m/w taki:

              |----|
          xxxxZxxxxZxx
          |__| |__| |_|
           dw1  dw2  w3

W cakiem rozsdnym czasie mona poczy takie dw1/dw2/w3 dla ktrych Z si pokryj. Jednak szybko przekonaem si o bezcelowoci takiego dziaania. Cay czas wierzyem jednak, e mona zama ten kryptosystem. Spokoju nie dawao mi to, e jest on tak chaotyczny, wyglda waciwie jak jaka funkcja losujca, a nie algorytm kryptograficzny. 96 bitw doprowadzio mnie do skrajnego wykoczenia psychicznego i stanw depresyjnych. Ten may, czerwony osobnik biegajcy po moim pokoju i krzyczcy "Dusza za brak hasa hehe" rwnie nie wpywa na popraw nastroju. Ale podpisany cyrograf podpisanym cyrografem, ale eby szczliwe zakoczy przygod i wyrwa si z niewolniczych acuchw naleao zama to cholerne haso. I oto pojawia si rewolucyjna myl... ju wiedziaem, e da si to zama. Jak wida granica moliwoci brute'a przy K-> oo wynosi nieskoczono. Rozwizanie moje polega na takim zoptymalizowaniu programu deszyfrujcego, aeby przy K-> oo Brute->0 ! I udao si tak zrobi, niewiarygodne w 10 min mona sprawdzi wszystkie moliwoci. Koncepcja wykorzystuje to, e algorytm jest pseudo-blokowy, co wida juz na wczesnym etapie jego badania. Ale o tym ju wspominaem i jest to warunek konieczny do zamania, ale nie wystarczajcy. Poszukiwanie drugiego zajo kolejna noc ;].Okazuje si, e warto zwrci uwag na fakt, i wraz ze zwikszajc si liczba bajtw maleje ilo moliwych ustawie dajcych potrzebny nam wynik. Teraz o tym, jak to wykorzysta... po prostu wystarczy napisa program deszyfrujcy, ktry sprawdza cz rozwizania [pseudo-blok] i nastpnie zagbia si w sprawdzanie dalej _TYLKO_ gdy wynik poredni jest w porzdku. Sprawdzamy wic kilka pierwszych kolumn, jeli wypenienie dobre, to sprawdzamy kolumn 4, jeeli to wypenienie dobre, sprawdzamy 5 etc. a dojdziemy do 12 kolumny. Oto fragmenty kodu rdowego [funkcja oblicz jest okrojona ze wzgldu na samopodobiestwo].

//Program deszyfrujcy haso miod-crkme4 wraz z plikami nagwkowymi//
////////////////by lock3r//eVC 2oo3/////////////////
//////////////////4/BCC5.0//////////////////////////
//increment.h

int tab2[8][12],tabtmp[8][12];

//ta funkcja inkrementuje bity kolumn

void TabBinInc(int k)
{

     for(int cx0=7;cx0>=0;cx0--)
     {
         if(tab2[cx0][k]==0)
           {
          tab2[cx0][k]=1;
          cx0=-1;

           }
         else tab2[cx0][k]=0;
     }

}

void zeruj()
{

     for(int cx=0;cx<8;cx++)
     {
           for(int c=0;c<12;c++)
           {
            tab2[cx][c]=0;
           }
     }

}
///////////////////////////
//sprawdz.h
//funkcja wypisujca wyniki oblicze do pliku.
#include <fstream.h>

void wypisz()
{

fstream plik;
plik.open("report.txt",ios::out||ios::end);

for(int l0=0;l0<wys;l0++)
      {
          for(int l1=0;l1<12;l1++)//?szer
               {
                plik<<tab2[l0][l1];//tab2
               }
               plik<<endl;
     // plik<<tab2[l0][0];

     }
      plik<<endl;
}
///////////////////////////
//Troch obcita bo pozostale podfunkcje oblicz robi to samo co 2 pierwsze,
//a nie chce mi si ich przeprogramowywa na rekurencyjne
//oblicz.h
#define wys 8
#define szer 4

int goodfill[8][12]={0,1,1,0,1,1,0,1,1,0,1,1,
               1,0,0,0,0,0,1,0,0,0,0,1,
               1,1,1,1,0,1,1,0,1,0,0,1,
               0,0,1,0,1,0,0,1,1,1,1,0,
               0,0,0,0,0,0,0,0,1,0,0,0,
               0,0,0,1,1,0,0,0,0,0,0,0,
               0,0,0,0,0,0,0,0,0,0,1,0,
               0,0,0,0,0,0,0,1,1,1,1,0};

#include "sprawdz.h"

//...Wyciete....//

void oblicz2()
{
   for(int x=0;x<wys;x++)//
   {
     for(int y=3,t=0;y<4;y++)//szer-1
     {

if(x-1>=0) t+=tab2[x-1][y];
if(x+1<=wys-1) t+=tab2[x+1][y];
if(y+1<=szer+1) t+=tab2[x][y+1];
if(y-1>=0) t+=tab2[x][y-1];
if(x-1>=0 && y+1<=szer+1) t+=tab2[x-1][y+1];
if(x-1>=0 && y-1>=0) t+=tab2[x-1][y-1];
if(x+1<=wys-1 && y+1<=szer+1) t+=tab2[x+1][y+1];
if(x+1<=wys-1 && y-1>=0) t+=tab2[x+1][y-1];

if(t==3) tabtmp[x][y]=1;
if(t==2 && tab2[x][y]==1) tabtmp[x][y]=1;
if(t==2 && tab2[x][y]==0) tabtmp[x][y]=0;
if(t!=2 && t!=3) tabtmp[x][y]=0;
t=0;

if(tabtmp[x][y]!=goodfill[x][y]) goto spierdalaj2;


     }

   }
part3();
spierdalaj2:

}

void part2()
{
 for(int x4=0;x4<0x100;x4++)
 {
  TabBinInc(4);
  oblicz2();
 }
}
void oblicz()
{
   for(int x=0;x<wys;x++)//
   {
     for(int y=0,t=0;y<szer-1;y++)//szer-1
     {

if(x-1>=0) t+=tab2[x-1][y];
if(x+1<=wys-1) t+=tab2[x+1][y];
if(y+1<=szer) t+=tab2[x][y+1];
if(y-1>=0) t+=tab2[x][y-1];
if(x-1>=0 && y+1<=szer) t+=tab2[x-1][y+1];
if(x-1>=0 && y-1>=0) t+=tab2[x-1][y-1];
if(x+1<=wys-1 && y+1<=szer) t+=tab2[x+1][y+1];
if(x+1<=wys-1 && y-1<=0) t+=tab2[x+1][y-1];

if(t==3) tabtmp[x][y]=1;
if(t==2 && tab2[x][y]==1) tabtmp[x][y]=1;
if(t==2 && tab2[x][y]==0) tabtmp[x][y]=0;
if(t!=2 && t!=3) tabtmp[x][y]=0;
t=0;

if(tabtmp[x][y]!=goodfill[x][y]) goto spierdalaj;


     }

   }
part2();
spierdalaj:

}


///////////////////////////
//main.cpp
#include "increment.h"
#include "oblicz.h"

void main()
{
 zeruj();

 for(int x0=0x0;x0<0xFF;x0++)
 {
 TabBinInc(0);
       for(int x1=0;x1<0x100;x1++)
      {TabBinInc(1);
         for(int x2=0;x2<0x100;x2++)
      {TabBinInc(2);
       for(int x3=0;x3<0x100;x3++)
       {TabBinInc(3);
        oblicz();
         }
       }
         }
       }
cout<<endl<<x0<<endl;
 }
}

Na koniec otrzymamy kilka macierzy w "report.txt" jedna z nich to

101110111010
010110000111
011001001100
100001100100
001001100001
000011111000
001000100000
000000011111

Ostatnia kolumna musi zosta podreperowana rcznie [ekhm no gdzie co le zainicjalizowaem pewnikiem] i na koniec, po zmianie 2 bitw mamy nasze ukochane haso.

101110111010
010110000111
011001001101
100001100100
001001100000
000011111000
001000100000
000000011111

serial: 1-`<qa

Na zakoczenie powiem jeszcze, e mona odnale opisan wyej metod hasa dla kilku loopw, nie jest to ju problemem, np. chcc zna potencjalne haso dla 2-xxxxxxxxxxxx wystarczy lekko przeprogramowa nasz program, eby int goodfill zapeniao wypenienie, ktre wanie uzyskalimy, czyli np. zmieniamy goodfill na nasz serial i znowu przepuszczamy przez sito i delektujemy si serialem 2-xxxxxxxxxxxx, ale jak dla mnie strata czasu taka tylko ciekawostka dla maniakw.

contact: lock3r@wp.pl / lock3r@ebolaviruscrew.net / GG:3842885

"I like the things I do, so hurrah for me, and FUCK YOU..."

written @ 23.08.2k3
re-mastered @ 29.08.2k3