How unhook APIs Message (global hooks) in x64?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3

Thread: How unhook APIs Message (global hooks) in x64?

  1. #1
    Join Date
    Apr 2014
    Posts
    54

    How unhook APIs Message (global hooks) in x64?

    Hello,

    I found a project that is able to list all hooks of messages and i had adapted also for unhook these hook listeds.

    My problem is that this code only works with Windows 32 bit.

    Then someone here could give me a clue about how make it work also in Windows 64 bit?

    Code:
    PS: Compiled with VS2012 Ultimate and tested in Windows 7 32 bit.
    Code:
    // EnumWindowsHookEx.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include "EnumWindowsHooks.h"
    
    #pragma comment(lib, "ntdll")
    
    int __cdecl main(int argc, char **argv)
    {
    	NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
    
    	PVOID ImageBase;
    	ULONG DllCharacteristics = 0;
    	PVOID User32InitializeImmEntryTable = NULL;
    
    	UNICODE_STRING DllName;
    	ANSI_STRING ProcedureName;
    
    	ULONG i;
    	ULONG UserDelta = 0;
    	ULONG HandleEntries = 0;
    
    	SHARED_INFO *SharedInfo = NULL;
    	HANDLE_ENTRY *UserHandleTable = NULL;
    	HOOK *HookInfo = NULL;
    
    
    	__try
    	{
    		system("cls");
    
    
    		RtlInitUnicodeString(
    			&DllName,
    			L"user32");
    
    		NtStatus = LdrLoadDll(
    			NULL,                // DllPath
    			&DllCharacteristics, // DllCharacteristics
    			&DllName,            // DllName
    			&ImageBase);         // DllHandle
    
    		if(NtStatus == STATUS_SUCCESS)
    		{
    			RtlInitAnsiString(
    				&ProcedureName,
    				"User32InitializeImmEntryTable");
    
    			NtStatus = LdrGetProcedureAddress(
    				ImageBase,                               // DllHandle
    				&ProcedureName,                          // ProcedureName
    				0,                                       // ProcedureNumber OPTIONAL
    				(PVOID*)&User32InitializeImmEntryTable); // ProcedureAddress
    
    			if(NtStatus == STATUS_SUCCESS)
    			{
    				__asm
    				{
    					       mov esi, User32InitializeImmEntryTable
    						test esi, esi
    						jz __exit2
    						mov ecx, 0x80
    
    __loop:
    					        dec ecx
    						test ecx, ecx
    						jz __exit1
    
    						lodsb
    						cmp al, 0x50
    						jnz __loop
    
    						lodsb
    						cmp al, 0x68
    						jnz __loop
    
    						lodsd
    						mov SharedInfo, eax
    
    						jmp __exit2
    
    __exit1:
    					mov SharedInfo, ecx
    
    __exit2:
    					sub eax, eax
    						mov eax, fs:[eax+0x18]
    					lea eax, [eax+0x06CC]
    					mov eax, [eax+0x001C]
    					mov UserDelta, eax
    				}
    
    				HandleEntries = *((ULONG *)((ULONG)SharedInfo->ServerInfo + 8));
    
    				printf(
    					" +--------------------------------------------------------------------+\n"
    					" | SHARED_INFO - %.8X                                             |\n"
    					" +--------------------------------------------------------------------+\n"
    					" | ServerInfo - %.8X                                              |\n"
    					" | HandleEntryList - %.8X                                         |\n"
    					" | HandleEntries - %.8X                                           |\n"
    					" | DisplayInfo - %.8X                                             |\n"
    					" | SharedDelta - %.8X                                             |\n"
    					" | UserDelta - %.8X                                               |\n"
    					" +--------------------------------------------------------------------+\n\n",
    					SharedInfo,
    					SharedInfo->ServerInfo,
    					SharedInfo->HandleEntryList,
    					HandleEntries,
    					SharedInfo->DisplayInfo,
    					SharedInfo->SharedDelta,
    					UserDelta);
    
    				UserHandleTable = (HANDLE_ENTRY *)SharedInfo->HandleEntryList;
    
    				for(i=0; i<HandleEntries; i++)
    				{
    					if(UserHandleTable[i].Type == TYPE_HOOK)
    					{ 
    						__try
    						{
    							HookInfo = (HOOK *)((ULONG)UserHandleTable[i].Head - UserDelta);
    
    							printf(
    								" +--------------------------------------------------------------------+\n"
    								" | HOOK - %.8X                                                    |\n"
    								" +--------------------------------------------------------------------+\n"
    								" | Handle - %.8X                                                  |\n"
    								" | LockObj - %.8X                                                 |\n"
    								" | ThreadInfo- %.8X                                               |\n"
    								" | Desktop1 - %.8X                                                |\n"
    								" | Self - %.8X                                                    |\n"
    								" | NextHook - %.8X                                                |\n"
    								" | HookType - %.8X                                                |\n"
    								" | FunctionAddress - %.8X                                         |\n"
    								" | Flags - %.8X                                                   |\n"
    								" | ModuleHandle - %.8X                                            |\n"
    								" | Hooked - %.8X                                                  |\n"
    								" | Desktop2 - %.8X                                                |\n"
    								" +--------------------------------------------------------------------+\n\n",
    								(ULONG)UserHandleTable[i].Head - UserDelta,
    								HookInfo->Handle,
    								HookInfo->LockObj,
    								HookInfo->ThreadInfo,
    								HookInfo->Desktop1,
    								HookInfo->Self,
    								HookInfo->NextHook,
    								HookInfo->HookType,
    								HookInfo->FunctionAddress,
    								HookInfo->Flags,
    								HookInfo->ModuleHandle,
    								HookInfo->Hooked,
    								HookInfo->Desktop2);
    
    							UnhookWindowsHookEx((HHOOK)HookInfo->Handle);
    						}
    						__except(EXCEPTION_EXECUTE_HANDLER) {}
    					}
    				}
    			}
    		}
    	}
    	__except(EXCEPTION_EXECUTE_HANDLER)
    	{
    		printf(">> main - %.8X\n", GetExceptionCode());
    
    		//return GetExceptionCode();
    	}
    
    	system("pause");
    
    	return FALSE;
    }

    EnumWindowsHooks.h

    Code:
    #ifndef __ENUM_WINDOWS_HOOKS__
    #define __ENUM_WINDOWS_HOOKS__
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    
    #define IMP_VOID __declspec(dllimport) VOID __stdcall
    #define IMP_SYSCALL __declspec(dllimport) NTSTATUS __stdcall
    
    #define STATUS_SUCCESS 0x00000000
    #define STATUS_UNSUCCESSFUL 0xC0000001
    #define STATUS_INVALID_PARAMETER_1 0xC00000EF
    #define STATUS_INVALID_PARAMETER_2 0xC00000F0
    
    typedef struct ANSI_STRING
    {
    	USHORT Length;
    	USHORT MaximumLength;
    	PCHAR Buffer;
    }
    ANSI_STRING,
    	*PANSI_STRING,
    	**PPANSI_STRING;
    
    typedef struct _UNICODE_STRING 
    {
    	USHORT Length;
    	USHORT MaximumLength;
    	PWSTR Buffer;
    }
    UNICODE_STRING,
    	*PUNICODE_STRING,
    	**PPUNICODE_STRING;
    
    #define TYPE_FREE           0
    #define TYPE_WINDOW         1
    #define TYPE_MENU           2
    #define TYPE_CURSOR         3
    #define TYPE_SETWINDOWPOS   4
    #define TYPE_HOOK           5
    #define TYPE_CLIPDATA       6
    #define TYPE_CALLPROC       7
    #define TYPE_ACCELTABLE     8
    #define TYPE_DDEACCESS      9
    #define TYPE_DDECONV        10
    #define TYPE_DDEXACT        11
    #define TYPE_MONITOR        12
    #define TYPE_KBDLAYOUT      13
    #define TYPE_KBDFILE        14
    #define TYPE_WINEVENTHOOK   15
    #define TYPE_TIMER          16
    #define TYPE_INPUTCONTEXT   17
    #define TYPE_CTYPES         18
    #define TYPE_GENERIC        255
    
    #define HMINDEXBITS 0x0000FFFF
    #define HMUNIQSHIFT 16
    #define HMUNIQBITS 0xFFFF0000
    
    #define MAX_HANDLE_COUNT 0x8000
    
    typedef struct _HEAD
    {
    	HANDLE Handle;
    	ULONG LockObj;
    }
    HEAD,
    	*PHEAD,
    	**PPHEAD;
    
    typedef struct _HANDLE_ENTRY
    {
    	HEAD *Head;
    	PVOID Owner;
    	UCHAR Type;
    	UCHAR Flags;
    	USHORT Unique;
    }
    HANDLE_ENTRY,
    	*PHANDLE_ENTRY,
    	**PPHANDLE_ENTRY;
    
    typedef struct _SHARED_INFO
    {
    	PVOID ServerInfo;
    	HANDLE_ENTRY *HandleEntryList;
    	PVOID DisplayInfo;
    	ULONG SharedDelta;
    }
    SHARED_INFO,
    	*PSHARED_INFO,
    	**PPSHARED_INFO;
    
    typedef struct _HOOK
    {
    	ULONG Handle;
    	ULONG LockObj;
    	PVOID ThreadInfo;
    	PVOID Desktop1;
    	PVOID Self;
    	PVOID NextHook;
    	LONG HookType;
    	PVOID FunctionAddress;
    	ULONG Flags;
    	ULONG ModuleHandle;
    	PVOID Hooked;
    	PVOID Desktop2;
    }
    HOOK,
    	*PHOOK,
    	**PPHOOK;
    
    extern "C" IMP_SYSCALL LdrLoadDll
    	(
    	IN PWSTR DllPath OPTIONAL,
    	IN PULONG DllCharacteristics OPTIONAL,
    	IN PUNICODE_STRING DllName,
    	OUT PVOID *DllHandle
    	);
    
    extern "C" IMP_SYSCALL LdrGetProcedureAddress
    	(
    	IN PVOID DllHandle,
    	IN PANSI_STRING ProcedureName OPTIONAL,
    	IN ULONG ProcedureNumber OPTIONAL,
    	OUT PVOID *ProcedureAddress
    	);
    
    extern "C" IMP_VOID RtlInitAnsiString
    	(
    	IN OUT PANSI_STRING DestinationString,
    	IN PCSTR SourceString
    	);
    
    extern "C" IMP_VOID RtlInitUnicodeString
    	(
    	IN OUT PUNICODE_STRING DestinationString,
    	IN PCWSTR SourceString
    	);
    
    #endif
    Last edited by FL4SHC0D3R; March 19th, 2017 at 08:44 AM.

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    18,886

    Re: How unhook APIs Message (global hooks) in x64?

    Quote Originally Posted by FL4SHC0D3R View Post
    My problem is that this code only works with Windows 32 bit.

    Then someone here could give me a clue about how make it work also in Windows 64 bit?
    ...
    This code cannot work in x64 system.
    The reason is (from MSDN):
    One of the constraints for the x64 compiler is to have no inline assembler support. This means that functions that cannot be written in C or C++ will either have to be written as subroutines or as intrinsic functions supported by the compiler. Certain functions are performance sensitive while others are not. Performance-sensitive functions should be implemented as intrinsic functions.
    Additional info supplied by Google:
    https://www.google.ch/webhp?sourceid...#q=__asm+x64&*
    Victor Nijegorodov

  3. #3
    Join Date
    Apr 2014
    Posts
    54

    Re: How unhook APIs Message (global hooks) in x64?

    Ok Vitor, thank you by this info.

    Between all solution, i think that the better is translate this piece of asm code, to C++ code.
    But i'm not good with asm.

    So, if someone here understand asm and want help me with this task, will very welcome this help.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This a Codeguru.com survey!


HTML5 Development Center