Zoom Icon

Iczelion 24

From UIC

Windows Hook

Contents


Infos
Author: §-Death_Reaver-§
Email: death.reaver@leonardo.it
Website: deathreaver.altervista.org
Date: 01/06/2005 (dd/mm/yyyy)
Level: Quite hard
Language: Italian Image:Flag_Italian.gif
Comments:



Introduction

Ristrutturato il 2/01/2007

Un bel giorno decisi di imparare a programmare in assembler. Girando sulla rete inceppai nei FAVOLOSI tutorial di Iczelion sulla programmazione a 32 bit in assembler, non quei pallosi programmi stile dos ma finalmente dialog, finestre ecc.

Pultoppo, andando avanti, notai che la traduzione in italiano arrivava fino al 23 su un totale di 35. Tra i non tradotti c'era anche qualcosa di veramente interessante per il reversing (tipo le DebugApi).

Poi mi sono detto: L'inglese lo conosco percui facciamo un favore alla nazione e traduciamo questi cavolo di tutorial. Questo fu l'inizio…


Tools

Allegato (codice sorgente + eseguibile già compilato)


RadAsm (IDE perfetto per programmare in asm)


Essay

Teoria:

I Windows Hooks possono essere considerati una delle caratteristiche più potenti di windows. Con essi, si può "agganciare" eventi che accadono in un nostro processo o in altri. Con l' "Hooking" dici a windows di una funzione, chiamata filter function (funzione di filtro) o "hook procedure", che verrà chiamata ogni volta che l'evento a cui siamo interessati accade.

Ci sono due tipi di Hook: LOCAL HOOK e REMOTE HOOK.

  1. LOCAL HOOK agganciano un evento che avviene in un nostro processo
  2. REMOTE HOOK agganciano un evento che avviene in altri processi. Ce ne sono due tipi:


Thread-Specific, i quali agganciano eventi che avvengono in uno specifico thread. In poche parole, li userai quando vuoi osservare un evento in uno specifico thread, in un processo specifico. System-wide, che agganciano tutti gli eventi che avvengono in qualsiasi thread di qualsiasi processo nel sistema

Quando installi degli hooks, ricordati che pesano sulla performance del sistema. I System-Wide sono i più instabili. Quando gli eventi scelti passeranno per la nostra filter function, in nostro computer può rallentare di molto. Perciò se decidi di usare i System Hook, dovresti usarli con giudizio e sganciarli appena non ti servono più.


Inoltre, c'è una grande possibilità di crash quando entri in conflitto con altri processi e se ci sono errori nella filter function. In questo caso con esso possono terminare anche altri processi. RICORDA: IL POTERE VA USATO CON RESPONSABILITA'


Prima di usarli con efficienza, dobbiamo capire bene come funzionano gli hook. Quando crei un hook, windows crea una struttura di dati in memoria contenente informazioni dell'hook, e la aggiunge a una linked-list (lista collegata) dove sono presenti tutti gli hook. Il nuovo hook sarà aggiunto davanti agli altri. Quando l'evento scelto accade, se installi un LOCAL HOOK, sarà chiamata la filter-function del processo e così via. Ma, se c'è un REMOTE HOOK, il sistema deve sistemare il codice per l'hook nell' address space degli altri processi. E il sistema lo può fare solo se la funzione (filter-function) risiede in una DLL, perciò, se vuoi usare un REMOTE HOOK, la tua hook procedure deve stare in una DLL. Ci sono solo due eccezioni: JOURNAL RECORD e JOURNAL PLAYBACK HOOKS. La hook procedure di questi due hooks deve risiedere nel thread che li installa. I motivi sono che tutti e due gli hook trattano con intercettazioni di basso livello degli eventi dell'input dell'hardware. Gli eventi di input devono essere registrati/riavviati nell'ordine in cui appaiono. Se il codice è in una DLL, gli eventi di input potrebbero espandersi in altri thread ed è impossibile conoscerne l'ordine. La soluzione sarebbe di mettere la procedura di hook di questi due in un singolo thread, ovvero il thread che li installa.

Ci sono 14 tipi di hooks:

  1. WH_CALLWNDPROC, chiamato quando è chiamato un SendMessage
  2. WH_CALLWNDPROCRET, chiamato quando un SendMessage ritorna
  3. WH_GETMESSAGE, chiamato quando è chiamato un GetMessage o un PeekMessage
  4. WH_KEYBOARD, chiamato quando GetMessage o PeekMessage restituiscono WM_KEYUP o WM_KEYDOWN alla coda di messaggi
  5. WH_MOUSE, quando GetMessage o PeekMessage danno un qualsiasi messaggio del mouse
  6. WH_HARDARE, quando GetMessage o PeekMessage danno un altro messaggio hardware che non sia della tastiera o del mouse
  7. WH_MSGFILTER, chiamato quando in una dialogbox, un menù o una scroll-bar stanno processando un messaggio. Questo hook è locale. È specifico per gli oggetti che hanno un message-loop interno
  8. WH_SYSMSGFILTER, come sopra, solo che è system-wide
  9. WH_JOURNALRECORD, chiamato quando windows restituisce un messaggio dalla coda degli hardware input
  10. WH_JOURNALPLAYBACK, chiamato quando un evento è richiesto dalla coda di sistema degli hardware input
  11. WH_SHELL, chiamato quando succede qualcosa di interessante riguardo la shell come quando la task-bar ha bisogno di ridisegnare i suoi pulsanti.
  12. WH_CBT usato specialmente per i computer-based training
  13. WH_FOREGROUNDIDLE, usato internamente a windows. Poca utilità per applicazioni classiche
  14. WH_DEBUG, usato per debugare la hooking procedure.


Adesso che conosciamo un po' di teoria, possiamo osservare come si installano/disinstallano gli hooks.

Per installare un hook, si usa SetWindowsHookEx:


SetWindowsHookEx PROTO HookType:DWORD, pHookProc:DWORD, hInstance:DWORD, ThreadID:DWORD


  • Hook Type è uno dei valori sopra (WH_*)
  • pHookProc è l'indirizzo della hook procedure che verrà chiamata per processare il messaggio per l'hook specificato. Se è un REMOTE HOOK deve stare in una DLL, altrimenti deve stare nel tuo processo
  • hInstance è l'Instance-handle della DLL che contiene la hook procedure. Se è un hook locale, va impostata su NULL
  • ThreadID è l'ID del thread dove vuoi che l'hook si agganci per spiare. Questo parametro è quello che determina se un hook è local o remote. Se il parametro è NULL, Windows vedrà l'hook come system-wide remote hook che coinvolge tutti i thread del sistema. Se specifichi un ID di un tuo thread in un tuo processo, l'hook sarà local; Se l'ID è di un thread di un altro processo, sarà un thread-specific remote hook. Ci sono due eccezioni a questa regola: WH_JOURNALRECORD e WH_JOURNALPLAYBACK sono sempre local system-wide hooks che non richiedono di stare in una DLL e WH_SYSMSGFILTER è sempre un system-wide remote hook. Quest'ultimo è identico WH_MSGFILTER con ThreadID==0.


Se la chiamata ha successo, eax conterrà l'handle dell' hook. Altrimnti eax sarà NULL. Devi salvare l'handle per "sganciare" l'hook più tardi.


Puoi sganciare un hook chiamando UnhookWindowsHookEx, che prende solo un parametro, l'handle dell'hook che vuoi sganciare. Se la chiamata riesce, eax sarà !=0 altrimenti sarà NULL. Adesso che sai come agganciare/sganciare gli hook, possiamo esaminare la hook procedure. La hook procedure verrà chiamata ogni volta che si presenterà l'evento con coi è stata associata. Per esempio, se installi un WH_MOUSE, quando si presenta un evento da mouse, la hook procedure verrà chiamata. Indipendentemente dal tipo di hook, la hook procedure ha sempre la seguente forma:


<nome> proto nCode:DWORD, wParam:DWORD, lParam:DWORD


  • nCode specifica il codice dell'hook
  • wParam & lParam contengono informazioni extra nell'evento
  • <nome> può essere sostituito con qualsiasi altro nome.


Il significato di nCode, lParam, wParam dipende dal tipo di hook installato. Anche il valore di ritorno varia, per esempio:


WH_CALLWNDPROC

-nCode può essere solo HC_ACTION, che ci dice che c'è un messaggio mandato a una finestra

-wParam contiene il messaggio che è stato mandato

-lParam punta a una struttura CWPSTRUCT

-valore di ritorno non è usato, è zero

WH_MOUSE

-nCode può essere HC_ACTION o HC_NOREMOVE

-wParam contiene il messaggio del mouse

-lParam punta a una struttura MOUSEHOOKSTRUCT

-valore di ritorno zero se il messaggio deve essere processato, 1 se il messaggio sarà scartato


Per avere ulteriori informazioni sul significato dei parametri e dei valori di ritorno, cercare nella vostra guida API.


Ricorda che gli hook sono legati a una linked-list, dove, l'hook più recente è in testa. Quando arriva l'evento, windows chiamerà il primo hook della catena. La responsabilità di chiamare l'hook seguente è della tua hook procedure. Puoi scegliere di non chiamare l'hook seguente, ma sarebbe meglio conoscere quello che stai facendo. La maggior parte delle volte è bene fare pratica chiamando la hook-procedure seguente, in modo che gli altri hook possano avere il proprio turno. Per chiamare l'hook successivo si usa CallNexHookEx che ha il seguente prototipo:


CallNextHookEx proto hHook:DWORD, nCode:DWORD, wParam:DWORD, lParam:DWORD


  • nHook è l'handle del nostro hook. Questa funzione usa questo handle per sfogliarsi la linked-list e per cercarsi la hook procedure da chiamare
  • nCode, wParam e lParam possono essere riempiti con quelli restituiti da Windows


RICORDATE: la hook procedure deve risiedere in una DLL che sarà mappata negli altri processi. Quando windows mappa la DLL nei processi, non mapperà la sezione dati. In poche parole, tutti i processi si condividono una singola copia di codice (hook procedure) ma hanno ognuno la propria DLL nella sezione dati. può essere una brutta sorpresa per gli incauti. Potresti pensare che quando metti un valore in una variabile di una DLL, quel valore sarà condiviso tra tutti i processi che la importano nel loro process-space. Ma non è vero. Nelle situazioni normali, questo comportamento è desiderabile in quanto dà l'illusione che ogni processo abbia la propria DLL. Ma non quando ci sono di mezzo gli hook. Noi vogliamo che la DLL sia UGUALE per tutti i processi, inclusi i dati. SOLUZIONE: bisogna "marcare" la sezione come "condivisa". Puoi farlo specificando gli attributi di sezione della fase di link. Per il masm si fà:


/SECTION:<section name>, S


Il nome dei dati inizializzati è .data e quelli dei dati non-inizializzati è .bss. Per esempio, se vuoi creare una DLL che contenga una hook procedure e vuoi che la sezione di dati non-inizializzati sia condivisa, devi linkare con la seguente riga:


link /section:.bss,S /DLL /SUBSYSTEM:WINDOWS ..........

"S" ci dice che la sezione è condivisa

;------------------------------------ Programma principale----------------------------

.386

.model flat,stdcall (se volete risparmiarvi tutto questo, usate il mio personale include
file allegato Death_Reaver.inc)


option casemap:none



include \masm32\include\windows.inc

include \masm32\include\user32.inc

include \masm32\include\kernel32.inc



include mousehook.inc

includelib mousehook.lib



includelib \masm32\lib\user32.lib

includelib \masm32\lib\kernel32.lib



wsprintfA proto C :DWORD,:DWORD,:VARARG

wsprintf TEXTEQU <wsprintfA>



.const

IDD_MAINDLG equ 101

IDC_CLASSNAME equ 1000

IDC_HANDLE equ 1001

IDC_WNDPROC equ 1002

IDC_HOOK equ 1004

IDC_EXIT equ 1005



WM_MOUSEHOOK equ WM_USER+6



DlgFunc PROTO :DWORD,:DWORD,:DWORD,:DWORD



.data

HookFlag dd FALSE

HookText db "&Hook",0

UnhookText db "&Unhook",0

template db "%lx",0



.data?

hInstance dd ?

hHook dd ?



.code

start:

invoke GetModuleHandle,NULL

mov hInstance,eax

invoke DialogBoxParam,hInstance,IDD_MAINDLG,NULL,addr DlgFunc,NULL

invoke ExitProcess,NULL



DlgFunc proc hDlg:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD



LOCAL hLib:DWORD

LOCAL buffer[128]:byte

LOCAL buffer1[128]:byte

LOCAL rect:RECT

.if uMsg==WM_CLOSE

.if HookFlag==TRUE

invoke UninstallHook

.endif

invoke EndDialog,hDlg,NULL

.elseif uMsg==WM_INITDIALOG

invoke GetWindowRect,hDlg,addr rect

invoke SetWindowPos, hDlg, HWND_TOPMOST, rect.left, rect.top, rect.right, rect.bottom,
SWP_SHOWWINDOW

.elseif uMsg==WM_MOUSEHOOK

invoke GetDlgItemText,hDlg,IDC_HANDLE,addr buffer1,128

invoke wsprintf,addr buffer,addr template,wParam

invoke lstrcmpi,addr buffer,addr buffer1

.if eax!=0

invoke SetDlgItemText,hDlg,IDC_HANDLE,addr buffer

.endif

invoke GetDlgItemText,hDlg,IDC_CLASSNAME,addr buffer1,128

invoke GetClassName,wParam,addr buffer,128

invoke lstrcmpi,addr buffer,addr buffer1

.if eax!=0

invoke SetDlgItemText,hDlg,IDC_CLASSNAME,addr buffer

.endif

invoke GetDlgItemText,hDlg,IDC_WNDPROC,addr buffer1,128

invoke GetClassLong,wParam,GCL_WNDPROC

invoke wsprintf,addr buffer,addr template,eax

invoke lstrcmpi,addr buffer,addr buffer1

.if eax!=0

invoke SetDlgItemText,hDlg,IDC_WNDPROC,addr buffer

.endif

.elseif uMsg==WM_COMMAND

.if lParam!=0

mov eax,wParam

mov edx,eax

shr edx,16

.if dx==BN_CLICKED

.if ax==IDC_EXIT

invoke SendMessage,hDlg,WM_CLOSE,0,0

.else

.if HookFlag==FALSE

invoke InstallHook,hDlg

.if eax!=NULL

mov HookFlag,TRUE

invoke SetDlgItemText,hDlg,IDC_HOOK,addr UnhookText

.endif

.else

invoke UninstallHook

invoke SetDlgItemText,hDlg,IDC_HOOK,addr HookText

mov HookFlag,FALSE

invoke SetDlgItemText,hDlg,IDC_CLASSNAME,NULL

invoke SetDlgItemText,hDlg,IDC_HANDLE,NULL

invoke SetDlgItemText,hDlg,IDC_WNDPROC,NULL

.endif

.endif

.endif

.endif

.else

mov eax,FALSE

ret

.endif

mov eax,TRUE

ret



DlgFunc endp

end start



 ;--------------------------- Codice della DLL-------------------------



.386

.model flat,stdcall

option casemap:none



include \masm32\include\windows.inc

include \masm32\include\kernel32.inc

includelib \masm32\lib\kernel32.lib

include \masm32\include\user32.inc

includelib \masm32\lib\user32.lib



.const

WM_MOUSEHOOK equ WM_USER+6



.data

hInstance dd 0



.data?

hHook dd ?

hWnd dd ?



.code

DllEntry proc hInst:HINSTANCE, reason:DWORD, reserved1:DWORD



.if reason==DLL_PROCESS_ATTACH

push hInst

pop hInstance

.endif

mov eax,TRUE

ret



DllEntry Endp



MouseProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD



invoke CallNextHookEx,hHook,nCode,wParam,lParam

mov edx,lParam

assume edx:PTR MOUSEHOOKSTRUCT

invoke WindowFromPoint,[edx].pt.x,[edx].pt.y

invoke PostMessage,hWnd,WM_MOUSEHOOK,eax,0

assume edx:nothing

xor eax,eax

ret



MouseProc endp



InstallHook proc hwnd:DWORD



push hwnd

pop hWnd

invoke SetWindowsHookEx,WH_MOUSE,addr MouseProc,hInstance,NULL

mov hHook,eax

ret



InstallHook endp



UninstallHook proc



invoke UnhookWindowsHookEx,hHook

ret



UninstallHook endp



End DllEntry



 ;------------------------ MakeFile per la DLL--------------------------



NAME=mousehook

$(NAME).dll: $(NAME).obj

Link /SECTION:.bss,S /DLL /DEF:$(NAME).def /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm\lib
$(NAME).obj

$(NAME).obj: $(NAME).asm

ml /c /coff /Cp $(NAME).asm

Analisi:

L'esempio mostrerà una dialog-box con tre edit-control che andranno riempiti con il nome della classe, l'handle della finestra e l'indirizzo della windows-procedure associata alla finestra su cui è posato il cursore del mouse. Ci sono due pulsanti: "Hook" e "Exit". Quando si preme il pulsante "Hook" il programma aggancia l'input del mouse e il testo del pulsante cambia in "UnHook" (sgancia). Quando si muove il cursore sopra una finestra, le informazioni sulla finestra saranno mostrate sulla finestra principale del nostro programma. Quando si preme il pulsante "UnHook", il programma rimuove l'hook. Il programma principale usa una dialog-box come sua finestra. inoltre si definisce un messaggio personalizzato, WM_MOUSEHOOK che sarà usato come tramite tra il programma e la hook-DLL. Quando il programma riceve tale messaggio, wParam contiene l'handle della finestra dove è il cursore. Naturalmente usare wParam è stata una decisione arbitraria. Ho deciso di mettere l'handle in wParam per semplicità. Puoi scegliere il tuo metodo di comunicazione tra il programma e la hook-DLL a piacere.

.if HookFlag==FALSE
invoke InstallHook,hDlg
.if eax!=NULL
mov HookFlag,TRUE
invoke SetDlgItemText,hDlg,IDC_HOOK,addr UnhookText
.endif

Il programma definisce un flag,HookFlag, per monitorare lo stato dell'hook. È FALSE se l'hook non è installato e è TRUE se l'hook è installato. Quando un utente preme il pulsante "Hook" il programma controlla se l'hook è già stato installato. Se non lo è, chiama la funzione InstallHook della DLL per installarlo. Nota che passiamo l'handle della dialogbox principale come parametro della funzione cosichè la hook-DLL possa inviare i WM_MOUSEMOVE alla giusta finestra, cioè la nostra. Quando il programma è caricato, anche la hook-DLL è caricata. Le DLL sono caricate in memoria immediatamente dopo il programma principale. La funzione di entry-point della DLL è chiamata prima della prima istruzione del programma principale. Perciò quando il programma esegue la DLL, essa è già inizializzata. Noi abbiamo messo il seguente codice nella funzione di entry della hook-DLL:

.if reason==DLL_PROCESS_ATTACH
push hInst
pop hInstance
.endif

Il codice salva la sua l'instance handle in una variabile globale chiamata hInstance per usarla nella funzione InstallHook. Finchè la funzione di entry della DLL è chiamata prima delle altre funzioni, hInstance è sempre valida. Abbiamo messo hInstance nella sezione .data? in modo che sia utilizzabile da tutti i processi. Quando il cursore del mouse punta su una finestra, la hook-DLL è mappata nel processo. Immagina che ci sia già una DLL che occupa l'indirizzo di mappatura della hook-DLL, in questo caso la hook-DLL potrebbe essere rimappata in un altro indirizzo. Il valore di hInstance sarà aggiornato con il nuovo indirizzo. Quando l'utente preme il pulsante UnHook e successivamente Hook, SetWindowsHookEx sarà chiamato di nuovo. Però questa volta userà il nuovo indirizzo come instance handle che sarà sbagliato poiché nell'esempio l'indirizzo di mappatura della hook-DLL non è stato cambiato. L'hook diventerà un hook locale dove puoi agganciare solo gli eventi del mouse della tua finestra. Situazione poco desiderabile.

InstallHook proc hwnd:DWORD
push hwnd
pop hWnd
invoke SetWindowsHookEx,WH_MOUSE,addr MouseProc,hInstance,NULL
mov hHook,eax
ret
InstallHook endp

La funzione InstallHook è molto semplice. Salva l'handle della finestra, passato come suo parametro, in una variabile globale chiamata hWnd per uso futuro. Quindi chiama SetWindowsHookEx per installare un mouse-hook. Il valore di ritorno di SetWindowsHookEx viene messo in un altra variabile globale chiamata hHook per poterla poi usare con UnhookWindowsHookEx. Dopo che SetWindowsHookEx è chiamata, il mouse-hook è funzionante. Quando si verificherà un evento da mouse nel sistema, è chiamata MouseProc (la tua procedura di hook).

MouseProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD
invoke CallNextHookEx,hHook,nCode,wParam,lParam
mov edx,lParam
assume edx:PTR MOUSEHOOKSTRUCT
invoke WindowFromPoint,[edx].pt.x,[edx].pt.y
invoke PostMessage,hWnd,WM_MOUSEHOOK,eax,0
assume edx:nothing
xor eax,eax
ret
MouseProc endp

La prima cosa che fa è chiamare CallNextHookEx per dare agli altri hook la possibilità di processare l'evento del mouse. Dopodichè chiama la funzione WindowFromPoint per prendere l'handle della finestra che è a specifiche coordinate. Notare che usiamo una struttura POINT nella struttura MOUSEHOOKSTRUCT (puntata da lParam) come coordinate attuali del mouse. Poi, mandiamo l'handle al programma principale con PostMessage con il messaggio WM_MOUSEHOOK. Una cosa da ricordare: Non dovresti usare SendMessage dentro la hook-procedure, essa infatti può causare il blocco del messaggio. PostMessage è raccomandato. La struttura MOUSEHOOKSTRUCT è definita sotto:

MOUSEHOOKSTRUCT STRUCT DWORD
pt POINT <>
hwnd DWORD  ?
wHitTestCode DWORD  ?
dwExtraInfo DWORD  ?
MOUSEHOOKSTRUCT ENDS
  • pt è la struttura POINT con le coordinate del cursore del mouse.
  • hwnd è l'handle della finestra che riceverà il messaggio. Di solito è la la finestra dove è il cursore, ma non sempre. Set una finestra chiama SetCapture l'input del mouse non sarà portato a quella finestra. Per questo motivo, non uso il membro hwnd ma invece chiamo WindowFromPoint.
  • wHitTestCode specifica il valore di hit-test. Il valore di hit-test dà più informazioni sulla posizione del mouse. Specifica su quale parte della finestra è il cursore del mouse. Per la lista completa, cerca informazioni su win32.hlp sotto WM_NCHITTEST
  • dwExtraInfo contiene le informazione extra associate col messaggio. Normalmente questo valore è impostato chiamando mouse_event dato dalla chiamata a GetMessageExtraInfo.

Quando la finestra principale riceve WM_MOUSEHOOK, usa l'handle in wParam per prendere informazioni dalla finestra.

.elseif uMsg==WM_MOUSEHOOK
invoke GetDlgItemText,hDlg,IDC_HANDLE,addr buffer1,128
invoke wsprintf,addr buffer,addr template,wParam
invoke lstrcmpi,addr buffer,addr buffer1
.if eax!=0
invoke SetDlgItemText,hDlg,IDC_HANDLE,addr buffer
.endif
invoke GetDlgItemText,hDlg,IDC_CLASSNAME,addr buffer1,128
invoke GetClassName,wParam,addr buffer,128
invoke lstrcmpi,addr buffer,addr buffer1
.if eax!=0
invoke SetDlgItemText,hDlg,IDC_CLASSNAME,addr buffer
.endif
invoke GetDlgItemText,hDlg,IDC_WNDPROC,addr buffer1,128
invoke GetClassLong,wParam,GCL_WNDPROC
invoke wsprintf,addr buffer,addr template,eax
invoke lstrcmpi,addr buffer,addr buffer1
.if eax!=0
invoke SetDlgItemText,hDlg,IDC_WNDPROC,addr buffer
.endif

Pen non commettere errori, controlliamo che il testo che è nelle editbox sia uguale a quello da immettere. Se è uguale, passiamo avanti. Prendiamo il nome della classe chiamando GetClassName, l'indirizzo della windows-procedure chiamando GetClassLong con GCL_WNDPROC e quindi le formattiamo e le mettiamo nei propri edit controls.

invoke UninstallHook
invoke SetDlgItemText,hDlg,IDC_HOOK,addr HookText
mov HookFlag,FALSE
invoke SetDlgItemText,hDlg,IDC_CLASSNAME,NULL
invoke SetDlgItemText,hDlg,IDC_HANDLE,NULL
invoke SetDlgItemText,hDlg,IDC_WNDPROC,NULL

Quando l'utente preme il tasto "UnHook", il programma chiama la funzione UninstallHook dalla hook-DLL. UninstallHook chiama solo UnHookWindowsHookEx. Dopodichè cambia il testo del pulsante di nuovo in "Hook", HookFlag in FALSE e pulisce il contenuto delle edit-controls

Lo switch del linker nel makefile:


Link /SECTION:.bss,S /DLL /DEF:$(NAME).def /SUBSYSTEM:WINDOWS


Specifica la sezione .bss come sezione condivisa per fare in modo che tutti i processi condividano la stessa sezione non-inizializzata della hook-DLL. Senza questo switch, la tua hook-DLL non funzionerebbe.


Note Finali

Prima di tutto ringrazio Iczelion. Senza di lui non avreste letto questo tutorial (l'avete fatto vero?)

Poi ringrazio Quequero, Zero_G e tutti gli appassionati della programmazione in Win32asm


Disclaimer

I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.

Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevoli e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.