Esame UIC n° 3
(Codice Auto-Modificante)


10/10/1999

by "BlackDruiD & Ritz"

 

 

UIC's Home Page

Published by Quequero

Per Bill Gates: che ti possa uscire dal qulo qualcosa che nemmeno la scienza è in grado di identificare.
Bravi black e ritz avete fatto un ottimo tutorial con un solo errore :))))) e poi siete gli unici ad aver usato il form aggiornato :))))
 
UIC's form
rizzatom@keycomm.it (scrivetemi pure qui)
Ritz, 41793377, #crack-it
black_druid@hotmail.com
BlackDruiD, #crack-it
 

UIC's form

Difficoltà

( )NewBies (X)Intermedio ( )Avanzato ( )Master

 

 

Ciao a tutti raga!! Chi vi sta scrivendo come avrete già capito sono BlackDruiD e Ritz. Naturalmente abbiamo scritto questo tute per spiegare la risoluzione dell'esame n° 3 dell'UIC riguardante l'SMC (Codice Auto-Modificante).


 

Esame UIC n° 3
(Codice Auto-Modificante))
Written by BlackDruiD & Ritz

Introduzione

 Il programma una volta avviato richiede un Nome e un Serial ricavato dal nome stesso.

N.B.: Nella stesura del testo BlackDruiD si è occupato principalmente dell'SMC, Ritz del patching, però può essere che in alcuni casi i commenti dell'uno siano stati modificati dall'altro, in entrambi i sensi. Non preoccupatevi se quindi in alcuni casi vedeste dei plurali, poi dei singolari, poi delle forme impersonali, ecc...: non fateci + di tanto caso :))

Tools usati

 SoftIce 3.24 o sup..

W32Dasm (per guardare un po' di roba con calma).

Hex Workshop 2.54 o cmq un aHexEditor (per il patching).

URL o FTP del programma

 http://quequero.cjb.net come sempre ;)

Notizie sul programma 

 Il programma naturalmente è stato scritto per essere crackato. Esso utilizza il metodo di protezione basato sull' SMC.

Essay

Bene bene gente... iniziamo questo faticosissimo tute (intendo da scrivere, spero non da leggere ;) ).

Avviate il programma, vi apparirà la classica schermata che chiede un cazzo di nome e un serial. Inserite due valori a caso, premete "Register" e sperate in una botta di culo... non l'avete avuta? Cazzo ci dispiace per voi... non vi resta che continuare a leggere ;).

Il programma, come avrete notato, non fa comparire alcuna messagebox se il serial è sbagliato, anzi scrivendo un nome a caso e un numero altrettanto randomizzato e premendo "Register" sembra non succedere nulla. Questo cmq per noi non è importante, in quanto è logico che il proggy dovrà pur in qualche maniera accedere a ciò che abbiamo scritto, no?!? OK perfetto, non ci resta che poppare nel Sice (non avreste mai creduto di di dover farlo eh :)) ) con CTRL+D e mettere un bpx su GetWindowTextA. Vi troverete qui:

 

:00401214 E842040000 Call 0040165B

:00401219 8BD0 mov edx, eax

:0040121B 6A28 push 00000028

:0040121D 68AF204000 push 004020AF //Indirizzo in cui viene salvato il nome

:00401222 FF354C204000 push dword ptr [0040204C]

 

* Reference To: USER32.GetWindowTextA, Ord:0000h

|

:00401228 Call 0040165B

:0040122D mov ebx, dword ptr [004020AF]

:00401233 xor ecx, ecx

:00401235 mov esi, 004015C1 //indirizzo dei byte "sorgente"

:0040123A mov edi, 00401265 //indirizzo dei byte "destinazione"

:0040123F mov ecx, 00000001 //numero dei byte da sostituire

:00401244 repz //ripete l'istruzione "movsb"

:00401245 movsb //finchè ecx è diverso da 0

 

Il programma quindi sostituisce 1 byte prendendolo dall'indirizzo "sorgente" (esi) e mettendolo nell'indirizzo "destinazione" (edi). Se andiamo a vedere all'indirizzo "sorgente" troveremo l'istruzione "inc eax" che ha come corrispondente codice macchina (che da ora chiamerò c.m.) il byte 40 (usate l'opzione "code on" in Sice); all'indirizzo "destinazione" invece troveremo l'istruzione "inc ebx" (c.m. 43).

 

:00401246 nop

:00401247 nop

:00401248 push 00000014

:0040124A push 0040209B

:0040124F push dword ptr [0040204C]

 

* Reference To: USER32.GetWindowTextA, Ord:0000h

|

:00401255 Call 0040165B

:0040125A push dword ptr [0040204C]

 

* Reference To: USER32.GetWindowTextLengthA, Ord:0000h

|

:00401260 Call 00401655 //calcola la lunghezza del nome

 

* Jump at Address:

|:004013E1(C) //istruzione prima della modifica effettuata sopra (:00401265 43 inc ebx)

|

:00401265 inc eax //istruzione dopo la modifica. Incrementa di uno la lunghezza del nome

:00401266 mov esi, 0040157C //indirizzo dei byte "sorgente"

:0040126B mov edi, 00401277 //indirizzo dei byte "destinazione"

:00401270 mov ecx, 00000038 //numero dei byte da sostituire

:00401275 repz //ripete l'istruzione "movsb"

:00401276 movsb //finchè ecx è diverso da 0

 

Il programma sostituisce 56 bytes (38 Hex) prendendoli dall'indirizzo "sorgente" e mettendoli nell'indirizzo "destinazione" (401277). I "nuovi" 56 byte sono i seguenti:

 

:0040157C mov dword ptr [0040210F], eax //mette la lung. del nome nell'indirizzo 40210F

:00401581 xor ecx, ecx

:00401583 mov al, byte ptr [ecx+0040209B] //esegue dei calcoli sul nome fino a 4015A2

:00401589 mov edi, 0000000B

:0040158E cdq

:0040158F idiv edi

:00401591 add eax, edx

:00401593 shl eax, 1

:00401595 mov dl, al

:00401597 call 0040160C

:0040159C xor eax, eax

:0040159E mov al, dl

:004015A0 xor al, 81

:004015A2 xor al, 40

:004015A4 mov byte ptr [ecx+004020C7], al //mette i byte calcolati a partire dall'indirizzo 4020C7

:004015AA inc ecx

:004015AB cmp ecx, 00000004 //esegue i calcoli sui primi 4 byte del nome

:004012AE jne 0040127F

:004015B0 nop

:004015B1 nop

:004015B2 nop

:004015B3 nop

 

I vecchi bytes sono questi:

 

:00401277 mov dword ptr [0040210F], ebx

:0040127D xor edx, edx

:0040127F mov al, byte ptr [ecx+0040209B]

:00401285 mov edi, 000000AB

:0040128A cdq

:0040128B idiv edi

:0040128D add eax, ecx

:0040128F shr eax, 04

:00401292 mov cl, dl

:00401294 call 0040160C

:00401299 xor edx, ebx

:0040129B mov bl, dl

:0040129D xor dl, 10

:004012A0 xor bl, 60

:004012A3 mov byte ptr [ecx+0040209B], bl

:004012A9 inc edx

:004012AA cmp edx, 00000009

:004012AD jne 0040127F

--------------------------------------------------

:004012AF mov esi, 00401516 //"sorgente"

:004012B4 mov edi, 004012C0 //"destinazione"

:004012B9 mov ecx, 0000005C //num bytes da cambiare (92)

:004012BE repz

:004012BF movsb

 

I nuovi bytes sono (i vecchi non li metto, sennò viene un file da 10 mb hehehe):

 

:00401516 mov ecx, 00000004

Jump at Address:

|:0040156B(C)

|

:0040151B xor eax, eax

:0040151D mov al, byte ptr [ecx+0040209B] //mette in al un byte del nome

:00401523 cmp ecx, dword ptr [0040210F] //se ecx = lunghezzanome + 1 allora salta a 401572

:00401529 je 00401572

:0040152B mov edi, 00000008 //inizio routine di calcolo

:00401530 cdq

:00401531 idiv edi

:00401533 add al, dl

:00401535 shl al, 03

:00401538 ror al, 1

:0040153A add al, 06

:0040153C shl al, 1

:0040153E xor al, byte ptr [0040210F]

:00401544 mov edi, 00000003

:00401549 cdq

:0040154A idiv edi

:0040154C add al, dl

:0040154E mov dl, al

:00401550 call 0040160C

:00401555 mov al, dl

:00401557 xor al, 82

:00401559 shl al, 02

:0040155C ror al, 02 //fine routine di calcolo

:0040155F mov byte ptr [ecx+004020C7], al //sposta il byte calcolato nell'indirizzo specificato

:00401565 xor eax, eax

:00401567 inc ecx

:00401568 cmp ecx, 00000008 //se ecx = 8 salta a 40151b quindi, dato che il loop iniziava con ecx = 4, significa che il loop stesso viene eseguito max 4 volte

:0040156B jne 004012C5

:0040156D nop

:0040156E nop

:0040156F nop

:00401570 nop

:00401571 nop

 

 

:0040131C mov esi, 004014E5 //"sorgente"

:00401321 mov edi, 0040133F //"destinazione"

:00401326 mov ecx, 00000022 //num bytes da cambiare

:0040132B repz

:0040132C movsb

:0040132D push 00000018

:0040132F push 004020AF

:00401334 push dword ptr [00402050]

 

* Reference To: USER32.GetWindowTextA, Ord:0000h

|

:0040133A Call 0040165B

 

I bytes cambiati sono i seguenti:

 

:004014E5 xor ecx, ecx

 

* Jump at Address:

|:00401505(C)

|

:004014E7 xor eax, eax

:004014E9 mov al, byte ptr [ecx+004020AF] //serial

:004014EF xor al, 81

:004014F1 xor al, 40

:004014F3 mov bl, byte ptr [ecx+004020C7] //buffer contenente i byte ricavati dal calcolo del nome

:004014F9 cmp al, bl

:004014FB jne 00401316

:00401501 inc ecx

:00401502 cmp ecx, 00000004 //il loop viene ripetuto 4 volte

:00401505 jne 004014E7

 

Questa porzione di codice confronta i primi 4 bytes calcolati(che si trovano a partire dall'indirizzo4020C7) con il serial

N.B.: il serial viene XORato 2 volte, viene cioè decrittato.

-------------------------------------------------

:00401361 nop

:00401362 nop

:00401363 mov esi, 004015C3 //"sorgente"

:00401368 mov edi, 00401374 //"destinazione"

:0040136D mov ecx, 00000049

:00401372 repz

:00401373 movsb

--------------------------------------------------

//bytes cambiati (73)

:004015C3 mov ecx, 00000004

* Jump at Address:

|:004015F2(C)

|

:004015C8 xor eax, eax

:004015CA mov al, byte ptr [ecx+004020AF] //serial

:004015D0 cmp ecx, dword ptr [0040210F] //se ecx = lunghezzanome + 1 allora esce dal ciclo

:004015D6 je 004015F4

:004015D8 xor al, 82

:004015DA shl al, 02

:004015DD ror al, 02

:004015E0 mov bl, byte ptr [ecx+004020C7] //codice crittato

:004015E6 cmp al, bl //se il codice e il serial non corrispondono, il prog termina senza messaggi di errore

:004015E8 jne 004013BF

:004015EE inc ecx

:004015EF cmp ecx,00000008 //il loop viene eseguito max 4 volte

:004015F2 jne 004015C8

* Jump at Address:

|:004015D6(C)

|

:004015F4 push 00000020

* Possible StringData Ref from Data Obj ->"SMC - - by Quequero for UIC"

|

:004015F6 push 00402061

* Possible StringData Ref from Data Obj ->"Serial esatto....Bravo!!!!"

|

:004015FB push 00402113

:00401600 push 00000000

:00401602 call BFF5437D

:0040139A jmp 00401170

 

FINE

 

Ed ora una piccola magia del Druido:

 

Black ----------> 486086

Ritz ----------> 62465 (per gentile concessione del Druido Nero) (graaazie Black! n.d.R.)

 

GENERAZIONE DEL SERIALE:

Ora vi spiegherò come viene generato il serial (almeno spero). Eseguite il programma e inserite un nome nel primo box e un seriale nel secondo (io ho usato Black e 11223344) nel sice settate un breakpoint su GetWindowTextaA, ritornate al programma e clikkate sul tasto "Register".

Una volta entrati nel sice disabilitate il bpx e steppate il prog finchè arrivate all'indirizz 40127E.

Ora osservate cosa fa il prog:

 

CALCOLO DELLA PRIMA PARTE DEL SERIALE

:00401581 xor ecx, ecx // ecx = 0

:00401583 mov al, byte ptr [ecx+0040209B] //sposta in al un byte del nome alla volta

:00401589 mov edi, 0000000B //edi = b

:0040158E cdq

:0040158F idiv edi //divide al per 12(edi) e mette il resto in edx

:00401591 add eax, edx //somma eax col resto della divisione

:00401593 shl eax, 1 //shift di un byte verso sinistra

:00401595 mov dl, al //sposta al in dl

:00401597 call 0040160C //funzione di verifica del byte calcolato (vedi sotto ***)

:0040159C xor eax, eax //eax = 0

:0040159E mov al, dl //al = dl

:004015A0 xor al, 81 //XORing di al ("crittazione" del byte)

:004015A2 xor al, 40 //XORing di al("crittazione" del byte)

:004015A4 mov byte ptr [ecx+004020C7], al //mette i byte calcolati a partire dall'indirizzo 4020C7

:004015AA inc ecx

:004015AB cmp ecx, 00000004 //esegue i calcoli sui primi 4 byte del nome

:004015AE jne 00401583

 

Questa routine esegue un calcolo sui primi 4 byte del nome e li salva in un buffer a partire dall'indirizzo 4020C7.

 

*** (questa call verifica che il carattere calcolato sia un numero o una lettera) *** Mica veroooo, hei non ci credo la routine è sempre quella ed ancora non avete capito a che serve? Bhè serve a ridurre il risultato del calcolo in modo da farlo stare in un range di caratteri ASCII accettabile NdQue

:0040160C cmp dl, 7A //confronta dl con 122

:0040160F jg 00401617 //se è maggiore salta a 401617(vedi sotto XXX)

:00401611 cmp dl, 30 //confronta dl con 30

:00401614 jl 00401621 //se è minore salta a ZZZ

 

:00401616 ret //esce dalla call

 

XXX:

:00401617 sub dl, 0A //sottrae A a dl

:0040161A cmp dl, 7A //finchè dl è > 7A(122)

:0040161D jg 00401617

:0040161F jmp 00401616

 

ZZZ:

:00401621 add dl, 0A //somma A a dl

:00401624 cmp dl, 30 //dinchè dl < 30

:00401627 jl 00401621

:00401629 jmp 00401616

 

FINE CALCOLO DELLA PRIMA PARTE DEL SERIALE

 

///////////////////////////////////////////////////////////////////////////

 

CALCOLO DELLA SECONDA PARTE DEL SERIALE (ma porka xxx zio xxx straxxx XXXXX)

 

:00401516 mov ecx, 00000004 //ecx = 4

:0040151B xor eax, eax //eax = 0

:0040151D mov al, byte ptr [ecx+0040209B] //mette in al un byte del nome

:00401523 cmp ecx, dword ptr [0040210F] //se ecx = lunghezzanome+1 allora esce dal ciclo

:00401529 je 00401572

:0040152B mov edi, 00000008 //edi = 8

:00401530 cdq

:00401531 idiv edi //divide al per 8 e mette il resto in edx

:00401533 add al, dl //somma al al resto della divisione

:00401535 shl al, 03 //shift di tre byte verso sinistra (al*8)

:00401538 ror al, 1 //shift verso destra con riporto di un byte

:0040153A add al, 06 //al + 6

:0040153C shl al, 1 //shift di tre byte verso sinistra (al*2)

:0040153E xor al, byte ptr [0040210F] //XORing di al con lunghezzanome+1

:00401544 mov edi, 00000003 //edi = 3

:00401549 cdq

:0040154A idiv edi //divide al per 3(edi) e mette il resto in edx

:0040154C add al, dl //al + resto della divisione

:0040154E mov dl, al //dl = al

:00401550 call 0040160C //controlla il byte(come spiegato sopra)

:00401555 mov al, dl //al = dl

:00401557 xor al, 82 //XORing di al con 82

:00401559 shl al, 02 //shift di 2 byte verso sinistra(al*4)

:0040155C ror al, 02 //shift verso destra con riporto di due byte

:0040155F mov byte ptr [ecx+004020C7], al //sposta il byte calcolato nell'indirizzo specificato (4 byte + avanti rispetto alla prima parte del codice calcolata in precedenza)

:00401565 xor eax, eax

:00401567 inc ecx

:00401568 cmp ecx, 00000008 //se ecx = 8 salta a 40151b quindi, dato che il loop iniziava con ecx = 4, significa che il loop stesso viene eseguito max 4 volte.

Inoltre dato che all'inizio della routine ecx valeva 4 e che al massimo può arrivare a 8, significa che vengono presi in considerazione al massimo 8 byte del nome.

:0040156B jne 004012C5

 

FINE CALCOLO DELLA SECONDA PARTE DEL SERIAL

 

//////////////////////////////////////////////////

 

VERIFICA DELLA PRIMA PARTE DEL SERIAL

 

:004014E5 xor ecx, ecx //ecx = 0

:004014E7 xor eax, eax //eax = 0

:004014E9 mov al, byte ptr [ecx+004020AF] //muove in al un byte del serial

:004014EF xor al, 81 //XORing di al con 81

:004014F1 xor al, 40 //XORing di al con 81

:004014F3 mov bl, byte ptr [ecx+004020C7] //sposta in bl un byte del serial precedentemente calcolato

:004014F9 cmp al, bl //confronta un byte del serial calcolato con quello inserito nella editbox

:004014FB jne 00401316 //se sono diversi esce dal ciclo e dal prog

:00401501 inc ecx

:00401502 cmp ecx, 00000004 //il loop viene ripetuto 4 volte

:00401505 jne 004014E7

 

Questa porzione di codice confronta i primi 4 bytes calcolati(che si trovano a partire dall'indirizzo 4020C7) con il serial.

N.B. il serial viene XORato 2 volte, viene cioè decrittato.

 

FINE DELLA VERIFICA DELLA PRIMA PARTE DEL SERIAL

 

///////////////////////////////////////////////////////////////////////////////////

 

VERIFICA DELLA SECONDA PARTE DEL SERIAL

 

:004015C3 mov ecx, 00000004 //ecx = 4

:004015C8 xor eax, eax //eax = 0

:004015CA mov al, byte ptr [ecx+004020AF] //serial

:004015D0 cmp ecx, dword ptr [0040210F] //se ecx = lunghezzanome + 1 allora esce dal ciclo

:004015D6 je 004015F4

:004015D8 xor al, 82 //XORing di al con 82

:004015DA shl al, 02 //shift di 2 byte verso sinistra(al *4)

:004015DD ror al, 02 //shift con riporto di 2 byte

:004015E0 mov bl, byte ptr [ecx+004020C7] //sposta in bl un byte del codice crittato

:004015E6 cmp al, bl //se il codice e il serial non corrispondono, il prog termina senza messaggi di errore

:004015E8 jne 004013BF

:004015EE inc ecx

:004015EF cmp ecx,00000008 //il loop viene eseguito max 4 volte

:004015F2 jne 004015C8

//se tutto va bene il programma vi mostrerà una messagebox che si complimenta con voi

* Jump at Address:

|:004015D6(C)

|

:004015F4 push 00000020

* Possible StringData Ref from Data Obj ->"SMC - - by Quequero for UIC"

|

:004015F6 push 00402061

* Possible StringData Ref from Data Obj ->"Serial esatto....Bravo!!!!"

|

:004015FB push 00402113

:00401600 push 00000000

:00401602 call BFF5437D

:0040139A jmp 00401170

 

FINEEEEEEEEEEEEEE!!!!!!!!!!!

 

Puttana troia gente, scusate il termine ma cazzo che fatica arrivare fin qui!! Bene... a questo punto voi sarete o già in stato comatoso, o a divertirvi da qualche parte, o a crogiolarvi del fatto che dopo tanta fatica finalmente avete reversato il programz. Per questi ultimi diciamo: poveri illusiiiii!!!!!!! Eheheheheh non è stato ancora trattato un altro obbiettivo: il patching del proggy.

Allora, voi avete trovato il serial, e fin qui OK... ora però dovete fare in modo che OGNI codide da voi inserito risulti valido. E ALLORA? E allora continuate a leggere... :))

Dunque, io ho fatto così: ho messo un bpx su GetWindowTextA, ho premuto 3 volte CTRL+D una volta che il Sice poppava, quindi ho premuto F11, e mi sono trovato akkì (copio direttamente dal Sice):

:0040132D push 18

push 4029AF

push dword ptr [402050]

CALL! USER32. GetWindowTextA

:00401441 xor ecx, ecx

xor eax, eax

mov al, [ecx+4020AF] //prima lettera serial in al

xor al, 81

xoa al, 40

mov bl, [ecx+4020C7]

cmp al, bl

jnz 401170 //FUCK OFF

inc ecx

cmp ecx, 06

jnz 401441 //FUCK OFF 2

nop

nop

mov esi, 4015C3

mov edi, 401374

mov ecx, 49

repz movsb

mov ecx, 4

xor eax, eax

mov al, [4020AF]

cmp ecx, [40210F]

jz 4013A5 //congratulazioni

xor al, 82

shl al, 02

ror al, 02

mov bl, [ecx+4020C7]

cmp al, bl

jnz 401170

inc ecx

cmp ecx, 08

jnz 401379

 

Come potete vedere, questa sezione non penso richieda molte spiegazioni: viene messa la prima lettera del serial in al, viene xorata e poi confrontata con bl (contenente in 1° char di 4020C7). Se i valori coincidono, va avanti, altrimenti siamo già fregati. OK vabbè sapendo che il ns. serial è sbagliato, steppiamo fino a "jnz 401170" e scriviamo "r fl z" per invertire il valore dello zero flag. Andiamo avanti. Vediamo subito dopo un altro cmp tra ecx e 06. Hum non convince: se steppiamo andiamo a finire male... scriviamo anche lì "r fl z". Avanti ancora: steppiamo fino a "jz 4013A5"... proviamo a fare "d 40210F" (ciò con cui viene comparato ecx). CAZZOOOO!!! Il msg di congratulazioni!!! Bene, scriviamo l'ultimo "r fl z" e... siamo registrati con dati a caso!!! OK siamo a buon punto. Ora fate così: settate nel Sice il "code on" e segnatevi gli opcodes dei 3 indirizzi visti sopra (quelli dove è stato cambiato il falg). Dovrebbero essere rispettivamente:

 

1- 0F8115FEFFFF

2- 75E0

3- 741C

 

Ora aprite l'Hex Workshop e cercate il primo mucchio di bytes (naturalmente da menu Edit/Find). Ci siete arrivati? Bene: dovrebbe essercene solo uno così: si tratta di un jnz che porta allo scazzamento del prog, quindi bisognerà nopparlo tutto scrivendo 909090909090 (90 x 6 volte). Cercate ora il secondo mucchio di byte, che naturalmente è lì vicino. Anch'esso è un jnz ma che occupa 2 bytes, quindi scrivete 9090. Cercate ora l'ultimo mucchio. Trovato? Esso NON è un jnz, ma un jz, quindi bisognerà fare in modo che il salto alla messagebox di conferma venga eseguito SEMPRE. Cambiate di conseguenza 74 con EB (jmp).

Salvate il tutto, avviate il file crackato, scrivete due robe a cazzo, e... yeahhhhhh appare la messagebox di conferma!!! Benissimo gente, ora possiamo proprio dire di aver finito. Dio santo era ora direte voi!! Eheheh mi sa proprio di si.

Sperando che il presente tute possa aver avuto favorevoli risvolti nella vostra carriera crackistica, porgiamo loro i più distinti auguri di HAPPY CRACING!!!

Ciao a tutti ragaaaaaaaaaaaaaa!!

 

                                                                                                                 BlackDruiD & Ritz

Note finali

Io (Ritz), vorrei ora ringraziare Black innanzi tutto per il fatto di aver accettato di fare l'esame insieme e per essersi occupato della sezione "reversing". Naturalmente un saluto va anche al carissimo prof. Que Eddai prof nooooooo :)))))) NdQue, ai compagni di classe, e a tutto il chan #crack-it e #UIC dove lo metti? NdQue. Non ho voglia di dilungarmi oltre perchè sono letteralmente finito dopo aver passato 3 ore di fila a scrivere tutta 'sta roba.

Disclaimer

Vorremmo ricordare che il software va comprato e non rubato, dovete registrare il vostro prodotto dopo il periodo di valutazione. Non ci riteniamo responsabili 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.


 

 
UIC's page of reverse engineering, scegli dove andare:

Home   Anonimato   Assembly    ContactMe  CrackMe   Links   
NewBies   News   Forum   Lezioni  
Tools   Tutorial 

UIC