Tutorial N°3   16-2-1999

Impariamo ad usare SoftICE

In questo tutorial impareremo ad usare SoftICE, conosceremo l'uso delle varie funzioni ed impareremo anche a modificare il codice di un programma.

SoftICE
Come abbiamo già detto SoftICE ci mostra il codice assembler di un programma, noi poi per scraccherellare il tutto abbiamo bisogno sia di conoscere l'Assembly, sia di saper usare il debugger, infatti come potremmo guidare una macchina senza conoscere il codice stradale e senza avere la patente?
Uno dei comandi che useremo più spesso sarà sicuramente "bpx" cioè breakpoint on execution che in pratica fa poppare Sice quando per esempio viene eseguita una funzione (GetWindowTextA, GetDlgItemTextA, MessageboxA ecc...) ma ovviamente ne esistono altri come per esempio:
 
bmp: breakpoint su un accesso alla memoria (possiamo utilizzarlo per vedere se una funzione legge o scrive su un determinato indirizzo)
 
bpr: bp (breakpoint) su un rango di memoria
 
bpio: bp su un accesso I/O
 
bpint: bp su un interrupt
 
bmsg: bp su un messaggio (lo useremo per brekkare su funzioni come WM_GETTEXT).
 
Task: Questo comando visualizza tutti i processi attivi, viene in genere utilizzato in combinazione con Hwnd.
 
Hwnd: Mostra l'handle delle finestre di un determinato programma.
Ora vi spiegherò meglio come utilizzare questo comando insieme a bmsg.
Per prima cosa scegliete un programma vittima (io userò Hex-Workshop), avviatelo ed aprite la finestra di registrazione, avviate Sice (^D) e scrivete task per vedere con quale nome gira sotto Winzoz l'H-Workshop.
Il nome che appare per primo e che sembra essere l'unico possibile è: Hworks32.
Bene bene, scriviamo: Hwnd Hworks32 e premiamo invio.
Vedrete adesso molte scritte, noi vogliamo cercare l'handle della casella di testo nella quale dobbiamo scrivere il numero seriale, ma come si fà? Bhè l'unico modo che io conosca è scriversi tutti gli handle (prima colonna a sinistra) che presentano l'attributo edit nella colonna class-name (la 4° da sinistra) e poi provarli uno ad uno scrivendo: bmsg xxxx (qui va inserito un handle) wm_gettext, ecco un esempio: task
                                                hwnd hworks32
                                                bmsg 01A5C wm_gettext.
Una volta trovato quello giusto Sice popperà dopo aver premuto il pulsante di registrazione.
 
bd*: Disabilita tutti i bp può essere sostituito p.e. con bd00 (disabilita il 1° bp)
 
be*: Abilita tutti i bp il resto è uguale a "bd"
 
bl: Llista tutti i bp che stiamo utilizzando se appare un "*" il bp è disabilitato
 
bc*: Cancella tutti i bp la sintassi e come bp e be
 
bh: Ci dice tutti i bp che abbiamo usato dall'accensione del pc (molto utile)
 
?: p.e. "? eax" ci dice quale valore esadecimale, decimale ed ASCII contiene eax
 
d: "d eax" dump eax, ci fà vedere il suo indirizzo esadecimale (difficile da dire a parole)
 
code on-off: fà apparire il codice esadecimale di fianco alle istruzioni, ecco un esempio:      015F:00425867             JNZ    00425921   <-------code off
             015F:00425867   751E  JNZ   00425921     <-------code on
                                        |----|<-------codice esadecimale
cercate di tenere questa istruzione sempre abilitata perchè molto importante, ora mi spiegherò meglio: se vogliamo cambiare un JNZ 00425921 in   JMP 00425921 dovremmo aprire l'eseguibile con l'editor esadecimale, cercare 751E e cambiarlo in EB1E, infatti EB significa JMP e 1E significa 00425921, nelle prossime pagine vi mostrerò una tabella con quasi tutti i valori esadecimali delle varie istruzioni, dovrete ricordare sempre che gli ultimi due caratteri (funziona solo per le istruzioni semplici a 4 caratteri, le altre cambiano) di ogni valore indicano l'indirizzo o il registro a cui si riferiscono, quindi dovrete cambiare solo i primi due e non gli ultimi a meno che non vogliate cambiare la direzione del salto oppure il nome del registro. P.E. il valore 85D2 significa: TEST EDX, EDX (ricordate questa istruzione? se no andate al tute N°2) però se lo cambiamo in 85F6 diventerà: TEST ESI, ESI, avete capito? 
 
a (address) : "a 015F:00425867" ci permette di cambiare ciò che si trova all'indirizzo 015F:00425867, una volta premuto invio potremo scrivere per esempio: TEST  EAX, EAX così il jnz verrà cambiato in test...
 
e (address): edit address, con questa funzione non possiamo cambiare le lettere come con "a 015F:00425867" ma dobbiamo agire sui valori esadecimali. Una volta premuto invio apprirà una finestra che mostra i valori, noi andremo a prendere i primi 4 caratteri "751E" ed andremo a scrivere "EB1E", vorrei ricordare che tutti i cambiamenti fatti dal debugger funzionano solo fino a che si riavvia il prog, dopodichè va tutto a farsi benedire.
 
 
 
Funzioni:
 
Visual Basic
__vbastrcmp,__vbastrcomp: Queste istruzioni vengono usate in VB per far comparire le stringhe (non chiedetemi nulla a riguardo visto che non conosco per niente il VB). Per usarle si deve mettere un bp su una delle due, inserire un numero nel box di registrazione, premere ok, aspettare Sice e prima di premere F11 si vede cos'è stato messo nello stack. Si esamina un registro (in genere EBP) in questo modo: dd ebp
e si controllano gli ultimi 8 valori con questo comando: d xxxxxxxx
si potrebbe anche trovare un seriale ;))))
 
__vbaR8Str: non ne sono sicuro ma dovrebbe essere l'equivalente di GetWindowTextA.
 
rtcmsgbox: Questo è MessageboxA in VB
 
C/C++
GetPrivateProfileStringA à Legge il file .INI dove spesso viene registrato il seriale, questa funzione si usa per disabilitare il number check all'avvio del programma.
 
GetWindowTextA à L'abbiamo già usata, comunque serve a copiare ciò che si trva nelle caselle di testo.
 
GetDlgItemTextA à Praticamente ugule alla precedente.
 
hmemcpyà Questa funzione grabba i tasti premuti sulla tastiera e puo essere sfruttata a nostro vantaggio nei sistemi di protezione che non utilizzano funzioni standard (GetWindowTextA, GetDlgItemInt, MessageBoxA ecc...) oppure in quei sistemi che abilitano il pulsante di registrazione solo se il codice è esatto, questo breakpoint funzioni infatti ogni volta che noi premiamo un tasto..bello vero?
Per ora altri comandi non mi vengono in mente.
 
MessageBoxA à Fà apparire un box di messaggio, la possiamo usare per entrare nel codice del programma dopo la "Beggar off" cioè il messaggio che ci dice che abbiamo sbagliato il seriale ecc....
 
GetSystemTime à Vede l'ora del sistema e si usa nei programmi che scadono dopo un'ora, due ore ecc....Per utilizzarla basta mettere un bp su di essa ed avviare il programma.
 
GetLocalTime à Controlla l'ora, il giorno ed il mese. Si usa nei programmi a scadenza di 30, 60, 90 gg ecc....Funziona come la precedente.
 
SetTickCount à Da quello che ho potuto vedere la funz. viene usata spesso per vedere negli shareware quanti giorni mancano all'espirazione del prog.

Cambiamo il codice al programma

Dopo aver scraccherellato per benino il nostro prog e dobbiamo cambiare qualche byte al programma è necessario sapere come cambiare le varie istruzioni, supponiamo di avere un pezzo di codice simile a questo e vediamo come ci dobbiamo comportare...
 
:004010CE 8B06              mov eax, dword ptr [esi]
:004010D0 85C0              test eax, eax
:004010D2 7409              je 004010DD
:004010D4 40                inc eax
:004010D5 E8E6EB0000        call 0040FCC0
:004010DA 83C404 add        esp, 00000004
       ^---codice        ^---istruzioni
           esadecimale
 
Il nostro crack consiste nel cambiare jE 004010DD in JMP 004010DD, per farlo avremo bisogno di cercare quel pezzo di codice esadecimale all'interno dell'H-Workshop. Prendiamo nota di qualche numero prima e dopo del salto come ad esempio 85c0740940E8E6, clicchiamo sul pulsante "find" ed inseriamo quei numeri, il nostro bersaglio è il num. 7409 e per cambiarlo in jmp basterà prendere dalla tabella qui sotto i primi due numeri dell'istruzione JMP e mantenere integri i secondi due, così facendo sostituiremo l'istruzione 7409 in EB09 (vorrei dire che se nel codice del debugger doveste trovare un jump che abbia più di 4 cifre esadecimali allora dovrete usare il comando a xxxxxxxx, fare i cambiamenti a mano e vedere cosa appare in Sice, segnarlo ed andarlo a cambiare nell'editor).
E se il nostro crack avesse richiesto l'eliminazione dell'istruzione inc eax?
In questo caso bastava cercare la solita stringa e cambiare il 40 con 90, questo numero equivale all'istruzione NOP, cioè No Operation, significa che lì non deve succedere nulla e si deve passare oltre.
Se vi capitasse di dover cancellare un'istruzione o di dover lasciare spazi vuoti   (p.e. se 68c88c deve diventare un jmp non potrete mai scrivere ebc88c) ricordate di sostituirli SEMPRE con un NOP.
Se per caso non siete sicuri di qualche cambiamento vi ripeto di provare prima con a xxxxxxxx.
 

Comando

Effetto

Comando

Effetto

EBXX0 JMP 33XX XOR XXX, XXX
75XX JNZ 77XX JA
7CXX JL 76XX JBE
7EXX JLE C3 RET
7DXX JGE FFFF INVALID
7FXX JG 0000 ADD [EAX], AL
73XX JAE 85XX TEST XXX, XXX
74XX JE/JZ 0BXX OR XXX, XXX
F4 HLT 90 NOP
                                                                    Quequero
Passiamo ora al 4° tutorial dove crackeremo un prog facile facile ed impareremo a "patchare" il prog.