
           ܲ   ߲      ߲ 
          ܲ     ۲      
                  ۲   
              ۲  ۲       
         ۲    ۲ ܲ  
          ߲   ߲       ߲   
                      -bHd-
                        +o cybult^2oo2


                          SunnY KeYGeNMe no. #1 by ManSun tutorial


        Cel     : SunnY KeYGeNMe no. #1 by ManSun
        Czym    : SoftICE, IDA
        Opis    : Crackme jest spakowane (FSG v1.2 by bart/xt aka Dulek), pisane
                  w MASM, autor pozwala patchowac Anti-toolsy. Kod nie jest
                  czytelny ze wzgledu na zastosowanie junkow. Skill HARD.

        notice: ustaw sobie czcionke terminal 12 przy czytaniu tego tuta.


        Dzis jest sobota, nareszcie znalazlem chwilke czasu na crackme ManSuna.
        Dosc dlugo sie do niego zabieralem, mialem troszke pracy przy swoich
        projektach, no a poza tym sa wakacje i nie mozna caly czas siedziec przy
        komputerze, heh. No wiec od poczatku.. crackme (a raczej keygenme) jest
        spakowane, po raz kolejny autor crackemsa pomaga sobie tym sposobem, nie
        wiem czy ten zwyczaj nie powinien zniknac, ostatnio widze sporo latwych
        crackme zaszyfrowanych exe-packerami (np. przerobionym PeXem lub Yoda's
        Crypterem, ktorych source jest freeware). O ile jeszcze posiadamy jaka
        taka wiedze na temat unpack-u mozemy sobie poradzic "recznie", w innym
        razie zdani jestesmy na uniwersalne unpackery, np. GUW32. Co zrobic gdy
        zaden sposob nie dziala? To zalezy, jesli crackme spakowane jest jakims
        najnowszym wydaniem PE-Crypt'a albo innym monsterem a reprezentuje skill
        newbies to mozemy pogratulowac autorowi zaradnosci. Ciekawe czy on sam
        zlamalby to crackme, poza tym jaki widzi cel pisania takich potworkow?
        Przeciez taki newbie nie zalozy nawet bpx-a na APIsa, nie wspominajac o
        zobaczeniu kawalka kodu pod SoftICE. Mozna na to wszystko przymruzyc oko
        jesli poziom crackme jest medium lub wyzszy, lamacz potraktuje pakera
        jako wyzwanie i majac juz troche doswiadczenia w crackowaniu sprobuje
        samemu ("recznie") odpakowac/odszyfrowac program, ewentualnie odbudowac
        jego strukture i doprowadzic do stanu uzywalnosci. Nie przesadzajcie
        wiec z tymi pakerami, to nie jest wasza praca i nie wzmacniajcie nimi
        swoich slabych zabezpieczen bo cracker zamiast z waszym niewidocznym
        algo bedzie walczyl z metodami anti autora packera. Wracajac do naszego
        keygnme :).. jest spakowane pakerem, do ktorego w chwili obecnej nie
        istnieje zaden napisany unpacker, kwestia czasu zapewne, ale jakby nie
        patrzec to trzeba sobie radzic samemu.. no chyba, ze odpakowywanie nie
        jest w ogole potrzebne i bedziemy sie bawic on-air ;)... Przypominam o
        nadanym przez autora poziomie crackme, poziomie hard. Sadze, ze to
        usprawiedliwia po czesci zastosowanie packera. Niech mu zreszta bedzie
        hehe, zobaczymy jak zabawa potoczy sie dalej, zaczynamy.

        Uruchom crackme, jesli nie wlaczyles wczesniej FrogsICE lub nie masz w
        pamieci aktywnego ICEDUMPa pokaze sie messagebox z badziewnym textem:

        DEBUGGER has found! You may NOT run SUNNYKEY1.EXE when the SoftIce 
        debugger is loaded, remove SoftIce and reboot. If you still track this
        program when stability system loss balance!

        Hmm, nie znam polnocno koreanskiego, ale chyba prosza nas o wylaczenie
        SoftICE, taki maly szantaz.. inaczej system straci rownowage. To chyba
        jakis kawal, pomyslalem sobie.. przeciez ja nie mam SoftICE :] Hehe...
        nie no az tak zle nie jest z tym crackme ;).. Zobaczmy jaka metoda SI
        zostal wykryty, wystarczy log z froga:

        => Sunnykey    
        ** SOFTICE DETECTION **  code 01, at  016F:00401107     
        Interrupt:03h >eax=00000004h  ebx=00404A9Ch  ecx=00000000h
                       edx=FFFF366Dh  esi=00404647h  edi=00404A4Dh >ebp=4243484Bh
        SEH proc address at cs:00401E6F

        Bylo to INT 3, metoda calkiem skuteczna jesli chce sie zapobiec przed
        stawianiem bpx-ow na adresach w progu jak i APIsach, grr.. nie mamy
        nawet jak spatchowac tego shitu, crackme jest na razie spakowane.. Gdy
        FrogsICE ma ustawiony Hook int3 crackme dziala, icedump calkowicie usuwa
        problem - po jego zaladowaniu wszystko hula jak trzeba.. wykorzystam go
        wiec do odpakowania FSG, to bulka z maslem, popatrzcie tylko..

        Najpierw ustawiam i3here off i faults off w SI.. Uruchamiam ProcDump a
        potem *ProcDump32 - Dump Server*.. zaznaczam funkcje AutoFix PE w bramce
        i odznaczam User Conf.. Teraz ProcDump czeka na sygnal icedumpa, ktorym
        my bedziemy sterowac z poziomu SoftICE.. i tu male przypomnienie,

        1. /BHRAMA ProcDump32 - Dumper Server

           ta komende radze sobie zautomatyzowac wpisem w winice.dat, przydaje sie..

           F3="/BHRAMA ProcDump32 - Dumper Server;"d


        2. /SCREENDUMP screen.txt
                
           screenshot, czy zrzut ekranu po polskiemu :) do pliku
           potrzebny bedzie raczej tylko mi, zeby cokolwiek zobrazowac ;)

        No dobrze, ICEDUMP jest juz zaladowany, Bhrama Server czeka, czas wiec na
        kilka sekund w SoftICE i unpack proga.. W SI poruszam sie tylko F8 ze
        wzgledu na zastosowane w FSG fake calle, ktore wywalaja natychmiast z
        debuggera.. Wszystko postaram sie pokazac na zrzutach..

        A wiec laduje crackme w Symbol Loader.. jestem w entry poincie pakera,
        czyli wirualnym offsecie 409000h,

PROT32
016F:00408FFE  FFFF                INVALID                                                     
016F:00409000  EB01                JMP       00409003      <--- tutaj jestem na poczatku      
016F:00409002  A1428D0580          MOV       EAX,[80058D42]                                     
016F:00409007  90                  NOP                                                          
016F:00409008  40                  INC       EAX                                                
016F:00409009  000F                ADD       [EDI],CL                                           
016F:0040900B  B6D2                MOV       DH,D2                                              
016F:0040900D  68F4000000          PUSH      000000F4                                           
016F:00409012  EB01                JMP       00409015                                           
016F:00409014  8A5EEB              MOV       BL,[ESI-15]                                        
016F:00409017  0271BA              ADD       DH,[ECX-46]                                        
 ==> 0040901A  C1CB1A              ROR       EBX,1A                                             
016F:0040901D  0FBE38              MOVSX     EDI,BYTE PTR [EAX]                                 
016F:00409020  EB02                JMP       00409024                                           
016F:00409022  CD20                INT       20 VXDCall EBFE,2B4B                               
016F:00409028  028CC681EFA331      ADD       CL,[EAX*8+ESI+31A3EF81]                            
016F:0040902F  9D                  POPFD                                                        
016F:00409030  3EC1E318            SHL       EBX,18                                             
016F:00409034  81F7A6D3C7ED        XOR       EDI,EDC7D3A6                                       
016F:0040903A  EB02                JMP       0040903E                                           
016F:0040903C  3A7D83              CMP       BH,[EBP-7D]                                        
016F:0040903F  C74EEB02CD2083      MOV       DWORD PTR [ESI-15],8320CD02                        
016F:00409046  C73EEB02E376        MOV       DWORD PTR [ESI],76E302EB                           
016F:0040904C  33FE                XOR       EDI,ESI                                            
016F:0040904E  80EB3B              SUB       BL,3B                                              
016F:00409051  83C74E              ADD       EDI,4E                                             
016F:00409054  EB02                JMP       00409058                                           
016F:00409056  CD20                INT       20 VXDJmp F72A,7783                                
016F:0040905C  D283C756EB02        ROL       BYTE PTR [EBX+02EB56C7],CL                         
016F:00409062  CD20                INT       20 VXDCall D8BE,0F57                               
016F:00409068  5A                  POP       EDX                                                
016F:00409069  8810                MOV       [EAX],DL                                           
016F:0040906B  EB02                JMP       0040906F                                           
016F:0040906D  385040              CMP       [EAX+40],DL                                        
016F:00409070  80F250              XOR       DL,50                                              
016F:00409073  4E                  DEC       ESI                                                
016F:00409074  EB01                JMP       00409077                                           
016F:00409076  1C85                SBB       AL,85                                              
016F:00409078  F6759F              DIV       BYTE PTR [EBP-61]                                  
016F:00409079  759F                JNZ       0040901A                                (JUMP )  
016F:0040907B  EB01                JMP       0040907E                                        
SUNNYKEY1!.rdata+1FFE

        Nastepnie trace'uje kod do offsetu 409079h gdzie wpisuje w linii komend:
        "g eip+2", czyli "g 40907B".. nieistotne dla mnie rzeczy tutaj sie dzieja wiec
        daruje sobie sledzenie tej petli.. ok, po komendzie G jestem na 40907B i ide 
        dalej.. no a tu prosze.. cala procka depakujaca :).. wcielo mi u gory jedna
        linijke :] ale olac, do edi idzie magiczny adres.. cos on wam mowi? jesli
        nie to nie szkodzi.. ;) jest to adres bufora gdzie zostana odszyfrowane dane z
        tej procedury, warto spojrzec tez co jest pod esi, sama nazwa rejestru cos
        powinna mowic.. Git, analiza zajme sie innym razem, teraz mowie jak ja to
        robie.. otoz wiedzac, ze w edi znajdzie sie kod wykonywalny i od bajtu spod
        adresu 401000h zacznie sie oryginalny entry point zaloze tam pulapke.. po co
        mam czekac az wyjde z tej petli.. logiczne chyba ;] niech dla wygody bedzie
        znowu 'g 401000' zamiast bpx 401000... breakpoint ustawi sobie 0CCh na tym
        offsecie i zmieni nam kod, ktory potem trzeba bedzie modyfikowac, a wiec hop ;]

PROT32
016F:00409085  BF00104000          MOV       EDI,00401000                                      
016F:0040908A  BE20774000          MOV       ESI,00407720                                      
016F:0040908F  53                  PUSH      EBX                                                
016F:00409090  E80A000000          CALL      0040909F                                           
016F:00409095  02D2                ADD       DL,DL                                              
016F:00409097  7505                JNZ       0040909E                                           
016F:00409099  8A16                MOV       DL,[ESI]                                           
016F:0040909B  46                  INC       ESI                                                
016F:0040909C  12D2                ADC       DL,DL                                              
016F:0040909E  C3                  RET                                                          
016F:0040909F  B280                MOV       DL,80                                              
016F:004090A1  33DB                XOR       EBX,EBX                                            
016F:004090A3  A4                  MOVSB                                                        
016F:004090A4  B302                MOV       BL,02                                              
016F:004090A6  FF1424              CALL      [ESP]                                              
016F:004090A9  73F8                JAE       004090A3                                           
016F:004090AB  33C9                XOR       ECX,ECX                                            
016F:004090AD  FF1424              CALL      [ESP]                                              
016F:004090B0  7318                JAE       004090CA                                           
016F:004090B2  33C0                XOR       EAX,EAX                                            
016F:004090B4  FF1424              CALL      [ESP]                                              
016F:004090B7  7321                JAE       004090DA                                           
016F:004090B9  B302                MOV       BL,02                                              
016F:004090BB  41                  INC       ECX                                                
016F:004090BC  B010                MOV       AL,10                                              
016F:004090BE  FF1424              CALL      [ESP]                                              
016F:004090C1  12C0                ADC       AL,AL                                              
016F:004090C3  73F9                JAE       004090BE                                           
016F:004090C5  753F                JNZ       00409106                                           
016F:004090C7  AA                  STOSB                                                        
016F:004090C8  EBDC                JMP       004090A6                                           
016F:004090CA  E843000000          CALL      00409112                                           
016F:004090CF  2BCB                SUB       ECX,EBX                                            
016F:004090D1  7510                JNZ       004090E3                                           
016F:004090D3  E838000000          CALL      00409110                                           
016F:004090D8  EB28                JMP       00409102                                           
016F:004090DA  AC                  LODSB                                                        
016F:004090DB  D1E8                SHR       EAX,1                                              
016F:004090DD  7441                JZ        00409120                                           
016F:004090DF  13C9                ADC       ECX,ECX                                           
016F:004090E1  EB1C                JMP       004090FF                                        
SUNNYKEY1!.rsrc+0085

        Jestem pod adresem 401000, teraz nic tylko wciskam F3 i zapisuje sobie calutki
        odpakowany program do pliku :) A wiec odpakowalem "recznie" crackme.. To bylo
        proste, polecam pobawic sie samemu.. 

        Wypadaloby teraz obejrzec plik pod jakims edytorem plikow wykonywalnych, lub
        jesli ktos woli - hexedytorem.. widac importy, stringi ascii tez.. looknijmy
        how it looks in IDA, poczawszy od entrypoint'u..

                public start
start:
                jmp     short loc_401006
; 
                db  90h
                db 0EAh
                db    2
                db 0ABh
; 

loc_401006:
                call    near ptr unk_40100C
; 
                db 0A2h
unk_40100C      db  83h
                db 0C4h
                db    4
; 
                call    sub_401F9B
                mov     ds:dword_4041DD, esp
                jmp     short loc_40101E
; 
                db 0CDh
                db  20h
; 

loc_40101E:
                push    offset unk_401E6F
                jmp     short loc_401029
; 
                db  90h
                db 0EAh
                db    2
                db    4
; 

loc_401029:
                call    SetUnhandledExceptionFilter
                jmp     short loc_401037
; 
                jmp     far ptr 8EBh:4C4836Bh
; 

loc_401037:
                call    near ptr loc_40103C+1

loc_40103C:
                jmp     far ptr 4041h:0E1A3F3EBh
; 
                db    0
                db  68h
; 
                pop     esi
                inc     ecx
                inc     eax
; 
                db    0
; 
                call    GetModuleHandleA
                mov     ds:hModule, eax
                jmp     short loc_401057
; 
                db 0CDh
                db  20h
; 

        Junki.. smutno mi normalnie, kto widzial kiedys kieygenme z junkami?? Trudno,
        bede musial radzic sobie z takim shitem.. najpierw zobaczmy apisy w tabeli
        importow, co nas czeka...

        TerminateProcess - podejrzewam, ze to jest po to aby kilic jakis util
                           z shitlisty zwlaszcza, ze obok mamy, pare nierozlaczna
        OpenProcess      - czyli: to,
        Process32Next    - to,
        Process32First   - i to ;)

        SetUnhandledExceptionFilter - moglo miec zwiazek z tamtym int 3
                                      do utworzenia handlera (SEH)

        GetProcAddress   - cos chca wywolac bez mojej wiedzy
        CreateThread     - jakis watek, zgadnijcie jaki.. ;)

        _lcreat          - 16bitowa funkcja z win 3.11, moze keyfile a moze
                         - jakis driver dla zmylki, trzeba oblookac...

        ExitWindowsEx    - hehe, ciekawe z jakim paramatrem wywolywane :D

        FindWindowExA    - szuka okien? ja nie mam, all deskami zabite ;)

        GetDlgItemTextA  - standard.. ehh ;/

        GetUserNameA     - lol, beda nas sypac do FBI

        Jeszcze jakies ciekawe importy?? A moze sa ale wywolywane GetProcAddress?
        Looknijmy na stringi, tu tez jes ciekawie..

        CreateToolhelp32Snapshot - \
        Process32First           -  > i to ma byc konspiracja?? ;)
        Process32Next            - /

        kernel32.dll     - a po co to? ;]
        user32           - j.w. tylko gdzie rozszerzenie sie podzialo??
        
        frog             - moze good password? eee, to nie delphi :D
                           to co cos probuje wykryc froga, ciekawe jak? ;)

        error!           - czyzby nazwa crackme? ;]]

        exception has occured, the program will destroyed! - koreanski ;P

        
        Thanks for registration!        - to pewnie goodboy, albo jakis fake!
        Please restrat this program!    - znowu koreanski ;)

        REGISTERED!                 \
        U-N-R-E-G-I-S-T-E-R-E-D      > moze maly bpm na adresy do tych stringow? ;)
        GetDlgItemTextA             /

        Te stringi u dolu to z pewnoscia shitlista wykorzystywana w watku
        szukajacym "not allowed tools" przez FindWindowExA
        ;---------------------------------------------------------------
        ProcDump32 (C) 1998, 1999, 2000 G-RoM, Lorian & Stone
        URSoft W32Dasm Ver 8.93 Program Disassembler/Debugger
        TRW2000 for Windows 9x
        [ LordPE RoyalTS ] by yoda
        file insPEctor XL
        SoftICE Symbol Loader
        ;---------------------------------------------------------------

        Tyle widac.. teraz czas na odpalenie crackme.. Na wszelki wypadek
        zapisz i pozamykaj wszystkie wazne pliki, dokumenty, itd. bo nie
        wiadomo co to crackme zrobi jak zobaczy crackera ;) Bywa roznie,
        odpal wiec programik i oblookaj co tam napisali..

        Wow.. wiedza jak sie nazywamy.. u gory jest nasz nick.. wpisze teraz
        jakis ciulowaty serial i zobacze czy wygralem milion baksuf.. Hy?

        Thanks for registration!
        Please restrat this program!

        Co, koniec? Klikam na Ok.. MessageBox sie zamyka a na pasku statusu
        widnieje napis rozwiewajacy moje naiwna wiare w cud.. huh.. Czyli
        musze jeszcze raz uruchomic crackme, dobra.. wiec tak robie.. Pyk,
        pyk i znow otworzylem crackme.. na statusie nic nie pisze.. heh a
        moze pisze REGISTERED! tylko jakims kurde podczerwonym swiatlem ;)
        w koncu zarejestrowam crackme, ladnie mi podziekowali.. Widzialem
        w importach kilka APIsuf z gdi32.dll.. moze to jakis nowy efekt 
        graficzny.. hehe, taa.. mozna sobie pomarzyc :D.

        Czas na sledzenie pod SI.. Ja zaczynam je zwykle od wywalania lub
        sprawdzenia istniejach watkow, teraz tez zaczne poniewaz widze,
        ze po zalaczeniu crackme, procesor jest uzywany w 80%.. na pewno
        Sleep jest za maly albo nie ma go w ogole ;) Denerwuje mnie to..
        zamykam crackme, bpx CreateThread, odpalam je i jestem tutaj:
        (lol! zadnych junkow???).. zaraz to wykorzystamy.. ;)

PROT32
016F:0040124D  50                  PUSH      EAX                                               
016F:0040124E  6A01                PUSH      01                                                
016F:00401250  6880000000          PUSH      00000080                                           
016F:00401255  FF7508              PUSH      DWORD PTR [EBP+08]                                 
016F:00401258  E83D0F0000          CALL      USER32!SendMessageA                                
016F:0040125D  686E494000          PUSH      0040496E                                           
016F:00401262  68EF484000          PUSH      004048EF                                           
016F:00401267  E8460F0000          CALL      ADVAPI32!GetUserNameA                              
016F:0040126C  68EF484000          PUSH      004048EF                                           
016F:00401271  6A0F                PUSH      0F                                                 
016F:00401273  FF7508              PUSH      DWORD PTR [EBP+08]                                 
016F:00401276  E82B0F0000          CALL      USER32!SetDlgItemTextA                             
016F:0040127B  B87C1D4000          MOV       EAX,00401D7C                                       
016F:00401280  68E6484000          PUSH      004048E6                                           
016F:00401285  6A00                PUSH      00                                                 
016F:00401287  6A00                PUSH      00                                                 
016F:00401289  50                  PUSH      EAX                                                
016F:0040128A  6A00                PUSH      00                                                 
016F:0040128C  6A00                PUSH      00                                                 
016F:0040128E  E8470E0000          CALL      KERNEL32!CreateThread                              
016F:00401293  50                  PUSH      EAX                                                
016F:00401294  E83B0E0000          CALL      KERNEL32!CloseHandle                               
016F:00401299  5E                  POP       ESI                                                
016F:0040129A  5F                  POP       EDI                                                
016F:0040129B  5B                  POP       EBX                                                
016F:0040129C  C9                  LEAVE                                                        
016F:0040129D  C21000              RET       0010                                               
016F:004012A0  0FB74510            MOVZX     EAX,WORD PTR [EBP+10]                              
016F:004012A4  6683F80E            CMP       AX,0E                                              
016F:004012A8  7421                JZ        004012CB                                           
016F:004012AA  6683F810            CMP       AX,10                                              
016F:004012AE  7431                JZ        004012E1                                           
016F:004012B0  6683F80C            CMP       AX,0C                                              
016F:004012B4  0F848F000000        JZ        00401349                                           
016F:004012BA  6683F80D            CMP       AX,0D                                              
016F:004012BE  0F84D2010000        JZ        00401496                                           
016F:004012C4  5E                  POP       ESI                                                
016F:004012C5  5F                  POP       EDI                                                
016F:004012C6  5B                  POP       EBX                                                
016F:004012C7  C9                  LEAVE                                                       
016F:004012C8  C21000              RET       0010                                            
UN!.text+024D

        Na samym poczatku jestem pod 401293h, czyli watek juz dziala ;/, ciekawe ile
        ich jest.. wciskam F5..nic.. czyli watek jest jeden.. adres procedury, ktora
        wykonuje watek latwo wylookac wyzej (401D7Ch).. wiec bpx na ten offset.. F5,
        SoftICE pojawia sie jeszcze raz (ciekawe czy autor dal jakis anti-bpx, no bo 
        jak na razie - nic na to nie wskazuje). I co mamy? :) FindWindowExA, no i 
        zupelnie tak jak myslalem.. watek wykonuje sie bez ani jednego Sleep-a, huh
        i tak guzik daje ta procka (hmm.. mysle, ze wszystkie okienka masz juz od
        poczatku spatchowane.. sorry, powinienem ci wczesniej o tym wspomniec..)..
        Ja ta procke musze zabic.. jak? proste.. jest tam jeden ret.. w sumie kto go
        tam wsadzil to ja niewiem ;].. wystarczy wrocic watek do callbacku.. albo
        zabobiec inicjacji watku.. ja decyduje sie na to drugie, bo nie chce mi
        sie znowu wklejac tutaj tych shitowych screenow z icedumpa.. ;)

        a wiec najlepiej zaraz po SetDlgItemTextA zrob reta, ale ret'a 10h, czyli

        0000087B:  5E                             pop       esi
        0000087C:  5F                             pop       edi
        0000087D:  5B                             pop       ebx
        0000087E:  C9                             leave
        0000087F:  C21000                         retn      0010

        hmm, pytasz sie dlaczego w ten sposob? otoz jesli na poczatku tego calla
        jest taki oto kod,

        push    ebp
        mov     esp, ebp
        push    ebx
        push    edi
        push    esi

        to musimy na koncu to wszystko zdjac ze stos,

        leave to 3 instrukcje w jednej:

        mov esp, ebp
        pop ebp
        
        no i ret
        
        Olac, w kazdym badz razie zrob jak mowie, to najprostszy sposob aby ten
        pozeracz zasobow nie uruchamial sie.. Ja takie rzeczy robie w BIEW, jak
        sie domyslam ty pracujesz na HIEW, wszystko wyglada tak samo, wiec nie
        powinno byc problemow ze zrozumieniem, nevermind.. lecimy dalej..

        Blah.. crackme is dead.. wyjatek.. nie martw sie, wszystko zrobiles jak
        trzeba.. moje crackme tez jest zepsute.. czyzbysmy zle spatchowali to
        crackme? Na probe sledzilem faults off-em.. nic z tego, wynik ten sam..
        Zaladowalem crackme do Symbol Loadera i spojrz co znalazlem zaraz na
        poczatku kodu programu,

loc_401FC2:
                mov     ecx, 10CBh
                mov     eax, 0FFFFFFFFh
                mov     edx, eax

loc_401FCE:
                push    ecx
                xor     ebx, ebx
                mov     bl, [edi]
                inc     edi
                xor     bl, al
                shl     bx, 1
                shl     bx, 1
                add     ebx, esi
                mov     cx, [ebx+2]
                mov     bx, [ebx]
                mov     al, ah
                mov     ah, dl
                mov     dl, dh
                xor     dh, dh
                xor     ax, bx
                xor     dx, cx
                pop     ecx
                loop    loc_401FCE
                not     ax
                not     dx
                push    dx
                push    ax
                pop     eax
                mov     ebx, offset unk_404A9C
                push    eax
                jmp     short loc_402010
        
        Jest to procedura liczaca CRC-32 pliku, wyrippowana co do bajta z ksiazki
        Pavola Cervena, ten ostatni jump dotrze do porownania typu,

loc_402010:
                cmp     [_correctCRC], eax      ; w eax obliczona suma kotrolna
                jnz     _spowoduj_exc           ; wymuszenie fake error
                jmp     _wszystko_ok            ; suma ok, wiec kontynuuj program..
        
_spowoduj_exc:
                int     1h                      ; exception!
                invoke  ExitProcess, -1

        Pomysl sprawdzanie poprawnej sumy kontrolnej nie jest bynajmniej zly, ale
        to wykonanie bylo latwo udaremnic.. Procka ta jak wiadomo musiala byc poza
        zasiegiem liczenia crc, spokojnie wiec mozna ja bylo namierzyc.. bardziej
        efektywne byloby monitorowanie na bierzaco tablicy importow - tam crc jest
        stale pod warunkiem, ze nie postawilismy zadnego breakpointa na API.. To
        naprawde dziala niezawodnie i daje niezle rezultaty.. Druga sprawa, to ta
        konsekwentna reakcja - spowodowanie wyjatku.. chyba lepszy rezultat bylby
        gdyby crackme po wykryciu zlej sumy kontrolnej modyfikowalo jakies wazne 
        przy rejestracji dane (wartosci tablic, stringi, nawet kod). Wtedy ciezko
        mielibysmy z namierzeniem tego crc-checka, a tak.. 20 sekund i po crc!

        Warunkowy skok (good/bad CRC) jest pod offsetem 402053h, wystarczy tylko
        zamienic go na jmp+0 i crackme dziala (spatchowane i bez watku :D)

        W referencjach tego _correctCRC znalazlem kilka wartosci m.in. unk_404A98,
        ktora to jest sprawdzana po kazdym wcisnieciu przycisku Check i jest to
        wskaznik bezposrednio zwiazany z crc.. troche ciezko sie polapac w tych
        kilometrach junkow i nie wnikam co, jak i gdzie.. w kazdym razie pod
        offsetem 40136Bh skok musi nastapic, inaczej ExitProcess.. btw: bardzo mi
        sie podoba ten check, co prawda tez na wierzchu ale sprytnie..
        
        Majac teraz swiety spokoj oraz zimny procesor zajmijmy sie wreszcie tym,
        o co pyta program.. znalezieniem danych rejestracyjnych. Zaloz wiec bpx
        na GetDlgItemTextA (wczesniej, przy analizie importow crackme ta funkcja
        sie pojawila, wiec mozemy sprobowac).. Wpisz seria... Hmm.. crackme sie
        zamknelo.. Pewnie anti-bpx :D nareszcie jest z czym troche powalczyc ;)
        Pewnie autor pozwalajac na patchowacnie anti-something mial tez na mysli
        tego anti-bpxa.. Coz, my poradzimy sobie bez tego.. uzyjemy HMEMCPY.. :)
        Sciagamy tego niefartowego bpx na GetDlgItemTextA przez bc*, wpisujemy
        jakis serial, ustawiamy bpx hmemcpy, nastepnie klikamy.. heh serial jest
        pobierany bez przycisku Check.. sprawdzmy to wchodzac do procki.. tam
        (401337h) 2 junki a potem (4016BFh) calkiem czysty i przyjemny kod.. 

        sub_4016BF      proc near               ; CODE XREF: .text:0040133Dp

                test    eax, eax
                jz      locret_40177D
                cmp     eax, 24                 
                jnz     locret_40177D
                xor     esi, esi
                mov     edi, offset unk_4049C4
                mov     eax, [esi+edi]
                add     esi, 4
                xor     eax, 20202020h
                add     eax, 0BADBADh
                rol     eax, 2
                cmp     eax, 50109085h
                jnz     locret_40177D
                mov     ebx, [esi+edi]
                inc     esi
                sub     ebx, 20202020h
                inc     esi
                ror     ebx, 3
                inc     esi
                xor     ebx, 12345678h
                inc     esi
                sub     ebx, 191C7C98h
                jnz     short locret_40177D
                mov     ecx, [esi+edi]
                add     esi, 2
                bswap   ecx
                add     esi, 2
                add     ecx, 87654321h
                sub     ecx, 11111111h
                sub     ecx, 96BDA530h
                jnz     short locret_40177D
                mov     edx, [esi+edi]
                xor     edx, eax
                rol     edx, 3
                cmp     edx, 82A68E3Bh
                jnz     short locret_40177D
                add     esi, 4
                mov     eax, [esi+edi]
                inc     esi
                rol     eax, 1
                inc     esi
                xor     eax, 0ABCDEFh
                cmp     eax, 0D8EB9F99h
                jnz     short locret_40177D
                add     esi, 2
                mov     ebx, [esi+edi]
                add     ebx, 200020h
                ror     ebx, 2
                sub     ebx, 5C995B58h
                jnz     short locret_40177D
                jz      short locret_40177D
                int     19h                             ; causes reboot of disk system
                push    offset unk_4048A6
                call    MessageBoxA

        locret_40177D:

                retn

        sub_4016BF

        Po pieciu sekundach wiemy, ze ta procka nic nie robi i jest bez sensu, MessageBox
        raczej nic nam tu nie pokaze.. wow!, zaczyna mi sie podobac ta cala zabawa ;)
        Czyli pobieranie textu poprzez kliniecie na edit jest dla picu.. nie robi nic..
        Klikamy na Check majac zalozona pulapke hmemcpy.. ladujemy pod sub_40177E.. tam
        procka.. nie bede jej tu nawet wwalal.. jest dluzsza niz poprzednia mimo, ze
        spelnia podobna funkcje.. nie robi nic.. chyba tylko tyle, zamienia nasz nick
        na uppercase i kopiuje go razem z serialem pod inne offsety.. czyli kolejny fake.
        Na koncu tego badziewia jest wyswietlany msbox z dzienksami za rejestracje i
        ustawiany status na U-N-R-E-G-I-S-T-E-R-E-D ! Czyli to tez nie tutaj.. Moze
        to inny przycisk, np. jak w "moo me" ToMKoLa (yo!) bedzie to About Button??
        Mozna sprobowac.. (mozna tez bpm na tamte skopiowane dane do bufforow)

        bc*
        cls
        [lyk tej herbatki z niebieskiego kubka po lewej ;]
        hwnd - wyswietla informacje o uchwytach
        szukamy #32770 (Dialog) w takim procesie jaki u nas ma nazwe crackmesa
        zapamietujemy (np. C4F)
        stawiamy pulapke na wiadomosc WM_COMMAND
        bmsg C4F wm_command

        klikamy na przycisk About.. potem do skutku F10 az dojdziemy do strony
        naszego proga.. a tam cala obsluga wm_command.. hmm.. ciekawe..

        
loc_4012A0:
                movzx   eax, word ptr [ebp+10h]
                cmp     ax, 0Eh
                jz      _exit
                cmp     ax, 10h
                jz      short loc_4012E1
                cmp     ax, 0Ch
                jz      loc_401349
                cmp     ax, 0Dh
                jz      _about
                pop     esi
                pop     edi
                pop     ebx
                leave
                retn    10h

        A tu blah! Podczas lookania referencji _exita znalazlem takie cos, zaloze sie,
        ze tutaj ManSun schowal procke sprawdzajaca poprawnosc seriala.. jesli tak, to
        zeby ja uruchomic trzeba wcisnac przycisk 'eXit' na dialogu..

_exit:
                call    sub_4019FE

        W tym cally cos sie dzieje z naszymi danymi.. mozna latwo poznac po offsetach,
        ale co ja wam bede sciemnial.. bpx na ten adres.. na poczatku jeszcze w miare
        czytelnie, potem zaczyna sie seria junkow.. proponuje wynopowac je recznie pod
        hiewem, nie sa skomplikowane bo ich budowa wyglada mniej wiecej tak,

                        call    _shit
        _popek:
                        add     esp, 4
                        jmp     _kod
        _shit:
                        jmp     _popek

        _kod:
                        ...
                        ...

        Latwo to wysledzic i zlikwidowac, po tym zabiegu IDA juz wszystko rozumie ;) i
        mozna w niej ladnie wylistowac ta procke.. gdy juz uda ci sie pozbyc tych tego
        szajsu przygladnij sie uwaznie co ona robi.. mysle, ze wszystko juz wiadomo :)
        Tutaj powstaje serial "lekko kopniety" :P, bo trzeba go tylko potraktowac xorem
        i addem co widac w nastepnym callu.. call ten "wyposoazono" w w kilka procedur
        anti-F8 i jesli bedziemy trace'owac w nim kod pod SoftICE to takie cos:

                mov     eax, offset _wynik
                push    eax                             <--*

        powtorzy sie kilkakrotnie co w rezultacie spowoduje zawieszenie sie systemu,
        bo kilka push-y zostanie nie zdjetych ze stosu.. tak wiec wylookac radze co
        w tym callu jest napchane, junki to wiadomo, ale co oprocz tego.. ;)

        W zwiazku z tym, ze nie trzeba niczego odwracac zbedna jest analiza tego co
        sie tam dzieje. Ja sobie w pare sekund wycialem kod z IDA i wwalilem w keygena
        co zaowocowalo wygenerowaniem s/n dl mojego nicka,

                Registration NAME: cybult
                Registration  KEY: ]lbb]LB]BwaC
                
        Wszystko widac tam jak na dloni, serial jest caly czas mielony stringami, wiec
        nawet trudno sie zgubic w sledzeniu, a oto procka keygena..

###############################################################################################
_format         db      '%d',10 dup (0)

_name           db      64 dup (0)
_wynik          db      54 dup(0)
_serial         db      50 dup (0)
_buffer         db      101 dup(0)
_repeclean      equ     ($-_name)/4

_magic_fuck     db 2Dh, 40h, 21h, 46h, 55h, 43h, 4Bh, 4Fh, 2 dup(46h)
                db 48h, 62h, 76h, 6Eh, 63h, 39h, 30h, 38h, 20h, 2Ah, 26h
                db 29h, 35h, 20h, 66h, 6Ah, 64h, 30h, 39h, 35h, 6Ah, 39h
                db 30h, 6Bh, 63h, 66h, 20h, 6Ah, 61h, 25h, 4Ah, 4Bh, 65h
                db 53h, 46h, 41h, 4Bh, 44h, 4Ah, 53h, 4Ch, 4Ah, 67h, 4Ah
                db 44h, 46h, 20h, 32h, 6Bh, 33h, 34h, 6Ch, 73h, 64h, 6Ah
                db 66h, 6Bh, 6Ch, 64h, 6Ah, 66h, 20h, 6Bh, 64h, 72h, 74h
                db 79h, 2 dup(5Ch), 2Eh, 5Ch, 53h, 49h, 43h, 45h, 3Bh
                db 6Ah, 61h, 66h, 64h, 6Bh, 6Ch, 3Bh, 67h, 6Ah, 61h, 73h
                db 64h, 6Bh, 6Ch, 3Bh, 72h, 35h, 36h, 38h, 72h, 3Bh, 6Ah
                db 76h, 2 dup(67h), 66h, 6Ch, 3Bh, 6Bh, 64h, 34h, 75h
                db 69h, 38h, 33h, 32h, 37h, 34h, 2 dup(20h), 76h, 6Ch
                db 6Bh, 6Ah, 66h, 64h, 6Ch, 6Bh, 3Bh, 73h, 66h, 6Ah, 67h
                db 6Bh, 6Ch, 66h, 64h, 67h, 6Ah, 6Ch, 65h, 6Ah, 74h, 30h
                db 2 dup(5Ch), 2Eh, 5Ch, 53h, 49h, 57h, 56h, 49h, 44h
                db 0, 2 dup(5Ch), 2Eh, 5Ch, 53h, 49h, 57h, 56h, 49h, 44h
                db 0
_magic2         db 6Bh, 4Bh, 60h, 40h, 5Eh, 3Eh, 64h, 44h, 6Ah, 4Ah, 71h
                db 51h, 60h, 40h, 6Bh, 4Bh, 60h, 40h, 61h, 41h, 0, 5Ah
                db 46h, 47h, 3Eh, 4Bh, 3Ch, 51h, 50h, 49h, 3Ch, 51h, 44h
                db 46h, 47h, 4Ah, 0FCh, 0FDh, 74h, 46h, 50h, 0FDh, 3Ch
                db 4Bh, 40h, 0FDh, 5Eh, 2 dup(66h), 61h, 0FDh, 3Ah, 4Bh
                db 3Ch, 3Ah, 42h, 40h, 4Bh, 0FDh, 13h, 8, 4, 0


_keygen:
                mov     ecx, _repeclean
                sub     eax, eax
                lea     edi, _name
                cld
                rep  stosd

                push    40
                push    offset _name
                push    EDIT1_ID
                push    hWnd
                call    GetDlgItemTextA

                push ebp

                lea     ebx, _name
                mov     ecx, 159
                mov     edi, 10F9A8h                            ; wynik procki z wczesniej..
                sub     esi, esi
                mov     ebp, eax
_jeszcze:
                mov     eax, esi
                cdq                                             ; xor edx, edx ?
                div     ecx
                movsx   eax, byte ptr (_magic_fuck+1)[edx]
                movsx   edx, byte ptr [ebx+esi]
                imul    eax, edx
                add     eax, edi
                xor     edx, edx
                mov     edi, 4000000000
                div     edi
                inc     esi
                cmp     esi, ebp
                mov     edi, edx
                jl      _jeszcze

                pop     ebp

                push    edi
                push    offset _format  ; "%d"
                push    offset _serial
                call    wsprintfA
                add     esp, 12

                cmp     eax, 5                  ; wsprintfA zwraca dlugosc ascii-z w eax
                jl      _bye
                mov     ecx, eax

                sub     eax, eax
                sub     edi, edi
                lea     esi, _serial

_sumuj:
                lodsb
                add     edi, eax
                loop    _sumuj

                mov     ecx, 123
                mov     eax, edi
                cdq
                idiv    ecx
                mov     edi, edx
                xor     ebx, ebx
                lea     eax, _serial
                lea     edx, _name
                lea     esi, _magic2

_below:
                movsx   ecx, byte ptr [edx]
                add     ecx, edi
                mov     dword ptr [eax], ecx
                cmp     ecx, 255
                jle     _malo
                xor     ecx, ecx
                mov     dword ptr [eax], ecx

_malo:
                inc     ebx
                add     eax, 4
                inc     edx
                cmp     ebx, 5
                jl      _below

                mov     dword ptr [eax], edi
                sub     ebx, ebx
                mov     eax, offset _wynik
                mov     edx, eax
                lea     eax, offset _serial

_not_yet:
                mov     ecx, dword ptr [eax]
                test    ecx, ecx
                jns     _plus
                add     ecx, 15

_plus:
                sar     ecx, 4
                mov     cl, byte ptr [esi+ecx]
                mov     byte ptr [edx], cl
                mov     ecx, dword ptr [eax]
                and     ecx, 8000000Fh
                jns     _jmpek

                dec     ecx
                or      ecx, -10
                inc     ecx
_jmpek:
                mov     cl, [esi+ecx]
                mov     [edx+1], cl
                inc     ebx
                add     edx, 2
                add     eax, 4
                cmp     ebx, 6
                jl      short _not_yet

                lea     esi, _wynik
                mov     edi, esi
                sub     eax, eax
                cdq
                push    12
                pop     ecx
_last:
                lodsb
                xor     al, 35
                sub     al, 6
                stosb
                dec     ecx
                jnz     _last
                sub     al, al
                stosb
        
                push    offset _wynik

                push    EDIT2_ID
                push    hWnd
                call    SetDlgItemTextA
_bye:
                ret                        
###############################################################################################

        Jasne jak slonce.. jak Sunny KeygenMe.. Crackme zlamane.. hmm teraz mozna sie
        zastanowic czy jego poziom hard nie jest "lekko" przesadzony.. wydaje mi sie,
        ze jest, chyba crackme bylo pisane pod katem ukrycia procedurki spawdzajacej
        serial i cala "moc" tego crackme miala zgasnac gdy uda sie na ja znalezc.. no
        a moze niepotrzebnie sugerujemy sie tym HARD.. w koncu tam jest tez "maybe"..
        A wiec "Let It May Be Hard".. Autor zyczy ciezkich matur maturzystom, hehe...

        Skill jak dla mnie light easy (3/10), gdyby nie te junki to newbies (2/10),
        przy okazji pokazalem prosta metoda unpacku FSG.
        Po slonecznym keygenme (w sloneczny dzien) pojde sobie na Sloneczny Patrol ;).

        pozdrawiam tomkola, kwaska, witka g, cyberboba, shielda, tnb!, virsa, hintusa.

        27 lipca 2002

        cybult
        cybult@poczta.onet.pl
