Tutorial 3/4

Transcript

Tutorial 3/4
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
:004010D0
:004010D2
:004010D4
:004010D5
:004010DA
8B06
85C0
7409
40
E8E6EB0000
83C404 add
^---codice
esadecimale
mov eax, dword ptr [esi]
test eax, eax
je 004010DD
inc eax
call 0040FCC0
esp, 00000004
^---istruzioni
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
Passiamo ora al 4° tutorial dove crackeremo un prog facile facile ed impareremo
a "patchare" il prog.