Vediamo come costringere un programma a svelarci il serial.
(iniezione di codice)

Data

by AciD_LeO

 

30/05/2001

UIC's Home Page

Published by Quequero


Grazie a Dio sono ateo.

Ahhhh e a me non saluti? Ok ok :P Ad ogni modo il tute è chiaro ed oltretutto la tecnica usata dal programma per confonderci è anche simpatica :))) Bravo acid

Datemi un debugger e vi solleverò il mondo :P

....

E-mail: [email protected]

Nick, UIN, canale IRC/EFnet frequentato

....

Difficoltà

( )NewBies (x)Intermedio ( )Avanzato ( )Master

 

Vi avevo promesso di non scrivere mai più un tutorial invece mi sono sbagliato :) (prendetevela con Andreageddon è stato lui a convincermi a continuare)


Facciamo una puntura ad un esegubile.

Written by AciD_LeO


Introduzione

In questo tute non vi spiegherò come visualizzare la solita messagebox con il serial del programma bensì vi mostrerò come ricavarvi l'hwnd della finestra e scrivere direttamente il seriale nell'edit box del programma man mano che l'utente inserisce il nome. (Figo Vero?)

Tools usati

Softice 

Hiew

Un editor esadecimale per appendere alla fine del file 4096 zeri in alternativa usate il codice asm che appendo alla fine del tute :)

PEditor

URL o FTP del programma

Il target sul quale opereremo si chiama CD2HTML (la versione a mia disposizione è la 4.3.1 in italiano  ma credo che nel frattempo ne sia uscita  una nuova :(  se avete qualche difficoltà a procurarla scrivetemi non mancherò di recapitarvela) l'url dal quale procurarlo è http://www.cd2html.de.

Notizie sul programma

CD2HTML è' un utile programma per indicizzare mediante pagine html il contenuto di una qualunque cartella di una qualunque unità disco presente sul vostro sistema la versione proposta dura per 30 giorni e si sblocca con il solito serial di registrazione calcolato in base al nome.

Essay

Facciamo partire il programma subito vi presenterà il nag che vi ricorda che state usando uno shareware premete sul pulsante "inserisci codice di registrazione" e notiamo che il pulsante OK si abilita solo quando il seriale è quello giusto per il nostro nome quindi ogni volta che inseriamo una lettera del nome si calcola il seriale giusto e lo confronta con quello inserito. Bene incominciamo: settiamo un bpx sul solito hmemcpy e inseriamo una lettera del nome Softice popperà in user.dll premete F12 fino a quando non vi troverete nel modulo principale e quindi avremo:

:004B4A79 8B45F0 mov eax, dword ptr [ebp-10]      <---- All'uscita dopo aver premuto F12
:004B4A7C 8D55F4 lea edx, dword ptr [ebp-0C]                un pò di volte ci dovremo trovare qui.
:004B4A7F E8004AF5FF call 00409484
:004B4A84 8B45F4 mov eax, dword ptr [ebp-0C]
:004B4A87 E838F5F4FF call 00403FC4
:004B4A8C 8BD8 mov ebx, eax
:004B4A8E 85DB test ebx, ebx
:004B4A90 7E27 jle 004B4AB9
:004B4A92 B901000000 mov ecx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B4AB7(C)
|
:004B4A97 8B45F4 mov eax, dword ptr [ebp-0C]
:004B4A9A 0FB64408FF movzx eax, byte ptr [eax+ecx-01]
:004B4A9F BA40420F00 mov edx, 000F4240
:004B4AA4 2BD1 sub edx, ecx
:004B4AA6 F7EA imul edx
:004B4AA8 99 cdq
:004B4AA9 0345F8 add eax, dword ptr [ebp-08]
:004B4AAC 1355FC adc edx, dword ptr [ebp-04]
:004B4AAF 8945F8 mov dword ptr [ebp-08], eax
:004B4AB2 8955FC mov dword ptr [ebp-04], edx
:004B4AB5 41 inc ecx
:004B4AB6 4B dec ebx
:004B4AB7 75DE jne 004B4A97

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B4A90(C)
|
:004B4AB9 8D45E8 lea eax, dword ptr [ebp-18]
:004B4ABC 50 push eax
:004B4ABD 8D45F8 lea eax, dword ptr [ebp-08]
:004B4AC0 8945E0 mov dword ptr [ebp-20], eax
:004B4AC3 C645E410 mov [ebp-1C], 10
:004B4AC7 8D55E0 lea edx, dword ptr [ebp-20]
:004B4ACA 33C9 xor ecx, ecx

* Possible StringData Ref from Code Obj ->"%-15x"
|
:004B4ACC B8304B4B00 mov eax, 004B4B30
:004B4AD1 E8825CF5FF call 0040A758
:004B4AD6 8B45E8 mov eax, dword ptr [ebp-18]
:004B4AD9 8D55EC lea edx, dword ptr [ebp-14]
:004B4ADC E8A349F5FF call 00409484
:004B4AE1 8B55EC mov edx, dword ptr [ebp-14]
:004B4AE4 B81C1B4E00 mov eax, 004E1B1C      <- *004E1B1C punta al vecchio serial
:004B4AE9 E8AAF2F4FF call 00403D98               <- dopo questa call viene rinfrescato con il nuovo
:004B4AEE 33C0 xor eax, eax                                      serial calcolato in base all'ultima lettera che abbiamo 
:004B4AF0 5A pop edx                                                aggiunto al nome.
:004B4AF1 59 pop ecx
:004B4AF2 59 pop ecx
:004B4AF3 648910 mov dword ptr fs:[eax], edx
:004B4AF6 68204B4B00 push 004B4B20

Vedete quello  che accade al VA 004B4AEE non vi suggerisce niente? certo questo è il momemto migliore per iniettare il codice che ci visualizza il serial perfetto. Il file è compresso con UPX quindi potete scompattarlo con l'opzione -d (upx.exe -d nomefilecompresso.exe) Per evitare di usare del padding già esistente aggiungiamo una nuova sezione all'eseguibile (non vi spiegherò passo passo come si fa tanto di tute in merito c'è ne stanno una marea) quindi apriamo PEditor (per me pecapolavoroeditor :) ) apriamo il file click sul pulsante section click con destro su una sezione già esistente e "add a section" dal menù a tendina dategli il nome e ok,  editiamo la sezione appena creata per impostare la dimensione mettete Virtual Size e Raw Size a 1000 (è esagerato lo so ma il tute lo scrivo io quindi le dimensioni le decido io ;)) adesso siamo pronti per l'operazione. Aprite il vostro editor esadecimale preferito posizionatevi alla fine del file e appendete 4096 byte che rappresentano la dimensione in decimale della nostra sezione salvate e riapriate il file con Hiew. La nostra sezione inizia a VA 527000(almeno a me inizia lì) raw offeset 11e800(prendete qualunque flc per calcolarlo) quindi andiamo al VA 004B4AEE (premete F5 e digitate l'indirizzo preceduto da un punto quindi .4B4AEE) segniamo da qualche parte i byte che sostituiremo con un jmp nella nostra sezione quindi 33 C0 5A 59 59 sono 5 perché l'opcode dell'istruzione jmp okkupa 5 byte e quindi F3 INVIO per inserire jmp 126400 ma non era 11E800 direte voi ma purtoppo il file non è allineato quindi per calcolarvi questo valore dovete fare RVA SALTO (127000)-(RVA SEZIONE (1000) - RAW OFFSET SEZIONE (400)) allora viene 127000-(1000-400)=126400 maledetti allineamenti. A questo punto ci serve l'hwnd dell'edit box che conterrà il serial e quindi invocare la funzione setwindowtexta bene. Prima di tutto chiamiamo la funzione findwindow per ottenere l'handle della finestra poi con getwindow scendiamo nella gerarchie della finestra fino al nostro edit. Le api che ci servono sono fortunatamente tutte importate dal programma quindi dal disassemblato vediamo che:

GetWindow           ha   RVA 00407E1C

FindWindowA        ha  RVA 00407CB4

SetWindowTextaA ha   RVA 00408054

e sono tutte le funzioni che ci servono adesso il codice:

.00527000: 33C0 xor eax,eax         <- vecchi opcode
.00527002: 5A pop edx
.00527003: 59 pop ecx
.00527004: 59 pop ecx
.00527005: 6660 pusha                 <-salviamo tutti i registri
.00527007: A130755200 mov eax,[000527530]
.0052700C: 83F800 cmp eax,000                  <- abbiamo già calcolato l'hwnd ?
.0052700F: 752C jne .00052703D 
.00527011: 6800755200 push 000527500     <-punta alla stringa "Registra CD2HTML"
.00527016: 6820755200 push 000527520     <-punta alla stringa "TSplash"
.0052701B: E8940CEEFF call .000407CB4  <-chiamata a findwindow
.00527020: 6A05 push 005                            <- costante GW_CHILD
.00527022: 50 push eax                                  <- hwnd del padre
.00527023: E8F40DEEFF call .000407E1C   <- chiamata a getwindow
.00527028: 6A05 push 005                   <-lo stesso gioco di prima per scendere ancora
.0052702A: 50 push eax                            nella gerarchia in quando è presente un pannello
.0052702B: E8EC0DEEFF call .000407E1C
.00527030: 6A02 push 002    <- costante GW_HWNDNEXT
.00527032: 50 push eax          <- hwnd del primo edit box
.00527033: E8E40DEEFF call .000407E1C      <-chiamata a getwindow
.00527038: A330755200 mov [000527530],eax <- salviamo l'hwnd della finestra per evitare di ricalcolarlo
.0052703D: FF351C1B4E00 push d,[0004E1B1C]    <- contiene il serial
.00527043: 50 push eax     
.00527044: E80B10EEFF call .000408054       <- settiamo nella finestra il testo
.00527049: 6661 popa
.0052704B: E9A3DAF8FF jmp .0004B4AF3   <- ritorniamo a  casa

Innanzi tutto le istruzioni che abbiamo sostituito con il jmp poi una popa per salvare tutto e una cmp per vedere se l'HWND era già stato calcolato in precedenza. Credo di dovervi un'ulteriore spiegazione sull'uso di quelle tre Getwindow, bene con con il programma avviato sulla schermata di registrazione andate in softice e digitate HWND CD2HTML comparirà qualcosa di simile:

Window Handle hQueue SZ QOwner Class Name Window Procedure 
03F8(1) 34C7 32 CD2HTML TSplash 0D0F:00000AF6 
  0418(2) 34C7 32 CD2HTML TPanel 0D0F:00000BBC 
     0420(3) 34C7 32 CD2HTML Edit 0D0F:00000BFE 
     041C(3) 34C7 32 CD2HTML Edit 0D0F:00000BE8 
  0410(2) 34C7 32 CD2HTML Button 0D0F:00000BA6 
  040C(2) 34C7 32 CD2HTML Button 0D0F:00000B90 
  03FC(2) 34C7 32 CD2HTML TPanel 0D0F:00000B22 
     0408(3) 34C7 32 CD2HTML Button 0D0F:00000B7A 
     0404(3) 34C7 32 CD2HTML Button 0D0F:00000B64 

Osservate le prime tre righe 03F8 è l'hwnd che troviamo con FindWindowA con la prima GetWindow con parametro GW_CHILD troviamo 0418 che è l'hwnd del primo figlio della finestra la seconda chiamata a GetWindow con GW_CHILD ci fa scendere ancora nella gerarchia fino al primo Editbox che cmq non ci interessa la terza chiamata a GetWindow infine con parametro GW_HWNDNEXT ci fa trovare l'HWND desiderato.  Per inserire gli indirizzi ai JMP e alle CALL usate sempre quella formula però tenete conto che ci troviamo nell'ultima sezione che ha RVA 127000 e offset fisico 11E800 ah naturalmente a VA 527500 e al VA 527520 dovete inserire la due stringhe "Registra CD2HTML" e "Tsplash". E infine eccovi il codice per appendere un padding di zeri alla fine del file (scritto in masm):

.386

.model flat, stdcall

option casemap :none

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc

includelib \masm32\lib\kernel32.lib

.data

Filename db "C:\Programmi\CD2HTML\cd2html.exe",0 ;<-cambiatelo con il nome

; del target sul vostro hard

Buffer db 4096 dup(0)

nsize dd 1000h

hfile dd 0

.code

start:

invoke CreateFile 

,ADDR Filename,GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0

cmp eax,0ffffffffh

je fine

mov hfile,eax

invoke SetFilePointer ,hfile,0,0,FILE_END

invoke WriteFile ,hfile,ADDR Buffer,4096,ADDR nsize,NULL

invoke CloseHandle ,hfile

fine:

invoke ExitProcess,eax ; andiamo a casa

end start

Ciao credo di aver detto tutto vedo di ritornare a studiare.

Note finali

Ringrazio tutti gli amici di #crack-it in particolare Andreageddon, Yado, x86 (che mi ha rimproverato perchè la volta scorsa non l'ho salutato :) ) e F. R. (Dharma) che mi a chiesto un tute sull'iniezione di codice quindi prendetevela anche con lui se avete dovuto subire questo tute. Spero di passare gli esami visto che invece di studiare mi sto cazzeggiando con sto tutorial.

Disclaimer

Qui inserirete con questo carattere il vostro piccolo disclaimer, non è obbligatorio però è meglio per voi se c'è. Dovete scrivere qualcosa di simile a: 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.