Click here to Skip to main content
15,885,278 members
Articles / Desktop Programming / Win32

EasyHook - The reinvention of Windows API hooking

Rate me:
Please Sign up or sign in to vote.
4.94/5 (79 votes)
14 Aug 2008LGPL329 min read 649.2K   24.3K   359  
Now supports an unmanaged API, kernel mode hooking, and extending unmanaged APIs with pure managed handlers since Windows 2000 SP4.
/*
    EasyHook - The reinvention of Windows API hooking
 
    Copyright (C) 2008 Christoph Husse

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    Please visit http://www.codeplex.com/easyhook for more information
    about the project and latest updates.

PLEASE NOTE:
    The LGPL allows you to sell propritary software based on this library
    (EasyHook) without releasing the source code for your application.
    This is a big difference to the original GPL. Refer to the attached
    "LICENSE" document for more information about the LGPL!
 
    To wrap it up (without warranty):
        
        1)  You are granted to sell any software that uses EasyHook over
            DLL or NET bindings. This is covered by the native API and the 
            managed interface.
        2)  You are NOT granted to sell any software that includes parts
            of the EasyHook source code or any modification! If you want
            to modify EasyHook, you are forced to release your work under
            the LGPL or GPL... Of course this only applies to the library
            itself. For example you could release a modification of EasyHook
            under LGPL, while still being able to release software, which
            takes advantage of this modification over DLL or NET bindings,
            under a proprietary license!
        3)  You shall include a visible hint in your software that EasyHook
            is used as module and also point out, that this module in
            particular is released under the terms of the LGPL and NOT
            under the terms of your software (assuming that your software
            has another license than LGPL or GPL).
 
    I decided to release EasyHook under LGPL to prevent commercial abuse
    of this free work. I didn't release it under GPL, because I also want to
    address commercial vendors which are more common under Windows.

BUG REPORTS:

    Reporting bugs is the only chance to get them fixed! Don't consider your
    report useless... I will fix any serious bug within a short time! Bugs with
    lower priority will always be fixed in the next release...

DONATIONS:

    I want to add support for Itanium (II - III) processors. If you have any hardware
    that you don't need anymore or could donate, which >supports< a recent Windows
    Itanium edition (Windows license is not required), please contact me. Of course we 
    could discuss a reasonable sponsorship reference for your company. Money for
    buying such hardware is also appreciated...
*/
#ifndef _DRIVERSHARED_H_
#define _DRIVERSHARED_H_

#ifdef __cplusplus
extern "C"{
#endif

#pragma warning (disable:4054) // function/data conversion
#pragma warning (disable:4055) // data/function conversion
#pragma warning (disable:4200) // zero-sized array in struct/union
#pragma warning (disable:4204) // non-constant init
#pragma warning (disable:4100) // unreferenced parameter


#include "rtl.h"

#define EASYHOOK_NT_INTERNAL            EXTERN_C NTSTATUS __stdcall
#define EASYHOOK_BOOL_INTERNAL          EXTERN_C BOOL __stdcall

EXTERN_C int __stdcall GetInstructionLength_x64(void* InPtr, int InType);
EXTERN_C int __stdcall GetInstructionLength_x86(void* InPtr, int InType);

#define EASYHOOK_INJECT_MANAGED     0x00000001

typedef struct _NOTIFICATION_REQUEST_
{
	ULONG				MaxCount;
	ULONG				Count;
	ULONG				Entries[0];
}NOTIFICATION_REQUEST, *PNOTIFICATION_REQUEST;

typedef struct _HOOK_ACL_
{
	ULONG                   Count;
	BOOL                    IsExclusive;
	ULONG                   Entries[MAX_ACE_COUNT];
}HOOK_ACL;

#define LOCAL_HOOK_SIGNATURE            ((ULONG)0x6A910BE2)

typedef struct _LOCAL_HOOK_INFO_
{
    PLOCAL_HOOK_INFO        Next;
    ULONG					NativeSize;
	UCHAR*					TargetProc;
	ULONGLONG				TargetBackup;
	ULONGLONG				TargetBackup_x64;
	ULONGLONG				HookCopy;
	ULONG					EntrySize;
	UCHAR*					Trampoline;
    ULONG					HLSIndex;
	ULONG					HLSIdent;
	void*					Callback;
	HOOK_ACL				LocalACL;
    ULONG                   Signature;
    TRACED_HOOK_HANDLE      Tracking;

	void*					RandomValue; // fixed
	void*					HookIntro; // fixed
	UCHAR*					OldProc; // fixed
	UCHAR*					HookProc; // fixed
	void*					HookOutro; // fixed
	int*					IsExecutedPtr; // fixed
}LOCAL_HOOK_INFO, *PLOCAL_HOOK_INFO;


extern LOCAL_HOOK_INFO          GlobalHookListHead;
extern LOCAL_HOOK_INFO          GlobalRemovalListHead;
extern RTL_SPIN_LOCK            GlobalHookLock;

EASYHOOK_BOOL_INTERNAL LhIsValidHandle(
            TRACED_HOOK_HANDLE InTracedHandle,
            PLOCAL_HOOK_INFO* OutHandle);

void LhCriticalInitialize();

void LhModuleInfoFinalize();

void LhCriticalFinalize();

void* LhAllocateMemory(void* InEntryPoint);

void LhFreeMemory(PLOCAL_HOOK_INFO* RefHandle);

HOOK_ACL* LhBarrierGetAcl();

ULONGLONG LhBarrierIntro(LOCAL_HOOK_INFO* InHandle, void* InRetAddr, void** InAddrOfRetAddr);

void* __stdcall LhBarrierOutro(LOCAL_HOOK_INFO* InHandle, void** InAddrOfRetAddr);

EASYHOOK_NT_INTERNAL LhRelocateEntryPoint(
				UCHAR* InEntryPoint,
				ULONG InEPSize,
				UCHAR* Buffer,
				ULONG* OutRelocSize);

EASYHOOK_NT_INTERNAL LhRoundToNextInstruction(
			void* InCodePtr,
			ULONG InCodeSize);

EASYHOOK_NT_INTERNAL LhGetInstructionLength(void* InPtr);

/*
    Helper API
*/
EASYHOOK_NT_INTERNAL DbgCriticalInitialize();

EASYHOOK_NT_INTERNAL DbgCriticalFinalize();

#ifdef __cplusplus
}
#endif

#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Software Developer SecurityRevolutions
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions