API Hooking
Publié : ven. 13/nov./2009 21:40
Voici un exemple de Hook d'API
Je ne peux malheureusement pas vous en expliquer le fonctionnement car c'est un code que j'ai récupérer sur le net; il n'est pas long, encore faut il le comprendre.
[Edit]
Je pense que Denis pourrait nous expliquer plus clairement ce qui se passe
Ce que j'ai compris, c'est qu'à l'adresse de la fonction MessageBox, on écrit en assembleur un saut qui
correspond à jmp(0)=$e9, ensuite on copie l'adresse du saut sur les Bytes suivant:
jmp(1)=$00,jmp(2)=$00,jmp(3)=$00,jmp(4)=$00
par contre, je ne sais pas à quoi correspond jmp(5)=$c3
[/Edit]
J'ai modifier le code d'origine pour qu'il puisse fonctionner en Unicode
Le programme à tester va hooker l'API MessageBoxA (si vous compilez en Ascii)
ou l'API MessageBoxW (si vous compilez en Unicode)
Le programme se compose d'une fenêtre avec un bouton, un clic sur le bouton affiche un MessageRequester -->"MessageRequester("Information","PureBasic")"
Si le Hook réussi, le texte suivant "(MessageBox Hooked)" sera ajouté à "PureBasic"
Voici le code:
Je ne peux malheureusement pas vous en expliquer le fonctionnement car c'est un code que j'ai récupérer sur le net; il n'est pas long, encore faut il le comprendre.
[Edit]
Je pense que Denis pourrait nous expliquer plus clairement ce qui se passe
Ce que j'ai compris, c'est qu'à l'adresse de la fonction MessageBox, on écrit en assembleur un saut qui
correspond à jmp(0)=$e9, ensuite on copie l'adresse du saut sur les Bytes suivant:
jmp(1)=$00,jmp(2)=$00,jmp(3)=$00,jmp(4)=$00
par contre, je ne sais pas à quoi correspond jmp(5)=$c3
[/Edit]
J'ai modifier le code d'origine pour qu'il puisse fonctionner en Unicode
Le programme à tester va hooker l'API MessageBoxA (si vous compilez en Ascii)
ou l'API MessageBoxW (si vous compilez en Unicode)
Le programme se compose d'une fenêtre avec un bouton, un clic sur le bouton affiche un MessageRequester -->"MessageRequester("Information","PureBasic")"
Si le Hook réussi, le texte suivant "(MessageBox Hooked)" sera ajouté à "PureBasic"
Voici le code:
Code : Tout sélectionner
; Exemple de Hook d'API
; On va intercepter l'API MessageBoxA ou MessageBoxW suivant qu'on compile en unicode ou pas
; ainsi on pourra modifier le message affiché
Global Dim hook.b(6)
Global *memoire
Global Library.s
Procedure.l HookFunction( *lpModule.l, *lpFuncName, *lpFunction, *lpBackup)
ModuleHandle=GetModuleHandle_(*lpModule)
Debug ModuleHandle
dwAddr.l=GetProcAddress_(ModuleHandle,*lpFuncName)
Debug dwAddr
Dim jmp.b(5)
jmp(0)=$e9 ;//jmp
;-------------------------
jmp(1)=$00 ;//address
jmp(2)=$00
jmp(3)=$00
jmp(4)=$00
jmp(5)=$c3
ReadProcessMemory_(GetCurrentProcess_(), dwAddr,*lpBackup, 6, 0)
dwCalc.l=(*lpFunction-dwAddr-5); //((to)-(from)-5)
CopyMemory(@dwCalc, @jmp(1), 4); //build the jmp
WriteProcessMemory_(GetCurrentProcess_(), dwAddr, @jmp(), 6, 0)
ProcedureReturn dwAddr
EndProcedure
Procedure.l UnHookFunction(*lpModule,*lpFuncName,*lpBackup)
dwAddr.l=GetProcAddress_(GetModuleHandle_(*lpModule),*lpFuncName);
If (WriteProcessMemory_(GetCurrentProcess_(), dwAddr,*lpBackup, 6, 0))
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure.l MyMessageBox(hWnd.l,*lpText,*lpCaption, uType.l)
UnHookFunction(@Library,*memoire, @hook())
Message.s=PeekS(*lpText)+Chr(13)+"(MessageBox Hooked)"
x.l=MessageBox_(hWnd, Message, PeekS(*lpCaption), uType)
HookFunction(@Library,*memoire, @MyMessageBox(), @hook())
ProcedureReturn x
EndProcedure
Library="User32.dll"
CompilerIf #PB_Compiler_Unicode
API.s="MessageBoxW"
CompilerElse
API.s="MessageBoxA"
CompilerEndIf
Longueur=MemoryStringLength(@API)
*memoire=AllocateMemory(Longueur+1)
PokeS(*memoire, API,-1,#PB_Ascii)
HookFunction(@Library, *memoire, @MyMessageBox(), @hook())
If OpenWindow(0, 0, 0, 222, 200, "ButtonGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 200, 20, "Bouton standard")
Repeat
event=WaitWindowEvent()
Select event
Case #PB_Event_Gadget
Select EventGadget()
Case 0
MessageRequester("Information","PureBasic")
EndSelect
EndSelect
Until event= #PB_Event_CloseWindow
EndIf