This is one of the topic that most of you will found it interesting to read. This time, I shared one of my latest achievement while using PureBasic. The Function Hooking method. Some of you might also called it as "API Hooking method". It can hook many of simple Windows API procedure for example:
I though i should share it for future benefit and also for my future reference. Just a simple inline API hooking with the ability to call the old function back. It took me 1 week to fully complete this . So here goes... I re-post this here so that much more people can look into this code and study it, use it or do anything with it (Improving it perhaps?).
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 :
[UPDATE] : Added InlineUnhook since I needed it inside my project.
[UPDATE] : Instead of using Poke 3 Times and Peek 3 Times, I replaced it with CopyMemory()
I know this isn't fully complete yet.
- Winsock Function.
This is the most fun function that people is trying to hook all the time. - MessageBoxA.
Perhaps you wanna try the code? - Many more others that have the same function header like the functions above.
I though i should share it for future benefit and also for my future reference. Just a simple inline API hooking with the ability to call the old function back. It took me 1 week to fully complete this . So here goes... I re-post this here so that much more people can look into this code and study it, use it or do anything with it (Improving it perhaps?).
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 :
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) EndProcedureThe working example:
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] : Added InlineUnhook since I needed it inside my project.
[UPDATE] : Instead of using Poke 3 Times and Peek 3 Times, I replaced it with CopyMemory()
I know this isn't fully complete yet.
No comments:
Post a Comment