Jeg tenkte jeg kunne kontribuere litt på dette forumet, så jeg har skrevet
en tutorial på hvordan man kan cracke mIRC. Mer spesifikt; hvordan man kan
lage en keygen. Jeg valgte mIRC fordi den brukes av mange og fordi den
er relativt enkel.
Det eneste programmet jeg har brukt er IDA pro (interactive disassembler pro), siden jeg synes den er best til å analysere kode.
Det fungerer også som en debugger, så da slår vi jo to fluer i en smekk =)
Andre forslag til disassembler og debugger er henholdsvis w32dasm og Ollydbg.
w32dasm fungerer også som en debugger, men den er ikke særlig god.
------------------------------------------------------------------------------
Last inn fila (mirc.exe) i en disassembler eller debugger.
Det jeg vanligvis bruker å gjøre først er å søke gjennom string referansene
i programmet for å lete etter eventuelle feilmeldinger som f.eks:
"The serial you have entered is incorrect"
Hvis jeg finner en slik referanse bruker jeg å backtrace i koden til jeg finner
der koden hopper til feilmeldingen.
I dette tilfellet fungerer ikke dette, siden teksten ligger som en ressurs som
loades av LoadString apien. I slike tilfeller bruker jeg å finne hvor i koden
programmet henter inn brukernavn og serial. Det kan være i form av tekst du skriver
inn i en tekstboks, en fil med registreringsinformasjon, en nøkkel i registeret +++
mIRC benytter tekstboks-metoden. Det finnes et utall måter å lese tekst fra en
tekstboks, sett ifra en programmerers synspunkt.
F.eks GetWindowTextA, GetDlgItemTextA, SendMessageA med WM_GETTEXT, SendDlgItemMessageA med WM_GETTEXT ++
mIRC benytter den siste av de jeg listet opp.
(Jeg måtte prøve meg frem for å finne det ut.)
Før vi starter vil jeg at vi skal benytte oss av IDA's
FLIRT funksjonalitet. FLIRT står for Fast Library Identification
and Recognition Technology, og er en måte å gjenkjenne funksjonskall
som er mye brukt.
Trykk Shift-F5. Høyreklikk og velg "Apply new signature".
Gjør dette med "Microsoft Visual Studio.Net COM+ Runtime" og
"Microsoft VisualC 2-8/net runtime". IDA vil så automatisk
endre navnene på kjente funksjoner slik at det f.eks står
call _strchr istedenfor call sub_570260.
Start opp programmet i debuggeren til IDA ved å trykke F9.
mIRC vil starte opp på vanlig vis.
Gå så inn på "Help"-menyen til mIRC og velg "register".
Skriv inn noe bogus registreringsinformasjon. I mitt tilfelle har jeg skrevet inn
"Elessar" og "1234567", slik at vi har noe å arbeide med.
Før du trykker OK må vi sette et breakpoint på SendDlgItemMessage, som
er den apien mIRC bruker for å hente inn teksten fra registreringsdialogen.
Trykk Shift-F4 for å få opp "Names"-vinduet. Dette vinduet inneholder
alle navn på funksjoner og variabler. Klikk på vinduet og trykk ALT-T.
Du vil få opp en søkefunksjon. Skriv inn SendDlgItemMessage og trykk OK.
Apien vil så dukke opp. Høyre-klikk så på den og velg "Add Breakpoint".
Du er nå klar til å trykke OK i registreringsdialogen til mIRC.
Trykk OK og debuggeren vil forhåpentligvis stoppe
på addresse 004C7BAA. Slik ser koden ut der:
--------------------------------------------------------------------------
--------------------------------------------------------------------------
Vi ser her at koden leser inn brukernavn og serial og caller en funksjon
med disse to som argument. Vi ser etterpå at når koden har returnert
så sjekker den om eax ikke er null. Hvis den ikke er null hopper den til loc_4C7CCE.
Dette er typisk dårlig beskyttelse siden vi da kan bare endre jz til jmp slik at den
alltid vil godta serial. Men vi må isåfall huske å endre på de to andre plassene
i koden som også caller denne subrutinen. I dette tilfellet er dette ikke interessant
siden vi vil lage en keygen.
Trykk F8 14 ganger til du kommer til call sub_4C7600.
Trykk så F7 for å gå inn i denne subrutinen.
La oss inspisere koden i sub_4C7600.
--------------------------------------------------------------------------
--------------------------------------------------------------------------
Her ser vi at koden zero'er ut to buffere som den etterpå kopierer brukernavn og serial til.
Det har jeg jo selvfølgelig funnet ut ved å single-steppe inn i sub_41EF30 og sub_41EE40.
Jeg orker ikke beskrive hva som skjer her inne fordi det ikke er viktig for serialutregningene.
Anbefaler derimot at dere selv går inn og tracer igjennom det som skjer der.
Trykk F8 21 ganger til du kommer til "call sub_4C7400".
La oss sjekke sub_4C7400. Der inne foregår valideringen av brukernavn vs serial, og vi
ser at den vil returnere 1 i eax dersom koden er gyldig. Denne subrutinen er ganske stor,
så jeg tror jeg prøver å dele den opp litt og forklare etterhvert.
Trykk F7 for å gå inn i den.
--------------------------------------------------------------------------
--------------------------------------------------------------------------
Fortsettelse følger i neste post - m0b
en tutorial på hvordan man kan cracke mIRC. Mer spesifikt; hvordan man kan
lage en keygen. Jeg valgte mIRC fordi den brukes av mange og fordi den
er relativt enkel.
Det eneste programmet jeg har brukt er IDA pro (interactive disassembler pro), siden jeg synes den er best til å analysere kode.
Det fungerer også som en debugger, så da slår vi jo to fluer i en smekk =)
Andre forslag til disassembler og debugger er henholdsvis w32dasm og Ollydbg.
w32dasm fungerer også som en debugger, men den er ikke særlig god.
------------------------------------------------------------------------------
Last inn fila (mirc.exe) i en disassembler eller debugger.
Det jeg vanligvis bruker å gjøre først er å søke gjennom string referansene
i programmet for å lete etter eventuelle feilmeldinger som f.eks:
"The serial you have entered is incorrect"
Hvis jeg finner en slik referanse bruker jeg å backtrace i koden til jeg finner
der koden hopper til feilmeldingen.
I dette tilfellet fungerer ikke dette, siden teksten ligger som en ressurs som
loades av LoadString apien. I slike tilfeller bruker jeg å finne hvor i koden
programmet henter inn brukernavn og serial. Det kan være i form av tekst du skriver
inn i en tekstboks, en fil med registreringsinformasjon, en nøkkel i registeret +++
mIRC benytter tekstboks-metoden. Det finnes et utall måter å lese tekst fra en
tekstboks, sett ifra en programmerers synspunkt.
F.eks GetWindowTextA, GetDlgItemTextA, SendMessageA med WM_GETTEXT, SendDlgItemMessageA med WM_GETTEXT ++
mIRC benytter den siste av de jeg listet opp.
(Jeg måtte prøve meg frem for å finne det ut.)
Før vi starter vil jeg at vi skal benytte oss av IDA's
FLIRT funksjonalitet. FLIRT står for Fast Library Identification
and Recognition Technology, og er en måte å gjenkjenne funksjonskall
som er mye brukt.
Trykk Shift-F5. Høyreklikk og velg "Apply new signature".
Gjør dette med "Microsoft Visual Studio.Net COM+ Runtime" og
"Microsoft VisualC 2-8/net runtime". IDA vil så automatisk
endre navnene på kjente funksjoner slik at det f.eks står
call _strchr istedenfor call sub_570260.
Start opp programmet i debuggeren til IDA ved å trykke F9.
mIRC vil starte opp på vanlig vis.
Gå så inn på "Help"-menyen til mIRC og velg "register".
Skriv inn noe bogus registreringsinformasjon. I mitt tilfelle har jeg skrevet inn
"Elessar" og "1234567", slik at vi har noe å arbeide med.
Før du trykker OK må vi sette et breakpoint på SendDlgItemMessage, som
er den apien mIRC bruker for å hente inn teksten fra registreringsdialogen.
Trykk Shift-F4 for å få opp "Names"-vinduet. Dette vinduet inneholder
alle navn på funksjoner og variabler. Klikk på vinduet og trykk ALT-T.
Du vil få opp en søkefunksjon. Skriv inn SendDlgItemMessage og trykk OK.
Apien vil så dukke opp. Høyre-klikk så på den og velg "Add Breakpoint".
Du er nå klar til å trykke OK i registreringsdialogen til mIRC.
Trykk OK og debuggeren vil forhåpentligvis stoppe
på addresse 004C7BAA. Slik ser koden ut der:
--------------------------------------------------------------------------
Kode
.text:004C7BA0 mov esi, [esp+48h+hWnd] .text:004C7BA4 mov edi, ds:SendDlgItemMessageA .text:004C7BAA push offset aElessar ; lParam <- Her havner du .text:004C7BAF push 3E7h ; wParam .text:004C7BB4 push 0Dh ; Msg .text:004C7BB6 push 83h ; nIDDlgItem .text:004C7BBB push esi ; hDlg .text:004C7BBC call edi ; SendDlgItemMessageA .text:004C7BBE push offset a1234123456 ; lParam .text:004C7BC3 push 3E7h ; wParam .text:004C7BC8 push 0Dh ; Msg .text:004C7BCA push 84h ; nIDDlgItem .text:004C7BCF push esi ; hDlg .text:004C7BD0 call edi ; SendDlgItemMessageA .text:004C7BD2 mov edx, offset a1234123456 ; "1234567" .text:004C7BD7 mov ecx, offset aElessar ; "Elessar" .text:004C7BDC call sub_4C7600 ; sjekk brukernavn og serial .text:004C7BE1 test eax, eax .text:004C7BE3 jz loc_4C7CCE
Vi ser her at koden leser inn brukernavn og serial og caller en funksjon
med disse to som argument. Vi ser etterpå at når koden har returnert
så sjekker den om eax ikke er null. Hvis den ikke er null hopper den til loc_4C7CCE.
Dette er typisk dårlig beskyttelse siden vi da kan bare endre jz til jmp slik at den
alltid vil godta serial. Men vi må isåfall huske å endre på de to andre plassene
i koden som også caller denne subrutinen. I dette tilfellet er dette ikke interessant
siden vi vil lage en keygen.
Trykk F8 14 ganger til du kommer til call sub_4C7600.
Trykk så F7 for å gå inn i denne subrutinen.
La oss inspisere koden i sub_4C7600.
--------------------------------------------------------------------------
Kode
.text:004C7600 sub_4C7600 proc near ; CODE XREF: sub_4C76E0+A9p .text:004C7600 ; sub_4C79F0+58p ... .text:004C7600 .text:004C7600 var_208= dword ptr -208h .text:004C7600 var_104= dword ptr -104h .text:004C7600 .text:004C7600 sub esp, 208h <- Vi havner her. .text:004C7606 push esi .text:004C7607 push edi .text:004C7608 mov esi, edx .text:004C760A mov edi, ecx .text:004C760C mov edx, 104h .text:004C7611 lea ecx, [esp+210h+var_208] .text:004C7615 call sub_41EF30 ; nuller ut en buffer .text:004C761A mov edx, 104h .text:004C761F lea ecx, [esp+210h+var_104] .text:004C7626 call sub_41EF30 ;nuller ut en buffer .text:004C762B push edi .text:004C762C mov edx, 104h .text:004C7631 lea ecx, [esp+214h+var_208] .text:004C7635 call sub_41EE40 ; kopierer en string (username) til buffer .text:004C763A push esi .text:004C763B mov edx, 104h .text:004C7640 lea ecx, [esp+214h+var_104] .text:004C7647 call sub_41EE40 ; kopierer en string (serial) til buffer .text:004C764C lea edx, [esp+210h+var_104] ; serial .text:004C7653 lea ecx, [esp+210h+var_208] ; username .text:004C7657 call sub_4C7400 ; den virkelige testen, her inne er den viktige koden .text:004C765C test eax, eax .text:004C765E jz short loc_4C766E ;vi kunne ha NOP'a ut denne, så hadde den alltid godtatt serial ;det andre viktige med denne jz'en er at den hopper til en annen serial-sjekk rutine ;mIRC har faktisk to forskjellige måter å validere serials på. Vi vil bare analysere den første. .text:004C7660 pop edi .text:004C7661 mov eax, 1 .text:004C7666 pop esi .text:004C7667 add esp, 208h .text:004C766D retn
Her ser vi at koden zero'er ut to buffere som den etterpå kopierer brukernavn og serial til.
Det har jeg jo selvfølgelig funnet ut ved å single-steppe inn i sub_41EF30 og sub_41EE40.
Jeg orker ikke beskrive hva som skjer her inne fordi det ikke er viktig for serialutregningene.
Anbefaler derimot at dere selv går inn og tracer igjennom det som skjer der.
Trykk F8 21 ganger til du kommer til "call sub_4C7400".
La oss sjekke sub_4C7400. Der inne foregår valideringen av brukernavn vs serial, og vi
ser at den vil returnere 1 i eax dersom koden er gyldig. Denne subrutinen er ganske stor,
så jeg tror jeg prøver å dele den opp litt og forklare etterhvert.
Trykk F7 for å gå inn i den.
--------------------------------------------------------------------------
Kode
.text:004C7400 sub esp, 0A4h <- Her havner vi. .text:004C7406 push ebx .text:004C7407 push ebp .text:004C7408 push esi .text:004C7409 mov esi, 0Bh .text:004C740E mov eax, 0Ah .text:004C7413 push edi .text:004C7414 mov edi, ecx .text:004C7416 mov ecx, 0Eh .text:004C741B mov [esp+0B4h+var_A0], esi .text:004C741F mov ebp, 6 .text:004C7424 mov ebx, 10h .text:004C7429 mov [esp+0B4h+var_78], esi .text:004C742D mov [esp+0B4h+var_64], esi .text:004C7431 mov [esp+0B4h+var_50], esi .text:004C7435 mov [esp+0B4h+var_44], esi .text:004C7439 mov esi, 8 .text:004C743E mov [esp+0B4h+var_A4], edx .... OSV.... (måtte kutte ned her slik at posten ikke blir over 16000 tegn)
Fortsettelse følger i neste post - m0b
Sist endret av m0b; 10. mai 2006 kl. 23:03.