VirS vs. FightMe 1.0 by JuBE

Witam wszystkich dnych zamania FightMe 1.0 by JuBE.
                                  ~~~~~~~~~~~~~~~~~~~
Ten crackme nie jest az tak bardzo skomplikowany, chocia mimo wszystko 
newbies bym go nie poleca. Mimo tego bede prawie wszystko opisyw do
dokadnie czasem az za dokadnie ;)
Sorry za literwki, ogonki itd. - nie bedzie korekty po napisaniu


Co nam bedzie potrzebne:
1. IDA - ja uywam 4.04 ale moe by 3.8
2. ProcDump
3. ExeScope
4. Mozg i troche wolnego czasu

Wstp.
------

Fightme jest spakowany UPX v. 0.71-0.72 [jak si chcesz tego dowiedziec to polecam
File Analyzer v 1.6] - trzeba go rozpakowa. Nie bd opisywa procesu rozpakowywania
ani przystosowywania FightMe do ogldania w IDA bo doskonale zrobi to W!K0 w tutorze
pod tytuem "..:: ReKompilacja programu ::.. czesc #2" dostpnym na 
http://jube.fm.interia.pl/.

Chciabym do razy zauway, e w kodzie ktry bd pokazywa mog by troche inne
offsety zmiennych, bufferw itd. tz. jak widzisz u siebie zmienn o adresie 00402034 to
u mnie bedzie to 00403034, jest tak dlatego, e ja w tej chwili operuje na kodzie,
ktry powsta ju po ponownej rekompilacji. Aby byo atwiej, przynajmniej mnie ;),
w wiekszosci zmnieniem etykiety w IDA na nazwy ktre latwiej jest czyta.

Przechodzimy do rzeczy.
-----------------------

jak widzisz na pocztku jest co takiego:

00401000 start           proc near
00401000                 mov     oldESP, esp
00401006                 push    offset loc_401046
0040100B                 call    j_SetUnhandledExceptionFilter
00401010                 mov     ebp, 4243484Bh
00401015                 mov     eax, 4
0040101A                 int     3               ; Trap to Debugger
0040101B                 jmp     short loc_401041


Jest to dobrze znana sztuczka na wykrycie debuggera. Dziaa ona nastpujaco:
1. dzieki SetUnhandledExceptionFilter stawiany jest handler obsugi wyjtkw,
nie wiem czy musze wyjani co to s  wyjtki, na wszelki wypadek: 
wyjtkiem jest np: bd dzielenia przez zero, zapis/odczyt do niedozwolonego miejsca
pamici, int 3 czyli puapka debuggera itd. Handler to fragment kodu ktry ma co
poradzi w przypadku wystpienia jakiego wyjtku, jak go nie postawisz to obejrzysz
licznie okienko o treci co jakby tak: "Program wykona niedozwolon operacje i zostanie
zakoczony jeeli problem bedzie si powtarza..." W naszym przypadku ten handler ma adres
401046. Trzeba ci jeszcze wiedzie e windowz jak zobaczy int 3 zachowuje si tak:
szuka czy w pamici jest jaki debugger (np SoftIce) jeeli tak to zwraca mu kontrole,
jak nie ma to sprawdza czy pogram postawi handlera na wyjtki, jezeli tak to przenosi si
pod jego adres, jak nie postawi to wywietla okienko ktre ju opisywaem i koczy 
program. Uwaga !!! w koncu dochodze do rzeczy ;) W chwili kiedy masz wczonego SoftIca
lub inny debugger to wykona si skok pod 0040101B ktry jak pewnie zauwazye prowadzi 
prosto do wyjcia z programu, jeeli jeste grzeczny i nie prbujesz debuggowa 
programu to on si przeniesie pod adres 401046. Mam nadzieje e jasne.
Idziemy dalej, nasz handler to kod:

00401046 loc_401046:                            
00401046                 mov     esp, oldESP
0040104C                 push    offset loc_40101D
00401051                 retn

Nie wiem czy wiesz ale jak przed ret wrzucisz co na stos to bedzie to adres pod ktry
si przeniesiesz jak przejdziesz przez ten ret.
loc_40101D to u nas kod tworzcy DialogBox pod 0040102B masz wrzucony na stos adres
procedury obsugi naszego Dialog'a tam te si udamy:

004010CC                 enter   0, 0
004010D0                 push    ebx
004010D1                 push    edi
004010D2                 push    esi
004010D3                 cmp     [ebp+uMsg], 2   ; WM_DESTROY
004010D7                 jz      short loc_4010FA
004010D9                 cmp     [ebp+uMsg], 10h ; WM_CLOSE
004010DD                 jz      short loc_4010FA
004010DF                 cmp     [ebp+uMsg], 111h ; WM_COMMAND
004010E6                 jz      short WhatPushed
004010E8                 cmp     [ebp+uMsg], 110h ; WM_INITIALDIALOG
004010EF                 jz      short InitDialogProc ; tu !!! 

Widzisz tutaj adresy pod ktre udaje si nasz program jeeli wystpi pewne okolicznoci
np jak tworzymy DialogBox to zostaje wysana przez Windowz do naszego programu wiadomo
WM_INITIALDIALOG popatrzymy sobie co te nasz FightMe wyprawia jak si tworzy, skocz sobie
pod ten adres ktry ja nazwaem "InitDialogProc" widzisz tam pare operacji ktre nas 
rednio obchodz np. ustawianie ikony, co interesujcego zaczyna si dopiero przy:

004011D8                 mov     ebx, offset flagaD
004011DD                 push    [ebp+hWnd]
004011E0                 pop     _hWnd
004011E6                 push    ebx
004011E7                 push    0
004011E9                 push    3
004011EB                 push    0
004011ED                 push    0
004011EF                 push    0
004011F1                 push    0
004011F3                 push    offset a_Sice   ; Czy jest SICE?
004011F8                 call    j_CreateFileA
004011FD                 cmp     eax, 0FFFFFFFFh
00401200                 pop     ebx
00401201                 jz      short findSICE2 ; jak nie ma to skok
00401203                 mov     ecx, 1          ; jak jest to ecx=1
00401208                 mov     [ebx], ecx      ; flagaD = 1

to co sobie nazwae flagaD bedzie informowao program czy s jakie nie podane
programu w pamici, np SoftIce. Widzisz tutaj e jeeli jest znaleziony jego sterownik
to do flagi trafia warto 1, jak nie ma to szukamy dalej. Nie chce mi si wszystkiego 
opisywa bo to chyba nie ma sensu. Powiem tylko e szukamy prcz SI jeszcze TRW2000  i 
sprawdzamy czy jest w podku IDT (interrupt descriptor table) [jak nie wiesz co to, 
to przeczytaj sobie manual do Pentium :P] - SoftIce robi tam baagan.
Dobra skoczylimy tworzenie Dialog'a to moemy si zaj obsyg przyciskw. Wr pod
adres 004010E6 jak co przyciniete to ten skok si, wykonuje mamy wic:

00401108 WhatPushed:                             
00401108                 cmp     [ebp+wParam], 0Ah
0040110C                 jz      short AboutProc ; jak about to skok
0040110E                 cmp     [ebp+wParam], 1
00401112                 jz      short OkProc    ; jak OK to skok
00401114                 pop     esi
00401115                 pop     edi
00401116                 pop     ebx

Mam nadziej e wiesz ale gdyby jednak nie to wiemy e 0Ah to ID about bo moemy
to sprawdzi w pliku zasobw ktry utworzylimy sobie ExeScope'm ( mam nadzieje ze 
przeczytae ten Tutor o rekompilacji !!!)
Dobra lecimy do OkProc:

00401136 OkProc:                                
00401136                 mov     edx, flagaD
0040113C                 cmp     edx, 0
0040113F                 jz      short loc_40114D ; nie byo debuggerow to skok
00401141                 call    FakeDebug
00401146                 pop     esi
00401147                 pop     edi
00401148                 pop     ebx
00401149                 leave
0040114A                 retn    0Ch

Jak widzisz nasz FightMe sprawdza tutaj, czy byy jakie debuggery wtedy kiedy sie 
uruchamia jak tak to idziemy prosto do faszywej procki sprawdzajcej co wpisae ;)
Jak odwrcisz jej algorytm, to otrzymasz info e nie Debugger wykryty, chyba si nie 
opaca ;). Dobra u nas nie ma debuggerw bo my nie jestemy jakimi wstrtnymi crackermi
afuj ;)) lecimy wiec pod loc_40114D tam do razu jest call w ktry wchodzimy i widzimy co
takiego:

0040137B Step1           proc near              
0040137B                 push    28h
0040137D                 push    offset KeyBuffer ; nasz buffer na Key
00401382                 push    69h      ;ID key
00401384                 push    _hWnd
0040138A                 call    j_GetDlgItemTextA ; co w key?
0040138F                 cmp     eax, 0
00401392                 jz      short step2     ; !!!
00401394                 cmp     eax, 0Eh
00401397                 jnz     short step2     ; !!!
00401399                 call    sub_401531
0040139E                 retn
 
To moe ci troch zmyli, pewnie bye przyzwyczajony (ja byem) ze jak program
zprawdza dugo czego a pniej porwnuje to z 0 to zaraz po tym jest skok do 
info o niepowodzeniu. Tutaj jest troche inaczej skok ma by pod step2 czyli
dugo twojego Key nie moe by rwna 0Eh !!! Jeste moe ciekaw co to za call?
On prowadzi do drugiej juz faszywej procedury, tym razem otrzymasz info o 
tresci "Fake, Sorry..." czy jakos tak, ten tekst jest zaszyfrowany, napisaem
co co mi to rozszyfrowo ale nigdzie nie zapisem wiec ju dokadnie nie
pamietam. 
Dobra wiadomo ju wiecej nie ma fake procek. Teraz tak naprawde bedziemy ama
nasze FightMe. Pod step2 jest skok do czegos co nam skopiuje key do jeszcze jednego 
buffera.

004013B0 KeyCopy         proc near               
004013B0                 mov     esi, offset KeyBuffer
004013B5                 mov     edi, offset keybuff2
004013BA 
004013BA loc_4013BA:                             
004013BA                 mov     bl, [esi]
004013BC                 cmp     bl, 0
004013BF                 jz      short step3     
004013C1                 mov     [edi], bl
004013C3                 inc     edi
004013C4                 inc     esi
004013C5                 jmp     short loc_4013BA 


Chyba specjalny opis nie jest potrzebny, jak ju skopiowane idziemy pod step3:

004013C7 step3:                                  
004013C7                 xor     eax, 7BFh       ; ???
004013CC                 add     eax, 6
004013CF                 xor     eax, 0D80h
004013D4                 sub     eax, 3
004013D7                 inc     eax
004013D8                 dec     ecx
004013D9                 rol     eax, 1
004013DB                 xor     eax, 7D0h
004013E0                 ror     eax, 1
004013E2                 sub     eax, 9D8h
004013E7                 jnz     short _invalid_
 
Moesz spyta co do cholery jest w eax ? Popatrz sobie gdzie to my ostatnio 
uywalimy akumulatora, tak, tak - wtedy kiedy sprawdzalimy dugo pobranego
key. Z tego co widzisz wyej, w 004013E7 flaga Z ma by ustawiona, z tego atwo 
sobie policzy ze nasz key ma mie dugo 13h czyli 19 znakw. Mam nadzieje ze 
wiesz jak do tego doszedem ( w kocu to samo odejmowanie, dodawanie i xor'owanie -
wszystko odwracalne ).
Ok teraz przeniesiemy si troche w czaso-przestrzeni i poszukamy informacji o 
ewentualnym sukcesie, moesz mi wierzy ze tak bedzie o wiele atwiej.
Tekst o "zwycistwie" pojawi si dzieki funkcji API SetDlgItemTekstA, poszukaj jej 
wywoania. Znajdzisz ich par, ktra jest informacj o sukcesie? no c W tym programie
wszystkie wane informacje s zaszyfrowane wiec przed wysaniem czego przez 
SetDlgItemTekstA naley to odszyfrowa. S dwie procki deszyfrujce, jedna pod adresem
0040106F - ta odszyfrowuje tekst sukcesie i jeszcze jedna pod 0040108F obie uywj
kluczy  8 bitowych ktre s zreszt zapisne w kodzie. Jak chcesz to moesz wyripowa 
kod tych procek i napisa co co odszyfruje ci wszystkie informacje - ja tak zrobiem.
W kadym razie info z gratulacjami jest pod 004021AC. Z tymi informacjami ie powieniene
mie kopotw z lokalizacj konca naszych wysikw. Jak sam nie znalaze to kiepsko ;)
Masz co ode mnie:

004014F8                 push    offset aMyIcq   ; "My ICQ#:"
004014FD                 push    6Eh
004014FF                 push    _hWnd
00401505                 call    j_SetDlgItemTextA
0040150A                 push    offset bingo
0040150F                 call    Rozszyfruj
00401514                 push    offset bingo ; nasz tekst gratulacuyjny
00401519                 push    6Bh ;ID tego gdzie sie ma wywietlic
0040151B                 push    _hWnd
00401521                 call    j_SetDlgItemTextA
00401526                 push    offset bingo
0040152B                 call    Rozszyfruj ; jak wiesz xor jest odwracalny wiec
										; teraz z powrotem szyfrujemy

Dobra wiesz juz gdzie jest cel, popatrz teraz tu:

00401456 true:                                  
00401456                 mov     eax, offset keybuff2
0040145B                 mov     ebx, [eax]    ;do ebx 4 znaki key  
0040145B                                         
0040145D                 xor     ebx, 12345678h
00401463                 add     ebx, 0C3BCDEF1h
00401469                 jnz     short _invalid_

Z tego atwo mona policzy co ma by w ebx, napewno ju policzye, nie?
NO dobra wyszo ci 2e777777h ? Jezeli tak to dobrze a teraz sprawd co te to jest
w ASCII czy nie "www."? No to ju wiemy jakie s pierwsze znaki key. Jak popatrzysz dalej
w kod to atwo skapujesz e zaczynamy sie ju zajmowac serialem - GetDlgItemInt zmienia
to co byo wpisane w serialu i zmienia t liczb dziesitn na odpowiednik hex.
Tym zajmiemy si troche pniej teraz wracamy do pozostaych literek key.
Napotykamy teraz na may problem nie ma zadnego call pod tej procki w ktrej jestmy.
IDA zgasza nam jedynie e pod adresem 0040139F jej offset jest uywany jako data. 
Patrzymy co si tam dzieje : nie specjalnego przypisujemy go do ecx, to niby nic 
wielkiego ale warto o tym pamieta !!! Dobra wracamy do ledzenia kodu po kolei od
tego miejsca gdzie poprzednio zaprzestalimy, przypomn ci to byo dzie okoo:

004013E9                 mov     ebx, offset KeyBuffer
004013EE                 xor     edx, edx
004013F0                 movzx   eax, byte ptr [ebx+3] ; do eax trafia 2Eh -> "."
004013F4                 dec     eax             ; eax == 2Dh
004013F5 
004013F5 loc_4013F5:                             
004013F5                 cmp     byte ptr [ebx], 0 ; ebx to oczywiscie offset KeyBuffera
004013F8                 jz      short step4
004013FA                 xor     [ebx], al       ; kazdy znak xorowany z 2Dh
004013FC                 inc     ebx
004013FD                 jmp     short loc_4013F5 ; ebx to oczywiscie offset KeyBuffera

widzisz teraz ju jestemy mdrzy bo wiemy e byte ptr [ebx+3] == 2Eh jak nie wiesz 
dlaczego to czytaj jeszcze raz, nie chce mi si pisa. Pniej odejmujemy od niego 1
i xorujemy wszystkei znaki z t wartoci. Jak ju nie ma znakw to step4:

004013FF step4:                                  
004013FF                 mov     eax, 1
00401404                 mov     ebx, offset KeyBuffer
00401409                 xor     edx, edx
0040140B 
0040140B loc_40140B:                             
0040140B                 cmp     byte ptr [ebx], 0
0040140E                 jz      short step5
00401410                 xor     [ebx], al       ; kazdy znak xorowany z kolejnymi wartosciami al
00401412                 add     dl, al          
00401414                 inc     ebx
00401415                 inc     eax
00401416                 jmp     short loc_40140B  

teraz xor wszystkich znakw z wzrastajcymi wartosciami al a suma zapisywana jest w 
dl,( zapamitaj to !!!)

Teraz step5:
00401418                 mov     ebx, offset KeyBuffer
0040141D 
0040141D loc_40141D:                             
0040141D                 cmp     byte ptr [ebx], 0
00401420                 jz      short step6     ; to co ma zostac z key po roznych zmianach
00401422                 xor     [ebx], dl       ; kazdy znak xorowany z suma poprzedniego xorowania
00401424                 inc     ebx
00401425                 jmp     short loc_40141D

Cay opis przy kodzie ;)

Step6:

00401427 step6:                                  
00401427                 mov     edi, offset WzorKey ; to co ma zostac z key po roznych zmianach
0040142C                 mov     esi, offset KeyBuffer

Trzeba ci spojrze pod to co nazwaem WzorKey, jak widzisz jest to rzad bajtw ktrych war
toci odpowiadaj temu co mamy dosta po wszystkich operacjach na naszym key. Wiemy to bo:
 
00401431 loc_401431:                             
00401431                 mov     bl, [edi]
00401433                 mov     al, [esi]
00401435                 cmp     al, 0
00401437                 jz      short SkokDoTrue ; w kocu jmp do Prawdziwej procki !!!!!!!!! yea !!!!
00401439                 cmp     al, bl
0040143B                 jnz     short _invalid_
0040143D                 inc     edi
0040143E                 inc     esi
0040143F                 jmp     short loc_401431

Jak widzisz SkokDoTrue to etykieta czego takiego:
jmp ecx , pamietach jak ci kazaem patrze czy gdzie jest wykoystywany ecx? To tutaj ;) 
 
Dobra wiemy ju wystarczajco duo oby otrzyma poprawny key. Jak wczeniej si 
dowiedzielimy pierwsze 4 znaki to "www." jak sobie teraz zrobisz XOR "w" czyli 0ffh z 
pierwsz wartosci spod WzorKey to otrzymasz warto tego czym xorowalimy pod 
adresem 00401422, nie podam ci jaka to liczba - zrb co sam :P Dobra jak j ju poznae
to wiesz e w 00401410 xorowlimy z kolejmymi wartociami al poczwszy od 1 no to
xoruj wa WzorKey - teraz powiniene mie ju cay key. Lecimy taraz szybko pod 0040147A
bo ju jestemy bardzo blisko ;)
Jak pamietasz teraz w eax bedzie warto hex tego co wpisae w serial.
Widzisz taki kod?

00401488                 xor     eax, 12345678h                                
0040148D                 rol     eax, 4
00401490                 xor     eax, 11223344h
00401495                 ror     eax, 4
00401498                 xor     eax, 87654321h
0040149D                 rol     eax, 4
004014A0                 xor     eax, 66666666h
004014A5                 ror     eax, 4
004014A8                 xor     eax, 0B67CE2F6h
004014AD                 setz    bl              ; flaga Z musi byc ustawiona !!!

mam nadzieje ze wiesz e setz to instrukcja ktra ustawi bl jezeli flaga zero 
jest ustawiona. Kod od  004014B0 - 004014E4 to dlamnie mydlenie oczu ;)
Wane jest to:

004014E9                 movzx   ebx, bl         ; w bl ma byc 1
004014EC                 rol     ebx, 4
004014EF                 cmp     ebx, 10h
004014F2                 jnz     _invalid_

No dobra ta inforamacja wystarcza, jak odwrcisz te wszystkie xory i rol to bedziesz
mial warto tego co zwraca GetDlgItemInt, uyj kalatora i zamie to na dziesitne.
No to masz i key i serial to chyba oznacza ,e ju wszystko - nie uwaasz?

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Mam nadziej e nie bye tak leniwy e nie chciao ci si liczy tego czego ci nie 
podaem.

Gdyby jednak tak si okazao to reversing to nie jest chyba dla ciebie najlepse zajecie.
W kadym razie oto wyliczone dane:
key : www.crackmes.prv.pl
serial: 72987389 

Nawiasem mwic chyba JuBE chcia by si w Dialog'u pojawio My ICQ#: 
ale co chyba u mnie nie wychodzi ;)
Koniec
------
Jak co niejasne to mailme : VirS@wp.pl
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
