|
||
Data |
by LordMoon |
|
16/11/2003 |
Published by Quequero |
|
io non ho particolari doti...sono solo appassionatamente curioso(Albert Einstein) |
Beh non posso che osannare tanta dedizione, hai ricostruito in ascii tutte le schermate di softice... Sei proprio matto! :)))) Cmq il tute e' completissimo, grazie mille |
finchè il vin dia la terra, sempre all'acqua guerra guerra! |
.... |
|
.... |
Difficoltà |
( )NewBies (x )Intermedio ( )Avanzato ( )Master |
bene bene oggi reverseremo mirc 6.12.il programma,come sapete, è uno dei client per irc più conosciuti.è shareware e dopo 30 giorni scade il tempo.E' provvisto di una protezione contro la modifica così che se cercate di modificarlo non vi parte più!L'autore spera così di arrestare il dilagante fenomeno della pirateria....ma noi che siamo molto curiosi ci avviciniamo al prog proprio per questo! ;-)
Introduzione |
Tools usati |
URL o FTP del programma |
Notizie sul programma |
Essay |
|
uhmmm...è possibile che sia questo???
cosa fa test eax,eax? controlla semplicemente se eax=0 e se si salta...e in alto a sinistra vediamo eax=1...bene quindi non deve saltare...!
Ora controlliamo la versione non funzionante...:
|
e siccome in genere quella che conta è l'ultima prima dei controlli....controlliamo la call 4D47C0!!!
(Saremmo potuti arrivare a questo anche con un altra strada...se il programma riconosce se viene modificato il suo file..beh da qualche parte deve prima reperire informazioni da confrontare poi...quindi basta qualche bpx su delle api giuste tipo ..... !però la strada qui seguita è molto + banale..il computer ragiona istruzione per istruzione..una sola per volta...l'idea è di confrontare le due strade e vedere dove si separano...in questo caso era molto semplice però in casi + complicati potete debuggare in automatico(wdasm lo permette e colora di rosso le istruzioni già eseguite....quindi non è difficile riconoscere le diversità)).
ecco un pezzo di codice della call incriminata...la parte prima è stata omessa perchè conteneva solo push e move in quantità noiosa!
|
ok noppiamo quel jz....basta premere eb 4D4888 e scriviamo 90 90!poi enter e esc.
ora non salta più e se premiamo F5 usciamo da sice e sorpresa il prog parte :-D
OK ora modifichiamo l'eseguibile per noppare quei 5 jz...li noppiamo tutti tanto vanno nello stesso punto..punto in cui noi non vogliamo andare!
bene come calcoliamo l'offset?beh qui basterebbe sottrarre 400000 all'indirizzo dell'istruzione della quale vogliamo l'offset ..però in generale no!allora noi che non vogliamo fare calcoli strani...(la pigrizia indirizzata bene ha portato a varie scoperte es:la lagrangiana per chi di voi studia fisica)usiamo la calc del Peditor apriamo il file,andiamo sulla calc e sotto virtual address...ci mettiamo gli indirizzi e ci segniamo la risposta...!
fatto?!?
apriamo l'editor e modifichiamo l'eseguibile in quegli indirizzi mettendo dei 90 (=nop no operation).......ora siccome i salti sono di 2 byte mettiamo 2 nop per indirizzo(uno per byte).
proviamo il nuovo eseguibile e ...si poppa sice perchè c'è il nostro entry point modificato eb eip 6a di nuovo e F5..il prog và che è una meraviglia...!!!!
Protezione fregata!
già che ci siete rimette al posto di CC il 6a nel file(dico nell'entry point sul file) così tutto và senza dover digitare eb eip...
parte bella finita!
ora parte noiosa e rutinaria....
mettiamo un break su qualche api in sice...bpx getdlgitemtexa (solitamente è questa) e enter.
caxxo sice non poppa!!!vuoi vedere che usa api strane per fare il miele ..ehm per leggere il testo?
uhmmm...io che come vi dicevo sono molto pigro e sparo con bazukaa sui moscerini
decido di usare ida invece che un comunissimo api spy(per vedere quale api viene usate).
dicevo apro ida...carico il prog...e aspetetto....uffa quanto aspetto...!
vado sotto names e trovo la lista delle api e funzioni importate usate dal prog!
bene bene guarda questa...SendDlgItemMessageA...uhmm...vuoi vedere che viene usata proprio questa...??
proviamo in sice bpx SendDlgItemMessageA (e voi non scrivetelo maiuscolo/minuscolo tanto funziona lo stesso serve solo per leggerlo meglio)..e voilà sice poppa!!!
mitico F5 e ripoppa!
F11 per andare dal chiamante(intendo colui che ha chiamato questa api)..e sorpresa
|
voilà registrazione ok!
bene...non è mica finita..sappiamo che la call 4C1D90 fa il check e se la password è giusta non deve saltare! cioè eax deve essere diverso da 0 magari 1. ;-)
ora normalmente un tipo come me ,intendo che non pensa, modifica il jz mettendoci un jnz o due nop.
Così il prog si registra...ma se è un prog decente...e questo lo è...fara qualche controllo all'avvio e magari anche alla chiusura!
Bene che si fà?
i programmatori sono persone che hanno moolti problemi in testa e non hanno voglia di sbattersi..così una call per testare la password è + che sufficente...il che significa una sola call ...una sola procedura per il check....una sola modifica :-D !!!!
analizziamo dunque la call con ida!
.text:004C1D90
sub esp, 208h
.text:004C1D96 push eax
.text:004C1D97 push ebp
.text:004C1D98 push esi
.text:004C1D99 mov ebp, edx
.text:004C1D9B mov ebx, ecx
.text:004C1D9D push edi
.text:004C1D9E mov edx, 104h
.text:004C1DA3 lea ecx, [esp+218h+var_208]
.text:004C1DA7 call sub_41E210
<----domanda a cosa serve?
.text:004C1DAC mov edx, 104h
.text:004C1DB1 lea ecx, [esp+218h+var_104]
.text:004C1DB8 call sub_41E210
<----ancora la stessa call!
.text:004C1DBD lea esi, [esp+218h+var_208]
.text:004C1DC1 mov eax, ebx
.text:004C1DC3 sub esi, ebx
.text:004C1DC5 mov cl, [eax]
<----------------------------
.text:004C1DC7 mov [esi+eax], cl
|
.text:004C1DCA inc eax
| ciclo di loop
.text:004C1DCB test cl, cl
|
.text:004C1DCD jnz short loc_4C1DC5
----------------------------
.text:004C1DCF lea edi, [esp+218h+var_104]
.text:004C1DD6 mov eax, ebp
.text:004C1DD8 sub edi, ebp
.text:004C1DDA lea ebx, [ebx+0]
.text:004C1DE0 mov cl, [eax]
<-------------------------
.text:004C1DE2 mov [edi+eax], cl
|
.text:004C1DE5 inc eax
| Altro ciclo di loop
.text:004C1DE6 test cl, cl
|
.text:004C1DE8 jnz short loc_4C1DE0
-----------------
.text:004C1DEA lea edx, [esp+218h+var_104]
.text:004C1DF1 lea ecx, [esp+218h+var_208]
.text:004C1DF5 call sub_4C1B80
<--- uhmm...a cosa servirà?
.text:004C1DFA test eax, eax
eax=0????
.text:004C1DFC jz short loc_4C1E0E
se si salta ,altrimenti prosegui
.text:004C1DFE pop edi
.text:004C1DFF pop esi
.text:004C1E00 pop ebp
.text:004C1E01 mov eax, 1
ricordate il nostro obbiettivo?fare in modo che eax sia
diverso da 0
.text:004C1E06 pop ebx
con mov eax,1 metto 1 in eax quindi eax è diverso da
zero!!!!
.text:004C1E07 add esp, 208h
.text:004C1E0D retn
.text:004C1E0E ;
---------------------------------------------------------------------------
figo se seguo questa strada ...eax=1 quindi test eax,eax fa z=0 (cioè eax diverso da 0)e quindi jz non salta e quindi il prog si registra!!!
ok quindi devo noppare 4C1DFC in modo che non salti assolutamente!!
per cercare l'offset basta guardare in basso ,ida lo calcola automaticamente ma se proprio volete sbattervi usate la calc di peditor come prima o addirittura sottraete 400000 ma vi ricordo che è un caso molto fortunato questo!
riprendiamo da prima quando dicevo noppiamo il jz...lo avete fatto??beeene!
avviamo il mirc
andiamo su register nome e codice e...
thanks. Mirc craccato e modificato! :-p
ora siccome siamo masochisti diamo un occhiata alle call!
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
vi sottolineo che la parte seguente è solo così come esercizio il mirc così è già craccato....
Ok con calma non vi spaventate...
per prima cosa fà qualche noiosa istruzione poi 2 call sub_41E210...(non credo sia importante...perchè usarla due volte?)cmq ecco il codice:
.text:0041E210 push edi
salva edi nello stack
.text:0041E211 mov edi, ecx
mette ecx in edi
.text:0041E213 test edi, edi
controlla edi=0?
.text:0041E215 jz short loc_41E231
se si salta
.text:0041E217 cmp edx, 0Ah
confronta edx=0A?
.text:0041E21A jle short loc_41E22E
.text:0041E21C mov ecx, edx
.text:0041E21E shr ecx, 2
.text:0041E221 xor eax, eax
.text:0041E223 rep stosd
.text:0041E225 mov ecx, edx
.text:0041E227 and ecx, 3
.text:0041E22A rep stosb
.text:0041E22C pop edi
.text:0041E22D retn
bah..fà qualche check .....
così salto ed esamino la prox call!nel caso qualcuno di voi volesse scrivere un keygenerator!è questa quella importante!!!!!!
.text:004C1B80 sub esp, 0A4h
.text:004C1B86 push ebx
.text:004C1B87 push ebp
.text:004C1B88 push esi
.text:004C1B89 mov eax, 0Ah
.text:004C1B8E push edi
.text:004C1B8F mov edi, ecx
.text:004C1B91 mov ecx, 0Eh
.text:004C1B96 mov ebx, 6
.text:004C1B9B mov esi, 0Bh
.text:004C1BA0 mov [esp+0B4h+var_8C], ecx
.text:004C1BA4 mov ebp, 10h
.text:004C1BA9 mov [esp+0B4h+var_70], ecx
.text:004C1BAD mov [esp+0B4h+var_6C], ecx
.text:004C1BB1 mov [esp+0B4h+var_5C], ecx
.text:004C1BB5 mov [esp+0B4h+var_58], ecx
.text:004C1BB9 mov ecx, 8
.text:004C1BBE mov [esp+0B4h+var_A4], edx
.text:004C1BC2 mov edx, 0Ch
.text:004C1BC7 mov [esp+0B4h+var_9C], ebx
.text:004C1BCB mov [esp+0B4h+var_7C], eax
.text:004C1BCF mov [esp+0B4h+var_74], ebx
.text:004C1BD3 mov ebx, 4
.text:004C1BD8 mov [esp+0B4h+var_40], eax
.text:004C1BDC mov [esp+0B4h+var_38], eax
.text:004C1BE0 mov [esp+0B4h+var_34], eax
.text:004C1BE7 mov [esp+0B4h+var_20], eax
.text:004C1BEE mov [esp+0B4h+var_10], eax
.text:004C1BF5 mov eax, edi
.text:004C1BF7 mov [esp+0B4h+var_3C], ecx
.text:004C1BFB mov [esp+0B4h+var_2C], ecx
.text:004C1C02 mov [esp+0B4h+var_14], ecx
.text:004C1C09 mov [esp+0B4h+var_A0], esi
.text:004C1C0D mov [esp+0B4h+var_98], 11h
.text:004C1C15 mov [esp+0B4h+var_94], edx
.text:004C1C19 mov [esp+0B4h+var_90], edx
.text:004C1C1D mov [esp+0B4h+var_88], 5
.text:004C1C25 mov [esp+0B4h+var_84], edx
.text:004C1C29 mov [esp+0B4h+var_80], ebp
.text:004C1C2D mov [esp+0B4h+var_78], esi
.text:004C1C31 mov [esp+0B4h+var_68], ebx
.text:004C1C35 mov [esp+0B4h+var_64], esi
.text:004C1C39 mov [esp+0B4h+var_60], 6
.text:004C1C41 mov [esp+0B4h+var_54], ebx
.text:004C1C45 mov [esp+0B4h+var_50], esi
.text:004C1C49 mov [esp+0B4h+var_4C], 9
.text:004C1C51 mov [esp+0B4h+var_48], edx
.text:004C1C55 mov [esp+0B4h+var_44], esi
.text:004C1C59 mov [esp+0B4h+var_30], ebp
.text:004C1C60 mov [esp+0B4h+var_28], ebx
.text:004C1C67 mov [esp+0B4h+var_24], 6
.text:004C1C72 mov [esp+0B4h+var_1C], edx
.text:004C1C79 mov [esp+0B4h+var_18], ebp
.text:004C1C80 mov [esp+0B4h+var_C], ebx
.text:004C1C87 mov [esp+0B4h+var_8], ebp
.text:004C1C8E mov [esp+0B4h+var_4], 0
.text:004C1C99 lea ecx, [eax+1]
.text:004C1C9C lea esp, [esp+0]
Tutte variabili messe nel posto giusto......
.text:004C1CA0
.text:004C1CA0 loc_4C1CA0: ; CODE XREF: sub_4C1B80+125 j
.text:004C1CA0 mov dl, [eax]
<--------
.text:004C1CA2 inc eax
|
.text:004C1CA3 test dl, dl
| ciclo di loop.tratta eax come puntatore mette in dl il
.text:004C1CA5 jnz short loc_4C1CA0
--------- carattere puntato e poi controlla se è zero
.text:004C1CA7 sub eax, ecx
praticamente mette in dl la stringa puntata
.text:004C1CA9 cmp eax, 5
da eax.sottrae da eax(che è=alla lunghezza
.text:004C1CAC jnb short loc_4C1CBB
della stringa) il valore di ecx e confronta il
.text:004C1CAE
risultato con 5.usando sice scopro eax-ecx=lung user
.text:004C1CAE pop edi
perchè eax punta alla fine dell'user ed ecx all'inizio.
.text:004C1CAF pop esi
.text:004C1CB0 pop ebp
.text:004C1CB1 xor eax, eax
<-----uhmmm setta eax=0!
.text:004C1CB3 pop ebx
.text:004C1CB4 add esp, 0A4h
.text:004C1CBA retn
<-----e qui esce!!!!se esce così eax=0 e quindi il prog
non si registra
ricordate prima alla linea 4C1DFA il test eax,eax?
conclusione non deve eseguire questa funzione!cioè tutte le volte che trovo un jmp condizionato a 4C1CAE so che non deve saltare!
praticamente ora so la strada che seguirebbe il prog se la password fosse giusta! ora si che si può scrivere un keygenerator.
infatti:
.text:004C1CBB ;
---------------------------------------------------------------------------
.text:004C1CBB
.text:004C1CBB loc_4C1CBB: ; CODE XREF: sub_4C1B80+12C j
.text:004C1CBB mov ebx, [esp+0B4h+var_A4]
<--- mette il nostro codice in ebx
.text:004C1CBF push 2Dh
<----in ascii è il carattere "-"
.text:004C1CC1 push ebx
<----salva il nostro codice nello stack
.text:004C1CC2 call sub_563730
<----la analizziamo dopo(forse)cmq mette in eax
l'indirizzo
.text:004C1CC7 mov esi, eax
della seconda metà del codice "-" compreso e poi lo mette
.text:004C1CC9 add esp, 8
in esi.
.text:004C1CCC test esi, esi
<----controlla se l'indirizzo è 0.cioè il codice è di 2
parti?
.text:004C1CCE jz short loc_4C1CAE <----uhmm....non
deve saltare per il discorso di 10 righe fa!
.text:004C1CD0 push ebx
<-----salva ebx
.text:004C1CD1 mov byte ptr [esi], 0
<----mette 0 al posto di"-".cioè aggiunge il terminatore
alla parte 1
.text:004C1CD4 call sub_563A14
<-----vediamo dopo.... mi limito a dire che ritorna un num
in eax
.text:004C1CD9 add esp, 4
numero che poche linee dopo viene salvato in ebp.
.text:004C1CDC mov byte ptr [esi], 2Dh <-----mette
il carattere "-" nella stringa puntata da esi
.text:004C1CDF inc esi
<-----incrementa esi
.text:004C1CE0 mov ebp, eax
<-----salva eax in ebp
.text:004C1CE2 cmp byte ptr [esi], 0
<-----confronta il carattere puntato da esi con 0
.text:004C1CE5 jz short loc_4C1CAE
<-----al solito non deve saltare!quindi non devono essere
=
.text:004C1CE7 push esi
<----salva esi
.text:004C1CE8 call sub_563A14
<---stessa call di prima!solo che dopo salva eax in [esp+....]
.text:004C1CED mov ecx, edi
<---mette edi in ecx
.text:004C1CEF add esp, 4
.text:004C1CF2 mov [esp+0B4h+var_A4], eax <---rende
esp+0B4h+var_A4 un puntatore a eax
.text:004C1CF6 lea edx, [ecx+1]
<---edx diventa un puntatore a ecx+1
.text:004C1CF9 lea esp, [esp+0B4h+var_B4] <---come
prima solo con esp
.text:004C1D00 mov al, [ecx]
<-------
.text:004C1D02 inc ecx
| ciclo di loop.tratta ecx come un puntatore e mette la
stringa
.text:004C1D03 test al, al
| puntata in al e ecx=lunghezza stringa
.text:004C1D05 jnz short loc_4C1D00
--------
.text:004C1D07 sub ecx, edx
<--- ecx-edx e risultato in ecx
.text:004C1D09 mov esi, 3
<---esi=3
.text:004C1D0E xor edx, edx
<---edx=0
.text:004C1D10 xor ebx, ebx
<---ebx=0
.text:004C1D12 cmp ecx, esi
<---ecx=3?minore?maggiore?
.text:004C1D14 jle short loc_4C1D38
<---se minore o uguale salta
.text:004C1D16 jmp short loc_4C1D20
<---altrimenti salta da qui
bla...bla non serve a nulla
.text:004C1D20 ;
---------------------------------------------------------------------------
.text:004C1D20 movzx eax, byte ptr [esi+edi] <---inizia
il loop..mette in eax il valore ascii...
.text:004C1D24 imul eax, [esp+edx*4+0B4h+var_A0] <---uhmm..moltiplica
per qualche valore ......
.text:004C1D29 add ebx, eax
<---- e ci somma sopra(cioè somma tutti i valori ottenuti
e mette in ebx)
.text:004C1D2B inc edx
<-----edx è un contatore,l'array è lunga 26h caratteri
.text:004C1D2C cmp edx, 26h
<--- se edx è maggiore di 26h allora fallo 0 e continua
.text:004C1D2F jle short loc_4C1D33
.text:004C1D31 xor edx, edx
<----una volta fatto,edx=0
.text:004C1D33 inc esi
<---esi è un contatore per il ciclo di loop
.text:004C1D34 cmp esi, ecx
<---in ecx c'è la lunghezza dell'user se sono uguali
smetti di
.text:004C1D36 jl short loc_4C1D20
leggere.e finisce il loop altrimenti continua
.text:004C1D38 cmp ebp, ebx
<---confronta ebp con ebx! se diversi salta!
.text:004C1D3A jnz loc_4C1CAE
<----non deve saltare quindi ebp deve essere uguale a ebx
.text:004C1D40 mov esi, 3
<----esi=3
.text:004C1D45 xor edx, edx
<---edx=0
.text:004C1D47 xor ebx, ebx
<---ebx=0
.text:004C1D49 cmp ecx, esi
<---ecx=3? cioè la lunghezza dell'user è minore o uguale a
3?
.text:004C1D4B jle short loc_4C1D70
<---se è minore o uguale salta,altrimenti continua
.text:004C1D4D lea ecx, [ecx+0]
<--praticamente mette in ecx l'indirizzo del suo contenuto
cioè ecx diventa un puntatore.
.text:004C1D50 movzx eax, byte ptr [esi+edi-1] <---del
tutto simile a prima
.text:004C1D55 movzx ebp, byte ptr [esi+edi]
.text:004C1D59 imul eax, ebp
.text:004C1D5C imul eax, [esp+edx*4+0B4h+var_A0]
.text:004C1D61 add ebx, eax
<----come prima mette la somma totale in ebx
.text:004C1D63 inc edx
.text:004C1D64 cmp edx, 26h
.text:004C1D67 jle short loc_4C1D6B
.text:004C1D69 xor edx, edx
<---fai edx=0
.text:004C1D6B inc esi
<---incrementa esi
.text:004C1D6C cmp esi, ecx
<---confronta esi ed ecx
.text:004C1D6E jl short loc_4C1D50
<--continua ciclo finchè non sono uguali
.text:004C1D70 mov ecx, [esp+0B4h+var_A4]
.text:004C1D74 pop edi
<---salva edi
.text:004C1D75 pop esi
<----salva esi
.text:004C1D76 xor eax, eax
<----eax=0!
.text:004C1D78 cmp ecx, ebx
<----confronta ecx e ebx e se uguali setta i vari flag
.text:004C1D7A pop ebp
<----salva ebp;chissà cosa c'è in ecx?
.text:004C1D7B setz al
<---questa è molto interessante..mette in al i flag di
prima
.text:004C1D7E pop ebx
<---legge dallo stack
.text:004C1D7F add esp, 0A4h
<---incrementa esp di 0A4h
.text:004C1D85 retn
<---e ora esce!!!!!
.text:004C1D85 sub_4C1B80 endp
vi faccio notare che esp è sempre durante i loop di controllo costantemente uguale anzi all'uscita di qualche call il prog si prende la briga di aumentarlo per farlo tornare come era prima ...vedi riga 4C1CEF.
Segue banalmente che esp+0B4h+var_A0 è una costante durante il calcolo del codice!e edx deve essere minore di 26h quindi 26h*4+esp+0B4h+var_A0 è il massimo valore consentito.
uhmm...ma cosa ci sarà dall'indirizzo esp+a4h fino a 26h*4+esp+0B4h+var_A0?ovviamente qualcosa che ci interessa molto..
dopo alcune prove e un pò di reverse ho concluso che esp varia con l'user ma il suo contenuto è costante!infatti se guardate all'inizio ..intendo all'indirizzo 4C1B80..vedete che il prog setta tanti bei valori tutti riferiti a esp...
Comunque usando sice ....bpx all'indirizzo giusto e un bel db esp+14:
|
...nella finestra data vedete disassemblata tutta la zone di memoria che ci interessa,ora siccome stiamo andando a multipli di 4h la stringa cercata è:
0B 06 11 0C 0C 0E 05 0C 10 0A 0B 06 0E 0E 04 0B 06 0E 0E 04 0B 09 0C 0B 0A 08 0A 0A 10 08 04 06 0A 0C 10 08 0A 04 10
Analizziamo meglio il problema...dato un username questi due loop non fanno altro che tirarne fuori un numero ciascuno!bene anche perchè fin qui non c'è nulla di incgnito,dato un user facciamo quello che ci dice l'assembly e otteniamo due numeri che devono essere uguali a quelli contenuti in ebp ed in ecx all'indirizzi 4C1D38 e 4C1D78.
uhm..coraggio siamo quasi alla fine!
manca ancora una cosa, la call sub_563A14 che viene chiamata due volte che fa?iniziamo subito a dire che il suo valore ritornato in eax viene sempre salvato..uhm...deve essere importante...!infatti è questo valore che viene confrontato coi valori ritornati dagli ultimi 2 loop.e lo potete verificare all'indirizzo 4C1D38 e 4C1D7A.bene se vogliamo scrivere un keygenerator ci è necessario capire meglio questa call...
ecco il codice:
.text:00563A14 push esi
.text:00563A15 mov esi, [esp+arg_0]
.text:00563A19 jmp short loc_563A1C
.text:00563A1B inc esi
.text:00563A1C movzx eax, byte ptr [esi]
.text:00563A1F push eax
.text:00563A20 call sub_5693B6 <---non
fa nulla....tranne eax=0
.text:00563A25 test eax, eax
.text:00563A27 pop ecx
.text:00563A28 jnz short loc_563A1B
.text:00563A2A movzx ecx, byte ptr [esi] <--valore
ascii in ecx
.text:00563A2D inc esi
<--punta al carattere successivo
.text:00563A2E cmp ecx, 2Dh
.text:00563A31 mov edx, ecx
.text:00563A33 jz short loc_563A3A
.text:00563A35 cmp ecx, 2Bh
.text:00563A38 jnz short loc_563A3E
.text:00563A3A movzx ecx, byte ptr [esi]
.text:00563A3D inc esi
.text:00563A3E xor eax, eax
.text:00563A40 cmp ecx, 30h
----|
.text:00563A43 jl short loc_563A4F
|<----se il codice ascii non +è compreso tra 31 e 39
esci...
.text:00563A45 cmp ecx, 39h
|
.text:00563A48 jg short loc_563A4F ----|
.text:00563A4A sub ecx, 30h
<---ecx=ecx-30h(questo perchè in ascii un numero diventa
3n cioè
.text:00563A4D jmp short loc_563A52
2 diventa 32....e se ci sottraggo 30 riottengo 2
.text:00563A4F or ecx, 0FFFFFFFFh
però in esadecimale..)
.text:00563A52 cmp ecx, 0FFFFFFFFh
.text:00563A55 jz short loc_563A63
.text:00563A57 lea eax, [eax+eax*4]
.text:00563A5A lea eax, [ecx+eax*2]
.text:00563A5D movzx ecx, byte ptr [esi]
.text:00563A60 inc esi
.text:00563A61 jmp short loc_563A40
.text:00563A63 cmp edx, 2Dh
.text:00563A66 pop esi
.text:00563A67 jnz short locret_563A6B
.text:00563A69 neg eax
.text:00563A6B retn
bene è lunga ma semplice!...+ di quanto possiate immaginare...non ve la commento istruzione per istruzione però osserviamo che:
.text:00563A57 lea eax, [eax+eax*4]
.text:00563A5A lea eax, [ecx+eax*2]
è la stessa cosa di:
eax=5*eax eax=ecx+2*eax
in parole povere:
eax=ecx+eax*10
esi è un puntatore al codice(alla prima parte o alla seconda dipende da quello che gli passa il prog)
e per finire:
.text:00563A5D movzx ecx, byte ptr [esi] .text:00563A60 inc esi
dice metti in ecx il valore ascii del carattere puntato da esi e poi punta al carattere dopo.
dunque
la call legge il primo carattere prende il codice ascii poi sottrae 30h(.text:00563A4A sub ecx, 30h) moltiplica per 10 somma con il secondo codice ascii....
in parole povere: dato un numero di n cifre xy....z -->10^n*x+10^(n-1)*y+....+z=xy..z(trattato come esadecimale)
bello e facile..ricordiamoci soltanto che il numero viene considerato come esadecimale e noi lo scriviamo in decimale quindi se sapete che dovete ottenere un numero ..per es:1CC7 lo convertite in decimale e ve lo tenete così...1CC7h=7367d!
uffa...sappiamo la strada da seguire...se volete scrivere un keygen..ora lo potete fare!;-)
visto?? per reversare un programma quando siete in difficoltà chiedetevi cosa deve fare questa call...?
e cercate il punto in cui fa esattamente l'opposto....almeno sapete che lì non dovete arrivare...e ogni vario
check sapete già cosa deve fare...!(è ovviamente solo un consiglio).
così vi resta solo da interpretare cosa fanno le varie parti del prog
ricapitolando:
il codice deve essere di 2 parti separate da un "-",il prog spezza in due il nostro codice,fa una certa operazione usando come incognita una stringa di 26h caratteri e confronta prima la seconda parte del codice che gli passate(trasformandolo in esa) col risultato poi fa lo stesso per l'altra parte, se tutto va bene il prog è registrato.
per scrivere un keygenerator ora dovete trasformare i due loop nel linguaggio che volete utilizzare prendete questi numeri e li convertite entrambi in decimale..poi ci mettete un "-" di mezzo e via codice fatto!:-D
ora ..volete il codice per il vostro username?mettete 2 bpx agli indirizzi 004C1D38 e 004C1D78,scrivete per esempio come user ciaociao e invio..sice poppa guardate in alto a sinistra c'è scritto ebp=17D0,ricordatevi questo valore ..premete F7 e sice ripoppa e guardate ora ecx,ecx=9589E.convertiteli in decimale con la la calc di window e ci mettete il "-" tra i due..ottenete: 6096-612510 che è appunto il codice di registrazione.
per concludere ve lo dico ora....è cambiata la forma ma l'algoritmo di verifica è sempre lo stesso ..i vecchi codici di registrazione funzionano lo stesso...se ve lo avessi detto prima chi c...o avrebbe letto questo tut?!?
fine!
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Se avete commenti lamente etc...la mail la avete..leggete in cima alla pagina!scrivetemi pure sarò felice di essere
insultato per il casino... ! :-p
ora se permettete è l'ora dei saluti...altrimenti la mia ex-rag mi uccide:
Allora un saluto particolare và a tutti quelli che mi conoscono,mi aiutano,mi fanno compagnia!
Ai chatters per le ore spese a parlare fondamentalmente di cazzate
A grappolo perchè con lui i viaggi non sembrano mai impossibili....persino fino in Polonia:Grazie Grappolo
Alla Cessa perchè mi sta sempre vicina
Alla Pay,Al Collins A Rex perchè sono amici fidati
A Pao,Ann e Ste che lì vedo sempre
A Corrad che mi aiuta a bere
Allo Zio Jack inseperabile compagnio di serate
A Maria perchè và con tutti ma fa compagnia
ed a tante alte persone.
LordMoon data:16/11/03 time:6.03 (che ci faccio ancora sveglio?)
Note finali |
Spero vi sia piaciuto perchè in seguito vi beccherete il crack di ida 4.5 e di opera 7.0 e tra loro non sono molto diversi...
Disclaimer |
Vorrei ricordare che il software va comprato e non rubato, dovete registrare il vostro prodotto dopo il periodo di valutazione. Non mi ritengo responsabile per eventuali danni causati al vostro computer determinati dall'uso improprio di questo tutorial. Questo documento è stato scritto per invogliare il consumatore a registrare legalmente i propri programmi, e non a fargli fare uso dei tantissimi file crack presenti in rete, infatti tale documento aiuta a comprendere lo sforzo immane che ogni singolo programmatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.
Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.