Page 2 of 2
Re: Extended Inline API Hooking
Posted: Wed Aug 18, 2010 6:13 pm
by Rescator
I know that, but read the topic title and look at the source in the first post again.
It doesn't really hook the API (OS) function now does it? It just changes the function table pointer (!) in the "current" process,
that's what I reacted too originally when I saw the post.
It's not like I could guess it was Part B of a larger code now could I?
(I just felt like pointing that confusion out as too often people just dump code into Tips'n'Tricks and it's not always easy to know what it's intended for or if it's a complete example or is supposed to be used with other code to really work, I liked how simple it was and felt a need to point out the few issues I found with it.)
Re: Extended Inline API Hooking
Posted: Wed Aug 18, 2010 9:52 pm
by PyroStrex
@Rescator
Hmm, taking all into one post, so basically you want me to do what? Make also an example to demonstrate the injection and ejection process? You should list it down
. I was also trying to improve my code
. Umm, about the Unicode function, can you name one function?
Re: Extended Inline API Hooking
Posted: Wed Aug 18, 2010 10:00 pm
by Thorium
PyroStrex wrote:
Edit: Oh, and can you also tell me what other function that cannot be hooked? ASM view would be nice
For example DbgBreakPoint.
It's only a 2 byte procedure.
Re: Extended Inline API Hooking
Posted: Wed Aug 18, 2010 10:09 pm
by PyroStrex
Thorium wrote:PyroStrex wrote:
Edit: Oh, and can you also tell me what other function that cannot be hooked? ASM view would be nice
For example DbgBreakPoint.
It's only a 2 byte procedure.
Owh, i can do IAT Hooking for this. If fails, EAT Hooking will try to support. But dunno if it will still fail though. I will go and take a look.
Re: Extended Inline API Hooking
Posted: Sun Sep 26, 2010 2:23 am
by PyroStrex
Added The UnHook Function and the example also updated.
Re: Extended Inline API Hooking
Posted: Wed May 21, 2014 2:00 pm
by PureGuy
I know this a bit old topic, but a very useful one.
My ASM knowledge is very poor.
Does anyone now how to get this function working for x64?
Re: Extended Inline API Hooking
Posted: Mon Oct 21, 2019 12:59 am
by Opcode
Updated 5.7X as a module. Removed
OpenProcess so it will only work for the current process that it's running in (you can re-add it if needed).
Detour.pbi
Code: Select all
DeclareModule CHook
Import "Kernel32.lib"
GetProcAddress_(hModule.l, lpProcName.p-ascii) As "_GetProcAddress@8"
EndImport
Declare.b InlineHook(LibraryName.s, LibraryFunction.s, NewFunction.l, OldFunction.l)
Declare.b InlineUnhook(LibraryName.s, LibraryFunction.s, NewFunction.l, OldFunction.l)
EndDeclareModule
Module CHook
; --------------------------------------------------
; Install Hook
; --------------------------------------------------
Procedure.b InlineHook(LibraryName.s, LibraryFunction.s, NewFunction.l, OldFunction.l)
Protected.l OldAddr, NewAddr, RetAddr, CodeAddress, OldProtection
OldAddr = GetProcAddress_(GetModuleHandle_(LibraryName), LibraryFunction)
NewAddr = NewFunction
RetAddr = OldAddr + 5
CodeAddress = VirtualAllocEx_(GetCurrentProcess_(), #Null, 10, #MEM_COMMIT, #PAGE_EXECUTE_READWRITE)
If CodeAddress = #Null
ProcedureReturn #False
EndIf
VirtualProtect_(OldAddr, 5, #PAGE_EXECUTE_READWRITE, @OldProtection)
; Trampoline
CopyMemory(OldAddr, CodeAddress, 5)
PokeB(CodeAddress + 5, $E9)
PokeL(CodeAddress + 6, RetAddr - (CodeAddress + 10))
; JMP To Detour Function
PokeB(OldAddr + 0, $E9)
PokeL(OldAddr + 1, ((NewAddr - OldAddr) - 5))
VirtualProtect_(OldAddr, 5, OldProtection, @OldProtection)
; Update Prototype Pointer To Point To Trampoline
PokeL(OldFunction, CodeAddress)
ProcedureReturn #True
EndProcedure
; --------------------------------------------------
; Remove Hook
; --------------------------------------------------
Procedure.b InlineUnhook(LibraryName.s, LibraryFunction.s, NewFunction.l, OldFunction.l)
Protected.l OldAddr, CodeAddress, OldProtection
OldAddr = GetProcAddress_(GetModuleHandle_(LibraryName), LibraryFunction)
CodeAddress = PeekL(OldFunction)
If CodeAddress = #Null
ProcedureReturn #False
EndIf
; Restore Bytes Of Original Function
VirtualProtect_(OldAddr, 5, #PAGE_EXECUTE_READWRITE, @OldProtection)
CopyMemory(CodeAddress, OldAddr, 5)
VirtualProtect_(OldAddr, 5, OldProtection, @OldProtection)
; Free Trampoline
FillMemory(CodeAddress, 10, 0)
VirtualFreeEx_(GetCurrentProcess_(), CodeAddress, 0, #MEM_RELEASE)
; Update Prototype Pointer To Point To Hook Function
PokeL(OldFunction, NewFunction)
ProcedureReturn #True
EndProcedure
EndModule
Example.pb
Code: Select all
XIncludeFile "Detour.pbi"
Prototype.l RealMessageBoxW(hWnd.l, lpText.s, lpCaption.s, uType.l)
Global o_MessageBoxW.RealMessageBoxW
Procedure.l MyMessageBoxW(hWnd.l, lpText.s, lpCaption.s, uType.l)
ProcedureReturn o_MessageBoxW(hWnd, "MessageBoxW Is Now Hooked!", lpCaption, uType)
EndProcedure
CHook::InlineHook("User32.dll", "MessageBoxW", @MyMessageBoxW(), @o_MessageBoxW)
MessageRequester("Demo", "This Is Test A!")
CHook::InlineUnhook("User32.dll", "MessageBoxW", @MyMessageBoxW(), @o_MessageBoxW)
MessageRequester("Demo", "This Is Test B!")
Re: Extended Inline API Hooking
Posted: Mon Oct 21, 2019 11:50 pm
by Mistrel
I'm not well versed in these kind of things. The example works but it fails for detouring GetTickCount() with an invalid memory access:
Code: Select all
Prototype.l o_GetTickCount()
Global o_GetTickCount.o_GetTickCount
Procedure.l MyGetTickCount()
ProcedureReturn o_GetTickCount()
EndProcedure
CHook::InlineHook("Kernel32.dll","GetTickCount",@MyGetTickCount(),@o_GetTickCount)
MyGetTickCount()
This function doesn't seem to work with the solution from the hot patching thread either:
viewtopic.php?f=12&t=47406
Re: Extended Inline API Hooking
Posted: Tue Oct 22, 2019 5:08 am
by Opcode
Mistrel wrote:I'm not well versed in these kind of things. The example works but it fails for detouring GetTickCount() with an invalid memory access:
Code: Select all
Prototype.l o_GetTickCount()
Global o_GetTickCount.o_GetTickCount
Procedure.l MyGetTickCount()
ProcedureReturn o_GetTickCount()
EndProcedure
CHook::InlineHook("Kernel32.dll","GetTickCount",@MyGetTickCount(),@o_GetTickCount)
MyGetTickCount()
This function doesn't seem to work with the solution from the hot patching thread either:
viewtopic.php?f=12&t=47406
This should work, however retrieving the real tick count via
o_GetTickCount() causes a crash. My guess is it gets patched by jmp unconditionally (e.g. hook has to be removed to call it).
Code: Select all
XIncludeFile "Detour.pbi"
Prototype.i RealGetTickCount()
Global o_GetTickCount.RealGetTickCount
Procedure.i MyGetTickCount()
ProcedureReturn 1337
EndProcedure
Debug GetTickCount_() ; Will display real tick count.
CHook::InlineHook("Kernel32.dll", "GetTickCount", @MyGetTickCount(), @o_GetTickCount)
Debug GetTickCount_() ; Will display 1337 from detour.
Re: Extended Inline API Hooking
Posted: Tue Oct 22, 2019 6:18 am
by Mistrel
Is there a way to fix this to also support calling the old function? I want to adjust the result and need to call the original function for as a reference.
Re: Extended Inline API Hooking
Posted: Tue Oct 22, 2019 7:12 am
by Mijikai
Mistrel wrote:Is there a way to fix this to also support calling the old function? I want to adjust the result and need to call the original function for as a reference.
Either unhook the function, call it and rehook (bad) or you just jump over the opcodes
of the hook by adjusting the function address.
Or be really lazy and call/use the Nt/Rtl/syscall counterpart.
Or hook the IAT to easily call the original function.
Re: Extended Inline API Hooking
Posted: Tue Oct 22, 2019 8:45 am
by Mistrel
I don't understand how to do any of that. Except maybe call the Nt counterpart.
Re: Extended Inline API Hooking
Posted: Tue Oct 22, 2019 8:37 pm
by Opcode
Mistrel wrote:I don't understand how to do any of that. Except maybe call the Nt counterpart.
That's one possibility.
Code: Select all
XIncludeFile "Detour.pbi"
Prototype.l RealGetTickCount()
Global o_GetTickCount.RealGetTickCount
Procedure.l MyGetTickCount()
Protected.l Result = NtGetTickCount_()
ProcedureReturn Result / 2
EndProcedure
Debug GetTickCount_() ; Returns real tick count.
CHook::InlineHook("Kernel32.dll", "GetTickCount", @MyGetTickCount(), @o_GetTickCount)
Debug GetTickCount_() ; Returns real tick count / 2.