My inspiration : http://help.madshi.net/ApiHookingMethods.htm
Please do not use it for creating malware or anything like it. Use it to help others is fully recommended.
Tested with PureBasic 4.50
The Hook Function :
Code: Select all
Procedure.i InlineHook(LibraryName$, LibraryFunction$, NewFunction.l, OldFunction.l)
DLLHandle.l = LoadLibrary_(LibraryName$)
OldAddr.l = GetProcAddress_(DLLHandle, LibraryFunction$)
NewAddr.l = NewFunction
RetAddr.l = OldAddr + 5
processHandle.l = OpenProcess_(#PROCESS_ALL_ACCESS, #False, GetCurrentProcessId_())
codeAddress.l = VirtualAllocEx_(processHandle, NULL, 9, #MEM_COMMIT, #PAGE_EXECUTE_READWRITE)
If codeAddress = 0
Debug "Failed to allocate memory address"
ProcedureReturn #False
EndIf
PokeW(codeAddress, PeekW(OldAddr))
PokeB(codeAddress+2, PeekB(OldAddr+2))
PokeW(codeAddress+3, PeekW(OldAddr+3))
PokeB(codeAddress+5, $E9)
PokeI(codeAddress+6, RetAddr - (codeAddress + 10))
VirtualProtect_(OldAddr, $05, #PAGE_EXECUTE_READWRITE, @OldProtection)
PokeB(OldAddr, $E9)
PokeI(OldAddr+1, ((NewAddr - OldAddr) - 5))
PokeL(OldFunction, codeAddress)
CloseHandle_(processHandle)
EndProcedure
Procedure.i InlineUnhook(LibraryName$, LibraryFunction$, NewFunction.l, OldFunction.l)
DLLHandle.l = LoadLibrary_(LibraryName$)
OldAddr.l = GetProcAddress_(DLLHandle, LibraryFunction$)
codeAddress = PeekL(OldFunction)
processHandle.l = OpenProcess_(#PROCESS_ALL_ACCESS, #False, GetCurrentProcessId_())
VirtualProtect_(OldAddr, $05, #PAGE_EXECUTE_READWRITE, @OldProtection)
If codeAddress = 0
Debug "Failed to get that code Address"
ProcedureReturn #False
EndIf
PokeW(OldAddr, PeekW(codeAddress))
PokeB(OldAddr+2, PeekB(codeAddress+2))
PokeW(OldAddr+3, PeekW(codeAddress+3))
FillMemory(codeAddress, 9, 0)
PokeL(OldFunction, NewFunction)
VirtualFreeEx_(processHandle, codeAddress, 0, #MEM_RELEASE)
CloseHandle_(processHandle)
EndProcedure
Code: Select all
Prototype.l proMessageBox(hwnd.l, lpText.s, lpTitle.s, Type.i)
Global oldMessageBox.proMessageBox
Procedure.i InlineHook(LibraryName$, LibraryFunction$, NewFunction.l, OldFunction.l)
DLLHandle.l = LoadLibrary_(LibraryName$)
OldAddr.l = GetProcAddress_(DLLHandle, LibraryFunction$)
NewAddr.l = NewFunction
RetAddr.l = OldAddr + 5
processHandle.l = OpenProcess_(#PROCESS_ALL_ACCESS, #False, GetCurrentProcessId_())
codeAddress.l = VirtualAllocEx_(processHandle, NULL, 9, #MEM_COMMIT, #PAGE_EXECUTE_READWRITE)
If codeAddress = 0
Debug "Failed to allocate memory address"
ProcedureReturn #False
EndIf
PokeW(codeAddress, PeekW(OldAddr))
PokeB(codeAddress+2, PeekB(OldAddr+2))
PokeW(codeAddress+3, PeekW(OldAddr+3))
PokeB(codeAddress+5, $E9)
PokeI(codeAddress+6, RetAddr - (codeAddress + 10))
VirtualProtect_(OldAddr, $05, #PAGE_EXECUTE_READWRITE, @OldProtection)
PokeB(OldAddr, $E9)
PokeI(OldAddr+1, ((NewAddr - OldAddr) - 5))
PokeL(OldFunction, codeAddress)
CloseHandle_(processHandle)
EndProcedure
Procedure.i InlineUnhook(LibraryName$, LibraryFunction$, NewFunction.l, OldFunction.l)
DLLHandle.l = LoadLibrary_(LibraryName$)
OldAddr.l = GetProcAddress_(DLLHandle, LibraryFunction$)
codeAddress = PeekL(OldFunction)
processHandle.l = OpenProcess_(#PROCESS_ALL_ACCESS, #False, GetCurrentProcessId_())
VirtualProtect_(OldAddr, $05, #PAGE_EXECUTE_READWRITE, @OldProtection)
If codeAddress = 0
Debug "Failed to get that code Address"
ProcedureReturn #False
EndIf
PokeW(OldAddr, PeekW(codeAddress))
PokeB(OldAddr+2, PeekB(codeAddress+2))
PokeW(OldAddr+3, PeekW(codeAddress+3))
FillMemory(codeAddress, 9, 0)
PokeL(OldFunction, NewFunction)
VirtualFreeEx_(processHandle, codeAddress, 0, #MEM_RELEASE)
CloseHandle_(processHandle)
EndProcedure
Procedure.l hookedMessageBox(hwnd.l, lpText.s, lpTitle.s, Type.i)
ProcedureReturn oldMessageBox(hwnd, "This is inside the hooked function!", lpTitle, Type)
EndProcedure
InlineHook("user32.dll", "MessageBoxA", @hookedMessageBox(), @oldMessageBox)
MessageRequester("Extended Inline API Hooking Example", "Testing this Extended Inline API Hooking system")
InlineUnhook("user32.dll", "MessageBoxA", @hookedMessageBox(), @oldMessageBox)
MessageRequester("Extended Inline API Hooking Example", "It is now unhooked!.")
Update Code: Instead of using Poke 3 Times and Peek 3 Times, I replaced it with CopyMemory()
I know it isn't fully complete yet.