Skip to content

Unable to hook DestroyCaret function from user32 module #4

@rommar

Description

@rommar

I want to hook CreateCaret and DestroyCaret functions from user32.dll. Hooking CreateCaret works ok, but DestroyCaret - no.

#include <Windows.h>

typedef BOOL(WINAPI *CreateCaretFuncPtr)(
	_In_ HWND hWnd,
	_In_opt_ HBITMAP hBitmap,
	_In_ int nWidth,
	_In_ int nHeight);

typedef BOOL(WINAPI *DestroyCaretFuncPtr)(VOID);

static CreateCaretFuncPtr CreateCaretOrigFuncPtr = NULL;
static DestroyCaretFuncPtr DestroyCaretOrigFuncPtr = NULL;

static BOOL WINAPI MyCreateCaret(
	_In_ HWND hWnd,
	_In_opt_ HBITMAP hBitmap,
	_In_ int nWidth,
	_In_ int nHeight)
{
	return CreateCaretOrigFuncPtr(hWnd, hBitmap, nWidth, nHeight);
}

static BOOL WINAPI MyDestroyCaret(VOID)
{
	return DestroyCaretOrigFuncPtr();
}

In main function I have:

HMODULE user32ModuleHandle = GetModuleHandle(L"User32");
CreateCaretOrigFuncPtr = (CreateCaretFuncPtr)GetProcAddress(user32ModuleHandle, "CreateCaret");
DestroyCaretOrigFuncPtr = (DestroyCaretFuncPtr)GetProcAddress(user32ModuleHandle, "DestroyCaret");
// will be true
bool createHookSetOk = Mhook_SetHook((PVOID*)&CreateCaretOrigFuncPtr, MyCreateCaret);
// will be false
bool destroyHookSetOk = Mhook_SetHook((PVOID*)&DestroyCaretOrigFuncPtr, MyDestroyCaret);

I studied a bit how mhook works under the hood and I see that the first call to DisassembleAndSkip in Mhook_SetHookEx returns instruction length of 5 bytes for CreateCaret, but 2 bytes for DestroyCaret. ollydbg shows that CreateCaret starts with MOV EAX,1032 (5 bytes long) while DestroyCaret is

759B38C7   6A 06            PUSH 6
759B38C9   E8 1F28FFFF      CALL USER32.759A60ED
759B38CE   C3               RETN

First instruction for DestroyCaret is PUSH which takes 2 bytes. So DisassembleAndSkip returns 2 bytes and we go to else block where a check for IsJumpPresentInFirstFiveBytes takes place. IsJumpPresentInFirstFiveBytes returns false because it checks only for conditional jumps (ITYPE_BRANCHCC). So trampoline is not created.

Could please anyone comment on this situation? Is this a known behavior?

In IsJumpPresentInFirstFiveBytes I tried to add a check for ITYPE_CALL and return true for that and after that I see that my hook is working (gets called). Is there any drawback of such modification?

OS is Windows 7. Application type is x86.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions