Copy Link
Add to Bookmark
Report

Un esempio di dll reversing - come riconfigurare il comportamento di explorer modificando alcune funzioni della libreria SHELL32.DLL

DrWatson's profile picture
Published in 
guide hacker
 · 3 Jun 2018

Salve a tutti!!

Quante volte avete pensato "cacchio se solo potessi evitare di far passare i files per il cestino di Windows quando li elimino...che rottura dover prima cancellare, poi svuotare il cestino, magari anche solo per un file....solo che poi se gli dico di eliminare sempre i files a volte mi trovo in difficolta'..." ??? Bene, se rientrate nella folta schiera (me compreso, altrimenti questo tute non avrebbe mai visto la luce :) di coloro i quali si pongono il problema, beh allora state leggendo il .txt adatto :)

a questo punto permettetemi di spiegarvi sinteticamente un paio di cosette e DISCLAIMARE le mie responsabilita':

UNO : Se apporterete le modifiche che vi indichero' in questo tutorial, non ritenetemi responsabile per perdite accidentali dei vostri dati (il vostro comando ELIMINA da explorer non sara' piu' sicuro come un tempo!! :)

DUE : questo e' un tutorial rivolto al reverse engineering piu' che al cracking. Se avete scaricato questo file credendo di poter sproteggere un programma o crackare un gioco, mi dispiace deludervi ma non troverete niente di simile qui. Vi consiglio di dare un'occhiata ai tutorials su ringzer0.cjb.net - troverete sicuramente qualcosa di vostro gradimento :)

Detto cio'......LET'S GO!!!

allora....come avrete certamente capito dall'intro, in questo tute faremo in modo che quando scegliete una determinata opzione, il vostro fido explorer di Window$ ELIMINERA' fisicamente i files dal disco, senza farli passare dal cestino. "Bella novita'", starete pensando..."lo posso fare pure selezionando l'opzione 'Non spostare i files nel cestino, elimina direttamente' nelle proprieta' del cestino"....ed invece ecco la novita'....che ne direste di un bel dialog box con tre opzioni, UNO=SPOSTA NEL CESTINO, DUE=ELIMINA DAL DISCO e TRE=ANNULLA L'OPERAZIONE ? Esatto....sto parlando di combinare, in qualche arcano modo, le tre cose senza smanettare con le opzioni del cestino (IMPORTANTE: PER SEGUIRE QUESTO TUTE, E SUCCESSIVAMENTE, *DOVETE* LASCIARE L'OPZIONE "SPOSTA NEL CESTINO", NIENTE "ELIMINA DIRETTAMENTE").
Ok, basta chiacchiere....

Contrariamente a quello che qualcuno potrebbe pensare, *NON* e' EXPLORER.EXE che regola le operazioni come cancellare i files, copiarli ecc., ma queste funzioni sono svolte da una DLL (Dynamic Link Library, ovvero un insieme di funzioni che vengono sfruttate da un programma, nel nostro caso EXPLORER.EXE) chiamata SHELL32.DLL e situata sotto WINDOWS\SYSTEM. Niente di grave, tratteremo la DLL come un qualsiasi eseguibile, e i tools saranno gli stessi di sempre:

* W32Dasm v8.93
* SoftICE v3.24
* HIEW v6.01

Bene...ci dovreste essere.
Aprite Shell32.dll con W32dasm....noterete la differenza di image base....non piu' 40000000h come i classici .exe ma 7FDB0000h. Bene, ora aprite Explorer.exe (Gestione Risorse) e create una directory temporanea, riempendola di files inutili copiati da altre dirs. MI RACCOMANDO NON OPERATE CON DIRECTORY GIA' PRESENTI SUL VOSTRO HARD DISK, PERCHE' LE POSSIBILITA' DI PERDERNE I DATI CONTENUTI E' MOLTO ALTA!
Allora...prendete un file a caso della vostra dummy dir e scegliete ELIMINA dal menu FILE (o dal context menu che appare premendo il tasto destro del mouse). Noterete un simpatico dialog che vi chiede se volete spostare xxxx.xxx nel cestino.....benissimo, ecco trovato il nostro hook per accedere al codice. Ad una prima occhiata, e' intuibile che la API su cui breakare e' DialogBoxParamA. E cosi' fate....scegliete NO, entrate in SoftICE, e scrivete

 
"BPX DialogBoxParamA".


Riselezionate "elimina" e sice vi poppera' sullo schermo. premete F12 e sarete di nuovo in pista, stavolta con il dialog sullo schermo. Selezionate SI...Sice ri-poppera', e sarete alla riga successiva al caller del Dialog Box, che e' questa:

 
* Reference To: USER32.DialogBoxParamA, Ord:0084h
|
:7FDE2505 FF15E83DE17F Call dword ptr [7FE13DE8]


Date un'occhiata ad EAX, che come saprete contiene il valore di ritorno di OGNI funzione API.Notate che e' 6. Ora premete F5, e il vostro file verra' spostato nel cestino. Adesso riprovate a scegliere ELIMINA. Noterete che, scegliendo NO, il return value in EAX successivamente al DialogBoxParamA e' = 7. Ripete l'operazione, ma stavolta lasciate perdere il mouse e premete ESC. Il return value sara' 2. quindi possiamo tracciare un semplice schema:

 
VALORE DI RITORNO DALLA CALL DEL DIALOGBOX | TASTO/BUTTON SELEZIONATO | ** SIGNIFICATO **
___________________________________________|__________________________|________________________
| |
00000006 | BUTTON "SI" SUL DIALOG | SPOSTA FILE NEL CESTINO
___________________________________________|__________________________|________________________
| |
00000007 | BUTTON "NO" SUL DIALOG | ANNULLA L'OPERAZIONE
___________________________________________|__________________________|________________________
| |
00000002 | TASTO "ESC" DA TASTIERA | ANNULLA L'OPERAZIONE
___________________________________________|__________________________|________________________


Hmm.....cio' che salta all'occhio qui e' un'inutile ripetizione.....due valori di ritorno svolgono la stessa funzione...sarebbe molto meglio se potessimo modificare il significato del button "NO" sul dialog box....magari redirezionandolo verso l'ELIMINAZIONE FISICA del file selezionato dall'hard disk...In tal modo, senza grosse modifiche al codice avremmo una situazione molto piu' interessante: "SI" sposterebbe il file nel cestino, "NO" lo eliminerebbe fisicamente e "ESC" annullerebbe l'operazione. Vediamo che si puo' fare :)

Cominciamo a tracciare con F10, finche' non arriviamo qui

 
* Referenced by a JUMP at Addresses:
|:7FDE24ED(U), :7FDE2519(C), :7FDE2524(U)
|
:7FDE252B 83FE06 cmp esi, 00000006 ; ESI CONTIENE IL RETURN VALUE
:7FDE252E 751E jne 7FDE254E ; SE NON SI E' SCELTO "SI"
:7FDE2530 8B452C mov eax, dword ptr [ebp+2C]
:7FDE2533 8B00 mov eax, dword ptr [eax] ; BYTE INIZIALE DESCRITTORE OBJECT
:7FDE2535 A810 test al, 10 ; CONTROLLA SE L'OBJECT E' UNA DIR
:7FDE2537 7515 jne 7FDE254E ; SE SI (10=DIR, 20=FILE) SALTA
:7FDE2539 A805 test al, 05 ; SE E' UN FILE....
:7FDE253B 7411 je 7FDE254E ; SALTA COMUNQUE :)
:7FDE253D 85FF test edi, edi
:7FDE253F 7503 jne 7FDE2544
:7FDE2541 8B7D20 mov edi, dword ptr [ebp+20]


Stop! Abbiamo quanto basta a capire che la continuazione naturale della procedura e' a 7FDE254E...dove troviamo questa parte di codice:

 
:7FDE254E 8BC6 mov eax, esi


Il return value viene rimesso in eax, molto bene....siamo sulla strada giusta...il check precedente serviva quindi solo a verificare problemi di memoria o di invalid handle....se c'erano problemi in eax veniva lasciato un dummy value e le operazioni successive non sarebbero andate in esecuzione. Come vedrete shell32.dll e' PIENA di checks di questo tipo...potete pure chiamarlo Good Old Micro$oft Redundant Code (TM) :)

Continuiamo il tracing con SoftICE fino al ret 028...ci ritroveremo qui:

 
:7FDE4093 E810E1FFFF call 7FDE21A8 ;< -- TORNIAMO DA QUESTA CALL
:7FDE4098 8BF8 mov edi, eax

* Referenced by a JUMP at Address:
|:7FDE4064(C)
|
:7FDE409A 83FF06 cmp edi, 00000006 ; DI NUOVO...CHECK SE ABBIAMO PREMUTO SI
:7FDE409D 7540 jne 7FDE40DF ; ALTRIMENTI ELABORA DI CONSEGUENZA
:7FDE409F 8B442434 mov eax, dword ptr [esp+34]
:7FDE40A3 8B08 mov ecx, dword ptr [eax] ; BYTE INIZIALE DESCR. OBJ. IN ECX
:7FDE40A5 F6C110 test cl, 10 ; ABBIAMO UN FILE QUI??
:7FDE40A8 7435 je 7FDE40DF ; SI! SALTA !
:7FDE40AA 81FD00010000 cmp ebp, 00000100 ; O UNA DIR?? (100=DIRECTORY)
:7FDE40B0 7408 je 7FDE40BA
:7FDE40B2 81FD00030000 cmp ebp, 00000300 ; (300=FILE)
:7FDE40B8 7525 jne 7FDE40DF


Benissimo.....ulteriori checks (uff! :)...ora il nostro jne a 409D non saltera' perche' abbiamo scelto "SI", mentre prenderemo quello a 40A8 per ovvi motivi (abbiamo scelto un file:)...ora una premessa e' d'obbligo. Poiche' quello che stiamo per fare e' MOLTO pericoloso per i vostri dati, ho deciso di trattare in questo tutorial SOLO la modifica del codice relativo all'eliminazione di UN SOLO FILE ALLA VOLTA. In altre parole, il file verra' distrutto SOLO quando verra' cancellato DA SOLO. Se decidete di cancellare directories intere, o piu' file alla volta, dovrete servirvi del cestino. Comunque, se siete intenzionati a modificare anche il codice relativo alla cancellazione di piu' files o di una dir intera, vi do un piccolo consiglio...il dialog box e' diverso per quando dovete cancellare piu' files...quindi, un bpx su DialogBoxParamA vi fara' poppare in un altro punto, e troverete semplice orientarvi nello stesso modo in cui stiamo agendo qui. (consiglio nel consiglio ;) : Quando cancellate piu' files potete provare a noppare il mov eax,2 che viene eseguito SIA quando premete ESC SIA quando premete il button "NO"...noppando il mov, avrete la dovuta differenziazione (7 o 2) nel return value, che vi serve a ridirezionare le funzioni anche in tal caso...l'unico problema e' che poi dovrete appendere del codice se questo non e' gia' presente nella dialog procedure, quindi magari dovrete ingrandire l'ultima sezione del pe e...ma hey! questo e' un altro discorso :)

Ritorniamo a noi! :)
I checks ci fanno intuire che la prossima zona di codice per l'elaborazione dei return values, nel caso in cui si e' scelto un file (insomma proprio cio' che ci interessa :) e' a 7FDE40DF.
Ecco qui....

 
:7FDE40DF 83FF02 cmp edi, 00000002
:7FDE40E2 741A je 7FDE40FE
:7FDE40E4 83FF07 cmp edi, 00000007
:7FDE40E7 7415 je 7FDE40FE
:7FDE40E9 837C241C00 cmp dword ptr [esp+1C], 00000000
:7FDE40EE 740E je 7FDE40FE
:7FDE40F0 FF742424 push [esp+24]
:7FDE40F4 56 push esi
:7FDE40F5 FF742434 push [esp+34]
:7FDE40F9 E845EEFFFF call 7FDE2F43

* Referenced by a JUMP at Addresses:
|:7FDE40E2(C), :7FDE40E7(C), :7FDE40EE(C)
|
:7FDE40FE 8BC7 mov eax, edi
:7FDE4100 5D pop ebp
:7FDE4101 5F pop edi
:7FDE4102 5E pop esi
:7FDE4103 5B pop ebx
:7FDE4104 83C418 add esp, 00000018
:7FDE4107 C22400 ret 0024


Altri tre checks....se abbiamo scelto ESC o "NO", il programma esce dalla call (con il ret 024 a 4107) conservando tale valore nel registro, altrimenti esegue una zona di codice, allo scopo di rilevare i dati necessari alla cancellazione del file (con la call a 40F9).
Continuiamo a tracciare con SoftICE, e ci ritroveremo al caller....

 
:7FDE4952 E8A3F6FFFF call 7FDE3FFA ; < --NOI TORNIAMO DA QUESTA CALL
:7FDE4957 83F802 cmp eax, 00000002 ; HAI PREMUTO "ESC" ?
:7FDE495A 0F847F080000 je 7FDE51DF
:7FDE4960 83F806 cmp eax, 00000006 ; HAI SCELTO "SI" ?
:7FDE4963 743F je 7FDE49A4
:7FDE4965 83F807 cmp eax, 00000007 ; HAI SCELTO "NO" ?
:7FDE4968 0F8486070000 je 7FDE50F4

* Referenced by a JUMP at Addresses:
|:7FDE48D1(U), :7FDE50AF(U)
|
:7FDE496E 8945FC mov dword ptr [ebp-04], eax ; SORRY, MA QUI C'E' QUALCOSA CHE
; NON VA...SE EAX NON CONTIENE
; NESSUNO DEI 3 VALORI DI CUI
; SOPRA, ABBIAMO UN INVALID
; HANDLE! MESSAGGIO DI ERRORE!


Wohho! Ecco il codice che ci interessa....il gioco si fa interessante :D
La fortuna ci assiste....abbiamo tre ramificazioni per tre eventuali opzioni...adesso tutto sta a ridirezionare il je relativo alla pressione del button "NO" in una zona di codice diversa, che ELIMINERA' il file dall'hard disk....non avremo bisogno di perdere tempo con le raw sizes e le virtual sizes delle sezioni del pe, e questo e' un bel vantaggio!

Per ora continuiamo a tracciare, per renderci un po' conto di come funzionano le cose...la nostra corsa deviera' a 4963 perche' in questo caso abbiamo scelto "SI"... e ci ritroveremo qui:

 
:7FDE49A4 8B4DF4 mov ecx, dword ptr [ebp-0C]
:7FDE49A7 8B01 mov eax, dword ptr [ecx]
:7FDE49A9 0B45F8 or eax, dword ptr [ebp-08]
:7FDE49AC 3D01020000 cmp eax, 00000201
:7FDE49B1 7725 ja 7FDE49D8
:7FDE49B3 0F8402020000 je 7FDE4BBB
:7FDE49B9 3D01010000 cmp eax, 00000101
:7FDE49BE 0F848E000000 je 7FDE4A52
:7FDE49C4 3D02010000 cmp eax, 00000102
:7FDE49C9 0F84FA000000 je 7FDE4AC9
:7FDE49CF 3D03010000 cmp eax, 00000103
:7FDE49D4 7447 je 7FDE4A1D
:7FDE49D6 EB3E jmp 7FDE4A16


Non fatevi spaventare dal numero dei jumps, se tutto va bene prenderete sempre il JA a 49B1 (non lo prendete se state cancellando un folder, ma gia' al primo file dello stesso saltera'), che vi portera' qui:

 
:7FDE49D8 3D02020000 cmp eax, 00000202
:7FDE49DD 743E je 7FDE4A1D
:7FDE49DF 3D03020000 cmp eax, 00000203
:7FDE49E4 0F84D1010000 je 7FDE4BBB
:7FDE49EA 3D01030000 cmp eax, 00000301
:7FDE49EF 0F84F0030000 je 7FDE4DE5
:7FDE49F5 3D02030000 cmp eax, 00000302
:7FDE49FA 0F843C020000 je 7FDE4C3C
:7FDE4A00 3D03030000 cmp eax, 00000303
:7FDE4A05 0F8444030000 je 7FDE4D4F ; JUMP CHE VERRA' PRESO SE TUTTO VA BENE
:7FDE4A0B 3D04030000 cmp eax, 00000304
:7FDE4A10 0F8499030000 je 7FDE4DAF


Hmmm....sembrano a colpo d'occhio ulteriori checks sulle caratteristiche dei files...lasciamoli stare....il jump che prendera' sempre e' quello a 4A05. Ecco dove conduce:

 
:7FDE4D4F 8B4730 mov eax, dword ptr [edi+30]
:7FDE4D52 85C0 test eax, eax
:7FDE4D54 741C je 7FDE4D72
:7FDE4D56 53 push ebx
:7FDE4D57 8D4DFC lea ecx, dword ptr [ebp-04]
:7FDE4D5A 6A00 push 00000000
:7FDE4D5C 8D95E4FDFFFF lea edx, dword ptr [ebp+FFFFFDE4]
:7FDE4D62 50 push eax
:7FDE4D63 51 push ecx
:7FDE4D64 52 push edx
:7FDE4D65 E815690000 call 7FDEB67F ; CALL DI CONTROLLO OPZIONE "CESTINO ON"
:7FDE4D6A 85C0 test eax, eax ; EAX E' *ZERO* SE CESTINO E' OFF
:7FDE4D6C 0F85ABFCFFFF jne 7FDE4A1D ; HAI IL CESTINO "ON", SALTA E SPOSTA
; I FILES
* Referenced by a JUMP at Address:
|:7FDE4D54(C)
|
:7FDE4D72 8D85E4FDFFFF lea eax, dword ptr [ebp+FFFFFDE4] ; ALTRIMENTI PROCEDI CON
:7FDE4D78 50 push eax ; L'ELIMINAZIONE FISICA DEL
* Reference To: SHELL32.Ordinal:00A4 ; FILE DALL'HD !!
|
:7FDE4D79 E8C7C3FFFF call 7FDE1145
:7FDE4D7E 85C0 test eax, eax
:7FDE4D80 7409 je 7FDE4D8B
:7FDE4D82 C745FC00000000 mov [ebp-04], 00000000
:7FDE4D89 EB09 jmp 7FDE4D94


Eh....sembra che ci siamo :)
Tutto viene giostrato da quella call di controllo opzione a 4D65...se il risultato di quella call e' ZERO, i files verranno cancellati fisicamente, altrimenti verranno spostati nel cestino. Io personalmente ci sono arrivato tracciando passo per passo la call, e segnandomi le differenze nell'esecuzione che si verificano con le due opzioni di cestino "on" e "off". Se vi puo' interessare, la zona di codice in cui viene decisa la sorte di eax in quella call e' quella dei tre jumps agli indirizzi B660, B666 e B66C. Lo xor azzerera' eax e ci restituira' il valore zero, evitando per altro di eseguire una buona parte del codice della call (che serve a preparare lo spostamento del file nel cestino).
Ora quindi sappiamo che, per ELIMINARE fisicamente i files, il nostro programma deve eseguire il codice che parte a 4D72...hey ma cosa vedo?? un jump che porta li'?? hmm, mettiamo un bpx su questo jump (7FDE4D54)...strano, non salta mai....nemmeno quando abbiamo il cestino ad "OFF"...ah! dimenticavo....il solito Redundand Code (TM) della Micro$oft :)))
Ora pero' devo dire che questo jump inutile (vabbeh, saltera' una volta ogni dieci millenni:) mi ha fatto pensare una cosa....se c'e' un jump che evita tutta la zona di codice precedente, non dobbiamo preoccuparci di inserire una flag e farla controllare dopo la call di controllo... si puo' accedere a quel codice anche EVITANDO tutto il check...lo dimostra il fatto che i programmatori hanno inserito nel codice un jump che fa proprio questo....evitare il codice... e' solo una questione di intuizione e logica (chiamiamolo ZEN che mi fa sembrare piu' cool ;) la soluzione a questo punto e' semplicissima......modificheremo il jump relativo al tasto "NO" in modo che esegua DIRETTAMENTE il codice a 7FDE4D72, invece che eseguire le sue inutili funzioni ! Pertanto il primo passo da seguire e' fare un BACKUP del file shell32.dll, chiamandolo ad es. shell32.bak. Poi copiamolo anche su un file temporaneo che andremo a patchare fisicamente (non possiamo patchare shell32.dll perche' non viene scaricato dalla memoria, nemmeno quando chiudiamo explorer.exe). Adesso abbiamo 3 files, shell32.dll, shell32.bak e, diciamo, shell32.new.

La logica ci direbbe di segnarci i due offsets (del je relativo a "NO" e del punto in cui vogliamo che salti), aprire HIEW e patchare come in ogni altro caso...e invece NO! Se tentate questo approcio, al riavvio di Windows con la nuova shell32.dll, premendo "NO" avrete l'amara delusione di un misero GPF...perche'?? La spiegazione e' molto semplice, il motivo purtroppo no....ho pensato ad una differenza di image base, ma gradirei se qualcuno mi spiegasse con certezza il perche' di questo problema. Quando patchiamo con HIEW, e' vero che l'offset a cui diciamo di saltare cambia in 34172h, ma purtroppo, all'esecuzione del jump nella "vita reale:)", la dll saltera' alla RIGA DI CODICE 34172h, NON all'offset 34172h (che e' relativo alla riga di codice 7FDE4D72)....hmmm problemuccio fastidioso eh?? Su, basta un po' di logica....non dimenticatevi MAI della potenza di SoftICE...entrateci e scrivete CODE ON (se non l'avete gia' nella init string)...questa opzione vi permettera' di visualizzare i bytes relativi alle varie istruzioni del codice...adesso mettete un bel bpx su 7FDE4968 (il je relativo alla pressione del button "NO")...per entrare nel codice della dll basta il solito bpx DialogBoxParamA. ora premete "NO" alla richiesta di spostamento del file nel cestino, e vi troverete fermi sulla riga del je su cui abbiamo piazzato il bpx. Se continuate con l'esecuzione causerete un GPF, ma se invece premete A (Assemble instruction), Sice vi dara' un simpatico prompt in cui potrete inserire il codice che volete, relativo alla riga in cui vi trovate. Non dovete far altro che inserirvi "JE 7FDE4D72", e noterete un cambiamento dei bytes a fianco all'istruzione. Prendete un pezzo di carta, e segnatevi per filo e per segno quei bytes. Dovrebbero essere questi: 0F8404040000. Detto cio', uscite da tutto e aprite HIEW con il vostro file temporaneo shell32.new...andate all'offset 33D68h, premete F3 e inserite l'ESATTA sequenza di bytes che vi ha dato SoftICE. Salvate il file, riavviate in modalita' MsDos, andate sotto windows\system e copiate SHELL32.NEW in SHELL32.DLL (che adesso e' sovrascrivibile, perche' non c'e' Windows in esecuzione). Mi raccomando la copia di Backup del file. adesso riavviate Windows.....aprite explorer e provate "elimina" su di un file che non vi interessa...se premete ESC, il file resta li'.....se premete "SI" viene spostato nel cestino...e se premete "NO" il file scompare dall'hard disk!! E' FATTA! :D

__________

Con questo tutorial ho voluto dimostrare come puo' essere semplice fare un po' di sano reversing, e spero che qualcuno abbia imparato qualcosa da questo txt. Se avete problemi a seguire il tutorial o volete chiedermi o comunicarmi qualcosa, il mio indirizzo e' neural_noise@hotmail.com

Detto cio', saluto tutti gli amici da #cracking4newbies, #crack-it e RingZ3r0...e colgo l'occasione per dare il benvenuto ad ALoR nel gruppo!!! :)

till next time......

-NeuRaL_NoiSE 1999

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT