Newsgroup: it.comp.programmare.win32
Titolo: Intercettare API

Ciao,
ho necessita' di intercettare la chiamata ad una API e sostituirla con una
funzione da me fornita (che ritorni le stesse cose e che abbia gli stessi
parametri).
E' possibile!?
Esiste (e se si, qual'e') una utility per tracciare tutte le chiamate alle
API (una sorta di regmon per le API, APIMON?) ?.
Grazie.
--
...:::::>Igor Antonacci
:::::::::>Web Applications Developer
::::::::::>email: 
igo...@libero.it

API (una sorta di regmon per le API, APIMON?) ?.
L'unica cosa che mi viene in mente e' sostituire la DLL che contiene
tale API con un'altra DLL fatta da te con lo stesso nome in modo da
"aggirare" la chiamata. Chiaramente e' un suicidio bello e buono
(dovresti riprodurre TUTTE le API contenute nella DLL, anche quelle
non documentate).
Davide

 wrote in message
news:396b1527...@news.cis.dfn.de...

Si`.  Lo ha fatto NuMega (BoundsChecker), comunque e` un
progetto che ha disperatamente bisogno di essere automatizzato.
Alex

 "aggirare" la chiamata. [...]
C'e` anche la possibilita` di scrivere un driver in kernel mode e
intercettare le chiamate, ma non so se funzioni anche per le DLL in user
mode (in quel caso le chiamate sono dei semplici CALL, non sono fatte
con delle eccezioni come quando si chiama il codice di sistema).
---
Bye! Lorenzo Lutti
http://www.geocities.com/SiliconValley/Peaks/6258/

Nel libro di Richter c'e' un paragrafo sull' API Hooking.
"Lorenzo Lutti" <lorenz...@DOHtiscalinet.it> ha scritto nel messaggio
news:8kfstd$a4v$3...@pegasus.tiscalinet.it...


 Nel libro di Richter c'e' un paragrafo sull' API Hooking.
Intendi "Advanced Windows Programming?" Devo al piu` presto leggere la
nuova edizione... in quella che ho letto qualche anno fa non c'era
niente del genere.
Cosi` per curiosita`, quali sono le soluzioni proposte da Richter?
Un'altra idea simpatica che mi viene in mente potrebbe essere quella di
scrivere un loader che lanci il processo in modalita` sospesa e vada a
modificare direttamente nella memoria tutte le CALL, prima di mandarlo
in run... ma questo e` piuttosto difficoltoso, complesso (di fatto si
deve scrivere un debugger) e non risolve completamente il problema.


 deve scrivere un debugger) e non risolve completamente il problema.
direi che piu' che difficoltoso e' inutile considerato il meccanismo di
binding per un modulo PE (se escludiamo delayed binding e forwarding)..
se quello che ti serve e' un API hooking "per process" direi che invece di
fixare il codice conviene patchare la IAT.. il metodo e' valido per
qualsivoglia piattaforma win32.. fai lo scan della Import Table
dell'eseguibile target, trovi il thunk corrispondente alla API e lo fai
puntare al tuo stub (via VirtualProtectEx, WriteProcessMemory se non ti sei
preventivamente iniettato con un tuo thread).. vviamente il tuo codice deve
essere mappato/bile nell'address space del processo stesso (x win9x puoi
semplicemente usare l'arena shared > 2GB senza tanti patemi, per NT uno dei
consueti sistemi di code/module injection : remote threads,ecc. - ovviamente
per tutto questo i credits vanno al solito Pietrek) . Qualche problema
potresti averlo in win9x se devi hookare un modulo (dll, etc) che ha
preferred baseaddr sopra i 2GB visto che le API Write/ReadProcessMemory,
VirtualProtect/Ex sono intenzinalmente "locked" x indirizzi sopra l'arena
privata (demenzialita' M$) ma puoi ricorrere alla undoc Kernel32!Ord_00010
(VxdCall0) e usare il servizio vwin32_PageModifyPermissions.
Variante piu' fine (nonche' metodo x un hooking system wide se il modulo e'
p.e. kernel32) e' quella di hookare invece che la IAT del modulo che importa
l'API direttamente  l'Export Table del modulo da cui e' importata. In questo
caso ovviamente gli stubs devranno essere mappabili in qualsiasi processo e
dovrai tenere in considerazione nel tuo codice il fatto di trovarti in
processi diversi nel caso tu riceva "objects" per process come handles,etc..
Saluti,
WalkerBoh

 importata.
Stesso dubbio di prima.


 > importata.
anche questo metodo e' concettualmente simile al precedente solo che il
thunk e' quello presente nella ExportTable.. ovvero l'address che, una volta
mappato il modulo, il loader andra' a scrivere nella IAT dell'exe o di
qualunque altro modulo che importi quella API... va da se che in Win9x
hookando in questo modo, se la dll e' shared (il che include kernel32 e
tutte le dll di sistema), l'hook e' a tutti gli effetti system wide. Qui
pero' valgono i caveat del precedente post dato che il tuo codice puo
potenzialmente (ed effettivamente x kernel32,user32,etc..) essere mappato in
qualsiasi address space.
Ops post lughetto.. cmq spero di essermi spiegato chiaramente (visto che
esser chiaro non e' il mio forte =)
Saluti,
 Walker Boh

 esser chiaro non e' il mio forte =)
Ti sei spiegato ottimamente. Una sola cosa: io questa IAT la trovavo in
modo empirico, cercando dei riferimenti all'API in una certa sezione di
memoria (ossia: io trovavo l'indirizzo dell'API, cercavo le locazioni
che contenessero questo indirizzo e poi cercavo delle istruzioni CALL
[indirizzi trovati]). Esiste un modo rigoroso per trovarla? Che so, un
riferimento nell'header PE?


 riferimento nell'header PE?
si, diciamo che nel 90% dei casi con un PE "legacy" il modo migliore e'
servendosi dell'RVA della Import Table  e qui percorrere i vari FirstThunks
di ogni modulo importato (spesso ma non sempre il campo IAT RVA contiene
direttamente l'RVA all'array packed coi vari FirstThunks)...
Cmq per una descrizione abbastanza dettagliata del PE (xchi intende eheh
pubblicita' occulta ;) la trovi a questo link
http://ringzer0.goldrake.com/tutes/pe_tut1.htm
 (che poi e' basato su
articoli/libri di Pietrek, R.Kath, SDK, etc..)
se ti serve quache snippet collaudato per un Import/Export Table
walking/hooking sia a runtime che statico non hai che da chiedere.
Saluti,
 Walker Boh

se quello che ti serve e' un API hooking "per process" direi che [..]
Non ho capito in tutto questo giro come funzionerebbe
l'intercettazioni di DLL caricate a runtime con la LoadLibrary().
Un sistema senza kernel drive dovrebbe esistere perche' per quel che
ne so una ditta italiana di dizionari e traduttori ha fatto questo
(voci di corridoio).
-- 
Tieni per te il Papero se vuoi la mia email
Sito Papero -> 
http://utenti.tripod.it/papero
Recensioni Papere su 
http://www.komix.org

 (voci di corridoio).
se lo fanno under win9x potrebbero aver usato 1 "modalita' undocumented", 2
e 3 ; se il metodo e' compatibile con NT allora senza kernel driver
(necessario x un hooking dei system services)  penso restino solo 2,3..
queste sono solo mie supposizioni e quindi smentibilissime...
Saluti,
  Walker Boh

queste sono solo mie supposizioni e quindi smentibilissime...
Vista che nella ditta in questione ci vado a lavorare tra un mese,
spero di potere chiedere direttamente al creatore. Non so se hanno
accesso all'undocumented.
++++
Non centra niente, ma perche' negli esempi di un tempo dell'SDK vedo
che caricavano le DLL sempre esplicitamente con una LoadLibrary, e
sempre con il numero ordinale? Il che, tra l'altro, implica che le
funzioni di sistema debba avercelo un numero ordinale.
C'e' un motivo per questa abitudine tra i programmatori MS? L'idea del
variabilita' del nome, e della fissita' del numero di ordinale mi ha
sempre lasciato perplesso.


 sempre lasciato perplesso.
a quel che mi risulta il "costume" corretto e' quello di utilizzare il nome
al posto dell'ordinal xche' meno version dependent.. il fatto che alla M$ lo
utilizzino diepende da:
a) abitudine ad utilizzare API non documentate ed esportate solo by ordinal
= malcostume insito nella mentalita' M$ >)
b) l'ordinal e' comodo per evitare di imbattersi in problemi di mangling dei
nomi.. il che capita fra ver diverse di compilatori o per dimenticanza di
dichiarare il .def,_declspec(dllexport),etc. .. c'e' pure un thread recente
c) un risparmio infinitesimale di clicli macchina visto che non si deva fare
un lookup sui nomi
Saluti,
Walker Boh

un lookup sui nomi
Un ciclo macchina e' come risparmiare un cent (Zio Paperone insegna).
In realta' risparmi anche sulla stringa con il nome della funzione.
++++
Sul mio sito Papero c'e' un mediocre articolo su come scrivere le
classiche (e obsolete) DLL da usare al VB. Perche' non lo allarghi con
queste informazioni di basso livello?
E' un peccato che una discussione (per me) cosi' interessante si perda
nel nulla.


 nel nulla.
beh non penso si perda nel nulla visto che ci sono due interlocutori
interessati =).. cmq se avro' tempo magari scrivo qualcosa anche se in
effetti sono tutte piu' o meno informazioni che si trovano in testi (piu' o
meno ufficiali) circolanti nella rete
Saluti,
Walker Boh

meno ufficiali) circolanti nella rete
Bisogna cercare e poi unire. Non sarebbe male un testo unico su un
argomento specifico, p.e. le DLL. Che lo svisceri da tutti i punti di
vista. Dal bassissimo livello, fino a server ATL. 
Ma forse a quel punto avremmo un libro.
++++
In questo momento la cosa che piu' mi sorprende e' il C++. Come
diavolo fa durante una eccezione C++ (no SEH n.d.p.) a cercare nello
stack (se li cerca nello stack) la funzione con il parametro piu'
adatto, e a fare le conversioni al volo del parametro. E poi a gestire
il rilancio dell'eccezione, in cui il parametro tra l'altro torna ad
essere quello originale. Rasenta la magia, ma presumo sia solo mia
incompetenza.
Dal disassemblato non ho capito molto. Probabilmente dovrei stamparmi
il codice e studiarmelo. Presumo pero' che da qualche parte ci sia
spiegato. Purtroppo ho visto un libro per scivere un compilatore C (il
LCC per la precisione) ma niente su compilatori C++ *moderni*.
Hai per caso la soluzione anche a questo mio dubbio?
