Newsgroup: it.comp.programmare.win32
Titolo: Subclassare Procedura in Dll

Un piccolo aiuto!
Sto sviluppando un programma in VB (ver 6 sp3).
Il mio tentativo è quello di sostituire una funzione esportata da una
dll
(di terze parti) con una mia procedura.
Utilizzando l'API LoadLibrary mi prendo l'handle della DLL.
Tramite la funzione GetProcAddress, ottengo l'indirizzo 
alla funzione che mi interessa.
Ora sorgono le difficoltà:
Come faccio a intercettare eventuali chiamate a quella procedura ed
eventualmente
sostituirla con una creata da me???
Anche ammettendo gli Hook Globali c'e' la possibilità di farlo????
Grazie per l'eventaule interessamento.
Martino.


Se la il meccanismo di risoluzione degli entry point nella
DLL e' a Load Time, allora la storia e' pressapoco come segue:
Una chiamata a DLL sara' qualcosa del tipo:
call dwprd ptr[XXXXXXXX] dove l'indirizzo XXXXXXXX
e' situato nella vista mappata della sezione .rdata del tuo file
PE.
Ora, se tu vai a sostituire la DWORD contenuta all'indirizzo
XXXXXXXX con l'indirizzo della tua funzione, il gioco e' fatto.
Peccato che la vista mappata della sezione .rdata sia con l'ttributo
di pagina di sola lettura,  percio' occorre andare di
VirtualQuery e VirtualProtect per rimuovere l'attributo
e modificare la tabella delle funzioni importate dal tuo PE.
Per risalire all'offset nella sezione .rdata della tua funzione,
noto il nome della funzione, occorra fare il lavoro inverso del loader.
I primi DWORD della sezione .rdata sono gli indirizzi in memoria
(cioe' gli indirizzi rispetto al punto di impianto dell'immagine
nello spazio di indirizzamento) della stringa che "descrive"
la funzione.
Esempio:
.rdata viene mappato a 0x2000 a partire dal punto di impianto.
la prima DWORD di .rdata e' 0x000022CC.
Vado al leggere 0x2CC bites dopo l'inizio della prima DWORD e
leggo "GetEnvironmentVariableA".
Quando il file viene caricato in memoria, nella prima DWORD
della sezione .rdata trovo la DWORD 0x77f1a4f6, che, per puro caso,
e' l'indirizzo in memoria della funzione GetEnvironmentVariableA.
Questo metodo funziona se le funzioni della DLL sono risolte a
Link Time e non a Run Time.
Se sono risolte a RunTime, non ti resta che "patchare" il punto di
ingresso della funzione.
Ottenuto l'indirizzo della funzione devi sostituire i primi 6 bytes
con la codifica dell'istruzione "jmp dword ptr[XXXXXXXX]".
In pratica ogni codice che chiama la funzione viene costretto a
saltare alla funzione specificata all'indirizzo XXXXXXXX.
Sent via Deja.com 
http://www.deja.com/
Share what you know. Learn what you don't.

Ti ha detto che lavora in Visual Basic e tu gli rispondi in assembler
:-)))))
Ciao, Giuseppe
---------------------------------------------------------------------------
_Guybrush su IRCNet canale #programmazione
ICQ: 42227764
---------------------------------------------------------------------------

 Ciao, Giuseppe
Almeno ha cercato di darmi una soluzione,
in altri newsgroup, non fanno neanche quello.
Comunque Grazie.

 Ti ha detto che lavora in Visual Basic e tu gli rispondi in assembler
La mia conoscenza dell'argomento si ferma a quello che ho scritto.
Non conosco nulla di VB, ma penso che qualcuno potrebbe
riuscire ad implementare qualcosa con le informazioni fornite.


Vedo che non avete afferrato il senso ironico (vedi ":-))" nel mio reply)
della mia risposta. Ivanbrug ha fatto benissimo a risponderti, solo pensavo
a cosa sarebbe stata utile una risposta in assembler ad una persona che
programma in Visual Basic.......



Ti spiego più in dettaglio a cosa mi servono le informazioni che stò
ricercando.
Da quando esiste Visual Basic, dalla Rel 1 alla 6 (quella attualmente in
distribuzione),
che sia interpretato o compilato, sto' fetente utilizza comunque la
libreria di run-time.
Tu puoi utilizzare un costrutto simile al "try and catch" del C++,
l'ormai famoso "On Error Goto <Etichetta>"
ma se non utilizzi questo costrutto e ti si verifica un errore ti pianta
su una bella MessageBox,
con la frase tipica "Errore di run-time ###..." e con un solo bottone
che ti pianta in asso il programma.
Così se tu hai un database aperto con una query di aggiornamento in
pieno corso magari al 99%, se ne frega nel modo 
più assoluto.
Se riesco ad intercettare la chiamata alla funzione di visualizzazione
dell'errore con una mia procedura che richiami tutti i metodi di
chiusura del programma almeno il sufficiente per salvare i dati sarebbe
una pacchia.
Utilizzando il debugger del VC++ ho individuato la funzione, ma mi
mancano le conoscenza per sostituirmi a 
quella funzione.
Grazie.