Click here to Skip to main content
Click here to Skip to main content

Easy way to set up global API hooks

By , , 19 Mar 2012
 

Contents

1.      Introduction
1.1.       What is API hooking?
1.2.       Local and global hooks
2.      AppInit_DLLs infrastructure
3.      Mhook library
4.      Writing the code
4.1.       Original function
4.2.       Hooked function
4.3.       Setting the hook
4.4.       Unhooking
5.      Running a sample
6.      Limitations
7.      Useful references

1. Introduction

This article describes an easy way to set up system-wide global API hooks. It uses AppInit_DLLs registry key for DLL injection and Mhook library for API hooking. To illustrate this technique we will show how to easily hide calc.exe from the list of running processes.

1.1 What is API hooking?

API hooking means intercepting some API function calls. By means of it you can alter the behavior of any software. Hooks are widely used by antiviruses, security applications, system utilities, programming tools etc.

1.2 Local and global hooks

There are two types of hooks: local and global ones. Local hooks are applied only to the specific application. Global hooks are applied to all processes in the system. The hook technique, which is shown in this article, is global and impacts on all processes in all sessions (in contrast to the SetWindowsHooks way that is bounded to the specific desktop).

2. AppInit_DLLs infrastructure

AppInit_DLLs infrastructure is a mechanism for loading an arbitrary list of DLLs in all user-mode processes which are linked with User32.dll  (Actually, there are very few executables that are not linked with it). The DLLs are loaded by User32.dll on its initialization.

The behavior of the AppInit_DLLs infrastructure is configured by a set of values that are stored under the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT \CurrentVersion\Windows key in the registry. These registry values are described in the table:

Value Description Sample values
LoadAppInit_DLLs
(REG_DWORD)
Value that globally enables or disables AppInit_DLLs. 0x0 – AppInit_DLLs are disabled.
0x1 – AppInit_DLLs are enabled.

AppInit_DLLs
(REG_SZ)

Space - or comma -separated list of DLLs to load. The complete path to the DLL should be specified using short file names. C:\PROGRA~1\Test\Test.dll
RequireSignedAppInit_DLLs
(REG_DWORD)
Require code-signed DLLs. 0x0 – Load any DLLs.
0x1 – Load only code-signed DLLs.

Table 1 - AppInit_DLLs Infrastructure registry values.

3. Mhook library

There are several libraries for api hooking. The typical things that they do are:

  1. Overwriting the beginning of the target function with custom code (so-called trampoline). When the function executes it will jump to the hook handler.
  2. Storing overwritten original code of the target function somewhere. It is needed for the correct target function functioning.
  3. Restoring overwritten portion of the target function.

Mhook is a free open source library for api hooking. It supports both x86 and x64 platforms and it is very easy in use. Mhook interface is simple and quite self describing:

  BOOL  Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction);
  BOOL  Mhook_Unhook(PVOID *ppHookedFunction);
For more info on library usage see the code sample shown in the next paragraph or visit Mhook home page.

4. Writing the code

We aregoing to write a user-mode DLL. First you should download the latest Mhook sources and add it to the project. If you are using precompiled headers turn it off for Mhook files.

As I’ve mentioned above our example will hide the calc.exe from the list of running processes.

4.1 Original function

The list of running processes is queried by calling NTAPI function NtQuerySystemInformation. So, we need to add some NTAPI stuff to our project. Unfortunately winternl.h header doesn’t contain full information and we have to define required data types ourselves:

/////////////////////////////////////////////////////////////////////////
// Defines and typedefs

#define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)

typedef struct _MY_SYSTEM_PROCESS_INFORMATION 
{
    ULONG                   NextEntryOffset;
    ULONG                   NumberOfThreads;
    LARGE_INTEGER           Reserved[3];
    LARGE_INTEGER           CreateTime;
    LARGE_INTEGER           UserTime;
    LARGE_INTEGER           KernelTime;
    UNICODE_STRING          ImageName;
    ULONG                   BasePriority;
    HANDLE                  ProcessId;
    HANDLE                  InheritedFromProcessId;
} MY_SYSTEM_PROCESS_INFORMATION, *PMY_SYSTEM_PROCESS_INFORMATION;

typedef NTSTATUS (WINAPI *PNT_QUERY_SYSTEM_INFORMATION)(
    __in       SYSTEM_INFORMATION_CLASS SystemInformationClass,
    __inout    PVOID SystemInformation,
    __in       ULONG SystemInformationLength,
    __out_opt  PULONG ReturnLength
    );

To store original function address create a global variable and initialize it:

//////////////////////////////////////////////////////////////////////////
// Original function

PNT_QUERY_SYSTEM_INFORMATION OriginalNtQuerySystemInformation = 
    (PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress(::GetModuleHandle(L"ntdll"), "NtQuerySystemInformation");

Hooked function

In the hooked function we call the original function first. Then check SystemInformationClass. If it is SystemProcessInformation we loop through the list of the running processes and find all entries for calc.exe to cut them out from the list. That’s all!

Note: This function must have the same signature as the original one.

//////////////////////////////////////////////////////////////////////////
// Hooked function

NTSTATUS WINAPI HookedNtQuerySystemInformation(
    __in       SYSTEM_INFORMATION_CLASS SystemInformationClass,
    __inout    PVOID                    SystemInformation,
    __in       ULONG                    SystemInformationLength,
    __out_opt  PULONG                   ReturnLength
    )
{
    NTSTATUS status = OriginalNtQuerySystemInformation(SystemInformationClass,
        SystemInformation,
        SystemInformationLength,
        ReturnLength);

    if (SystemProcessInformation == SystemInformationClass && STATUS_SUCCESS == status)
    {
        //
        // Loop through the list of processes
        //

        PMY_SYSTEM_PROCESS_INFORMATION pCurrent = NULL;
        PMY_SYSTEM_PROCESS_INFORMATION pNext    = (PMY_SYSTEM_PROCESS_INFORMATION)SystemInformation;
        
        do
        {
            pCurrent = pNext;
            pNext    = (PMY_SYSTEM_PROCESS_INFORMATION)((PUCHAR)pCurrent + pCurrent->NextEntryOffset);

            if (!wcsncmp(pNext->ImageName.Buffer, L"calc.exe", pNext->ImageName.Length))
            {
                if (0 == pNext->NextEntryOffset)
                {
                    pCurrent->NextEntryOffset = 0;
                }
                else
                {
                    pCurrent->NextEntryOffset += pNext->NextEntryOffset;
                }

                pNext = pCurrent;
            }            
        } 
        while(pCurrent->NextEntryOffset != 0);
    }

    return status;
}
 

4.3 Setting the hook

Setting the hook is pretty easy: call Mhook_SetHook from DllMain when the DLL is loaded to a new process:

//////////////////////////////////////////////////////////////////////////
// Entry point

BOOL WINAPI DllMain(
    __in HINSTANCE  hInstance,
    __in DWORD      Reason,
    __in LPVOID     Reserved
    )
{        
    switch (Reason)
    {
    case DLL_PROCESS_ATTACH:
        Mhook_SetHook((PVOID*)&OriginalNtQuerySystemInformation, HookedNtQuerySystemInformation);
        break;
 

4.4 Unhooking

Unhooking is performed by calling Mhook_Unhook from DllMain when the DLL is unloaded from the process:

//////////////////////////////////////////////////////////////////////////
// Entry point

BOOL WINAPI DllMain(
    __in HINSTANCE  hInstance,
    __in DWORD      Reason,
    __in LPVOID     Reserved
    )
{        
    switch (Reason)
    {
    ...
    case DLL_PROCESS_DETACH:
        Mhook_Unhook((PVOID*)&OriginalNtQuerySystemInformation);
        break;
    }

5. Running a sample

Now it’s time to show the described hook in action. Build the project and put the resulting AppInitHook.dll to the root of the disk C.

api-hooks/diskc.PNG

Figure 1 - The hook DLL is put to the root of the disk C.

Open the registry editor and locate AppInit_DLLs registry key (The key is HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT \CurrentVersion\Windows). Then specify the path to the hook DLL (C:\AppInitHook.dll in our case).

api-hooks/registry.PNG

Figure 2 – Modifying the registry.

After the registry has been modified the hook starts working. Let’s run a few instances of calc.exe. Then open Windows Task Manager and look at the processes tab. There is no calc.exe at all!

api-hooks/taskmgr.png

Figure 3 - Windows Task Manager processes tab.

Let’s see what shows another popular tool written by Mark Russinovich - Process Explorer.

api-hooks/procexp.png

Figure 4 - Process Explorer shows no calc.exe.

All calc.exe instances are hidden successfully. And finally run command line tool tasklist.exe:

api-hooks/tasklist.png

Figure 5 - Tasklist.exe listing of the running processes.

The hook is working!

6. Limitations

There are a few limitations of this hook technique you should know about:

  1. As it was mentioned before this hook is applied only to those processes that are linked to User32.dll.
  2. As hooking is performed in DllMain of User32.dll you can call functions only from Kernel32.dll and Ntdll.dll (other libraries are not initialized yet).
  3. Windows7/Windows 2008 R2 introduces the new security feature – AppInit DLLs have to be digitally signed (however there is a registry key that can turn this feature off).
  4. The file path to AppInit DLL must not contain spaces.

Useful references

  1. Working with the AppInit_DLLs registry value
  2. AppInit DLLs in Windows 7 and Windows Server 2008 R2
  3. API hooking revealed
  4. Mhook, an API hooking library, v2.2
  5. Microsoft Research's Detours
  6. DllMain Callback Function

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Authors

Sergey Podobry
Software Developer (Senior) ApriorIT
Ukraine Ukraine
Member
No Biography provided

Apriorit Inc
Apriorit Inc.
Ukraine Ukraine
Member
Organisation
31 members

ApriorIT is a Software Research and Development company that works in advanced knowledge-intensive scopes.
 
Company offers integrated research&development services for the software projects in such directions as Corporate Security, Remote Control, Mobile Development, Embedded Systems, Virtualization, Drivers and others.
 
Official site http://www.apriorit.com

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWindows 8memberjohny2k53 Mar '13 - 23:19 
First thanks for this sample!
I would like to know if anyone tried it on Windows 8 and if it worked for them to hide the calc.exe or any other process from tasklist.
Thanks!
SuggestionRe: Windows 8memberjohn-655376 Mar '13 - 13:42 
Yes, I'm just about to ask the same question.
Please help. Wink | ;)
AnswerRe: Windows 8memberSergey Podobry6 Mar '13 - 22:36 
Why not to try? It is not so hard Smile | :)
GeneralRe: Windows 8memberjohny2k516 Mar '13 - 11:21 
I've tried it and doesn't work for me. That's why I've asked if it works for others on Windows 8.
AnswerRe: Windows 8memberSergey Podobry18 Mar '13 - 6:21 
I tested it and I confirm that it works on Windows 8 too. The hook dll is loaded, the calc.exe is hidden from the taskmanager. However the tasklist.exe shows the calc.exe. Do they use another API for enumeration?
QuestionWindows 7 tasklist.exe shows the hidden methodmemberSedatŞen21 Feb '13 - 7:40 
Dear Sergey,
Thank you for your article. It is very usefull and easy to understand.
I have downloaded the code and used on a 32 bit Windows 7 system. calc.exe is not shown in TastManager and Process explorer but in command window tasklist.exe shows calc.exe. What could be the reason. Is tasklist.exe using another api call or what else?
AnswerRe: Windows 7 tasklist.exe shows the hidden methodmemberjohn-655376 Mar '13 - 13:49 
Other than tasklist.exe, IceSword.exe also reveals your hiden processes.
It's API Hook's limitation.
Any process uses lower level functions just won't be hooked.
AnswerRe: Windows 7 tasklist.exe shows the hidden methodmemberSergey Podobry6 Mar '13 - 22:34 
The goal of this article is not to hide a process from everyone. It shows how to use api hooking.
AnswerRe: Windows 7 tasklist.exe shows the hidden methodmemberSergey Podobry6 Mar '13 - 22:33 
Hi,
 
It is very strange because I checked it on Windows 7 and tasklist.exe didn't show calc.exe. Run Process Explorer and see whether AppInitHook.dll is loaded into the tasklist.exe process.
Questionproblem with StartPage hookmemberHiroki Ino30 Nov '12 - 11:22 
I wrote very small code to hook StartPage API from GDI32.dll.
But I had error of 'Data Execution Prevention' when I printed from any applications to call StartPage.
 
The code is as follows:
#include "stdafx.h"
#include "mhook/mhook-lib/mhook.h"

typedef int (WINAPI *PStartPage)(
	HDC hdc
    );
 
PStartPage OriginalStartPage = 
    (PStartPage)::GetProcAddress(::GetModuleHandle(L"gdi32.dll"), "StartPage");
 
int HookedStartPage(HDC hdc){
	OutputDebugString(L"StartPageHooked");
	return OriginalStartPage(hdc);
}
 
BOOL WINAPI DllMain(
    __in HINSTANCE  hInstance,
    __in DWORD      Reason,
    __in LPVOID     Reserved
    )
{        
    switch (Reason)
    {
    case DLL_PROCESS_ATTACH:
	Mhook_SetHook((PVOID*)&OriginalStartPage, HookedStartPage);
        break;
 
    case DLL_PROCESS_DETACH:
	Mhook_Unhook((PVOID*)&OriginalStartPage);
        break;
    }
 
    return TRUE;
}
 
Does anyone have any idea?
AnswerRe: problem with StartPage hookmemberSergey Podobry3 Dec '12 - 1:37 
Hi!
 
It looks you forgot to specify the WINAPI function call convention:
int WINAPI HookedStartPage(HDC hdc)

GeneralRe: problem with StartPage hookmemberHiroki Ino3 Dec '12 - 14:55 
I specified WINAPI and it worked!
Thank you very much.
AnswerRe: problem with StartPage hookmemberSergey Podobry21 Jan '13 - 2:27 
You're welcome!
Questiontrying to hook socket/WSASocketmemberBoyracer26 Nov '12 - 5:37 
first of all, it's great and working in many places Smile | :)
 
I am able to hook bind/accept/listen for example but I have no luck with socket/WSASocket
(I think I also need them from ws2_32.dll)
 
Anyone had a chance to get a hook on socket() , e.g socket (AF_INET, SOCK_STREAM, 0) ?
 
thanks!
AnswerRe: trying to hook socket/WSASocketmemberBoyracer5 Dec '12 - 0:53 
Some progress on this: It turns out that the first socket() call in a user
program is not hooked, but further ones are.
 
Any idea why this could be the case ?
GeneralRe: trying to hook socket/WSASocketmemberSergey Podobry6 Dec '12 - 4:40 
Hi!
 
When do you set the hooks?
GeneralRe: trying to hook socket/WSASocketmemberBoyracer16 Jan '13 - 6:00 
hi,
 
still an open item Wink | ;)
 
I am setting them in DllMain as part of
 

case DLL_THREAD_ATTACH:
case DLL_PROCESS_ATTACH:
Mhook_SetHook((PVOID*)&Originalsocket, Hookedsocket);
[]
 

regards, Markus
AnswerRe: trying to hook socket/WSASocketmemberSergey Podobry21 Jan '13 - 2:27 
There are several socket functions: socket, WSASocketA, WSASocketW. Are you sure you are hooking the right one?
GeneralRe: trying to hook socket/WSASocketmemberBoyracer21 Jan '13 - 21:13 
Correct. All 3 of them are hooked. What's puzzling is that if you have an application
 
main()
a = socket()
b = socket();
 
then only b gets the hooks/interception
Also verified for applications using the Winsock api like WSASocket
(which you can't hook but you need to hook WSASocketA/WSASocketW)
 
Markus
GeneralRe: trying to hook socket/WSASocketmemberSergey Podobry21 Jan '13 - 23:56 
Interesting. Could you upload a complete test code?
GeneralRe: trying to hook socket/WSASocket [modified]memberBoyracer22 Jan '13 - 4:51 
 
typedef SOCKET (WINAPI *PWSASOCK) (
	__in int af,
	__in int type,
	__in int protocol,
	__in LPWSAPROTOCOL_INFO lpProtocolInfo,
    __in GROUP g,
    __in DWORD dwFlags
	);
 
typedef SOCKET (WINAPI *PSOCK) (
	__in int af,
	__in int type,
	__in int protocol
	);
 
PSOCK Originalsocket =
	(PSOCK)::GetProcAddress(::GetModuleHandle(L"ws2_32.dll"), "socket");
 
PWSASOCK OriginalWSASocketW =
	(PWSASOCK)::GetProcAddress(::GetModuleHandle(L"ws2_32.dll"), "WSASocketW");
 
PWSASOCK OriginalWSASocketA =
	(PWSASOCK)::GetProcAddress(::GetModuleHandle(L"ws2_32.dll"), "WSASocketA");
 

//////////////////////////////////////////////////////////////////////////
// Hooked functions
int WINAPI HookedWSAStartup (WORD wVersionRequested, LPWSADATA lpWSADataint)
{
	return OriginalWSAStartup(wVersionRequested, lpWSADataint);
}
SOCKET WINAPI Hookedsocket(int af, int type, int protocol)
{
  int ret = 0;
  MTCP_TRACE_IN ("af %d type %d protocol %d\n", af, type, protocol);
  ret = Originalsocket (af, type, protocol);
  MTCP_TRACE_OUT ("new socket %d\n", ret);
  return ret;
}
 
SOCKET WINAPI HookedWSASocketA(int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags)
{
	int ret = 0;
	printf ("af %d type %d protocol %d\n", af, type, protocol);
	ret = OriginalWSASocketA (af, type, protocol, lpProtocolInfo, g, dwFlags);
        printf ("new socket %d\n", ret);
	return ret;
}
 
SOCKET WINAPI HookedWSASocketW(int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags)
{
	int ret = 0;
	printf ("af %d type %d protocol %d\n", af, type, protocol);
	ret = OriginalWSASocketW (af, type, protocol, lpProtocolInfo, g, dwFlags);
        printf ("new socket %d\n", ret);
	return ret;
}
 
DllMain:
 
  case DLL_PROCESS_ATTACH:
        /* verify appname so that not all apps are hooked */
	Mhook_SetHook((PVOID*)&OriginalWSAStartup, HookedWSAStartup);
	Mhook_SetHook((PVOID*)&OriginalWSASocketA, HookedWSASocketA);
        Mhook_SetHook((PVOID*)&OriginalWSASocketW, HookedWSASocketW);
        Mhook_SetHook((PVOID*)&Originalsocket, Hookedsocket);
        break;
  case DLL_PROCESS_DETACH:
        /* socket connection init */
        Mhook_Unhook((PVOID*)&OriginalWSASocketA);
        Mhook_Unhook((PVOID*)&OriginalWSASocketW);
        Mhook_Unhook((PVOID*)&Originalsocket);
break;
 

 
/* not 100% complete but it should be pluggable into the framework */
/* added defines */

modified 24 Jan '13 - 3:23.

GeneralRe: trying to hook socket/WSASocketmemberBoyracer7 Feb '13 - 5:40 
I think this actually falls into the known limitations section
where it says the other libs are not yet initialized.
 
calling WSAStartup is not invoking Dllmain so the first
socket call in a program can do but that's prior to the
interception.
 
if the app does
wsastartup
gethostbyname
socket
 
then the first socket does see the hooks as the lib was loaded via
gethostbyname->dllmain
QuestionWhat if the API I want to hook to is not from ntdll.dll?memberdc_200018 Aug '12 - 21:28 
For instance, if I want to hook to an API in PowrProf.dll?
 
Someone suggested starting a worker thread from the DllMain and wait for the library to load there, but what if this specific library never loads because the process that's being started doesn't contain it?
 
PS. Thanks for the article, it's very helpful!
AnswerRe: What if the API I want to hook to is not from ntdll.dll?memberSergey Podobry20 Aug '12 - 3:29 
I answered your question in the another thread.
 
Glad you've found the article useful!
QuestionUse the hook in the windows service.memberMember 777926126 Apr '12 - 15:41 
Great tutorial! Big Grin | :-D
 
I wonder, how can I use this hook in the system service.
Is possible to use it in a normal application instead of the dll library?
AnswerRe: Use the hook in the windows service.memberSergey Podobry26 Apr '12 - 22:20 
The hook can be implemented only as dll and runs in a context of the calling process. However you can incorporate an RPC mechanism and communicate with your service application. Be careful, don't do a lot of stuff in the DllMain!
 
Have a nice day!
QuestionQuestion???membercrin9918 Mar '12 - 23:53 
Where can I download AppInitHook.dll-compiled as dll to test it,caz i dont want and cant compile it from source??? pls answer me and send to me on email: cembox7@yahoo.com
thanks.
AnswerRe: Question???memberSergey Podobry19 Mar '12 - 3:24 
Hi!

Added binaries to the download archive.

Cheers!
QuestionMhook for specific application threadmemberMember 157271014 Mar '12 - 7:30 
Can Mhook, hook one specific application thread (ie setwindowshookex) or is it system-wide only? For example, if I hooked the createwindow function, isn't that going to hook all processes on the machine and not just one targeted application? It would seem to be simpler to use setwindowshookex in that case unless there are other advantages.
 
Thanks Much.
AnswerRe: Mhook for specific application threadmemberSergey Podobry14 Mar '12 - 11:26 
Sure, you can hook only one specific process but hook dll will be loaded to all processes (very similar to setwindowshookex). You just have to get process image name in your hook dll and decide whether to setup hooks or not.
 
Cheers!
GeneralRe: Mhook for specific application threadmemberMember 157271016 Mar '12 - 7:33 
Just to be clear. The approach to using mhook would be just to ignore all other hook methods(injection, setwindowshook) and if need be filter by thread or window calling the dll. So does this approach save in code/memory loaded into any one application and/or the performance degradation is trivial? Basically I'm swapping loading code into every thread I choose by injection(setwindowshook) vs a global check on the thread id/window I really want to run code on (mhook).
 
By way of example is this what you mean?
 
DLL_PROCESS_ATTACH: Mhook_SetHook(CreateWindow, MyCreateWindow)
 
MyCreateWindow: if currentThread != threadIWant &&
currentWindow != windowIWant
return CreateWindow
else ..... mycreatewindow code ......

 
Thanks again!
Questionproblem with copyfileexwmemberDinakara K23 Nov '11 - 2:12 
Dear Sergey Pedobry,
 
I am hooking CopyFileExWusing mhook. But it is in some way interfering with the uninstall programs(other applications) and giving following error:
 
Unable to execute file in the temporary directory. Setup aborted.
 
Error 2: The system cannot find the file specified.
 

How could I get over this problem...
 

My initial guess is that it has something to do with the callback function lpProgressRoutine of CopyFileExW
 
Thanks in advance.......
Dinakara K
 
CAIR, Bangalore

SuggestionRe: problem with copyfileexwmemberSergey Podobry23 Nov '11 - 2:28 
Hi!
 
For the start only call the original function from your hook. Everything should work fine. Than analyze what else you do in the hook. Also you can log calls to CopyFileExW in the first (only original) and the second (with your logic) cases and look for the difference.
 
I think you didn't copy the file required for uninstall or copy to the wrong place\name.
 
Cheers!
GeneralRe: problem with copyfileexwmemberDinakara K23 Nov '11 - 2:52 
Dear Sergey Podobry,
 
Thanks for the quick reply, As you have suggested, I am just calling the original function from the hook. The code looks something like this
 
BOOL WINAPI MyCopyFileExW(LPCWSTR lpExistingFileName,
LPCWSTR lpNewFileName,
LPPROGRESS_ROUTINE lpProgressRoutine,
LPVOID lpData,
LPBOOL pbCancel,
DWORD dwCopyFlags){
 
DebugPrint("<AppInitHook>>main.cpp>MyCopyFileExW()>Entered");
 
BOOL status = OP_SUC;
 
if (NULL !=OriginalCopyFileExW){

status = (*OriginalCopyFileExW)(lpExistingFileName,
lpNewFileName,lpProgressRoutine,lpData,pbCancel,dwCopyFlags);
 
char tmp[MAX_PATH];
sprintf_s(tmp,MAX_PATH,"lpProgressRoutine1()>CopyFileExW:%d",status);
DebugPrint(tmp);
 
return status;

}

 
But the problem persists.
 
thanks
Dinakara K
 
CAIR, Bangalore

AnswerRe: problem with copyfileexwmemberSergey Podobry23 Nov '11 - 3:22 
I think I know what is wrong: you are changing LastError value. Save it right after original function call and restore before return.
GeneralRe: problem with copyfileexwmemberDinakara K24 Nov '11 - 2:12 
Thanks Sergey Podobry.
 
You are right.Actually the DebugPrint() or OutputDebugString()changes the LastError value.So either we should not use it as first statement in the hooked Function call or we have to save and restore the LastError value before return, as you rightly pointed out.
Dinakara K
 
CAIR, Bangalore

Questionppt problemmemberjohn-6553716 Nov '11 - 16:14 
How weird!
In a XP 32b environment, everything hooked OK with registry method.
But after I installed Office 2010, powerpoint and only powerpoint, no matter 2003 or 2010, can NOT be hooked with registry anymore(Remote Hooking is still OK).
Any idea?
AnswerRe: ppt problemmemberjohn-6553716 Nov '11 - 20:14 
Sorry, the problem is due to my own dll, have nothing to do with office 2010.
Questionwindows 7 problemmemberjohn-6553713 Nov '11 - 19:21 
This way works greatly on windows other than win7 and later.
In Windows 7 64bits environment I just cannot let the dlls been hooked by the registry.
I've set registry values correctly, codesigned the dll, but still won't hook.
I tried a remote hook method which use CreateRemoteThread(), it can hook 32bit processes but not 64bit processes.
Please Help.
AnswerRe: windows 7 problemmemberSergey Podobry13 Nov '11 - 22:20 
This method works perfectly on win7 x64. Read this comments thread: Works fine on 32 bit machine. Not working in 64
GeneralRe: windows 7 problemmemberjohn-6553714 Nov '11 - 16:28 
Yes, this method is OK in Windows 7, my previous problem is due to a silly fault. The LoadAppInit_DLLs Key in Windows 7 MUST be DWORD type. In Vista my .reg script can be LoadAppInit_DLLs="1", but win7 won't accept that.
After I changed the data type of LoadAppInit_DLLs, DLLs hook beautifully.
Thanks for the reply. Smile | :)
Questionhooking of user32.dll [modified]memberjob@3deden.com28 Oct '11 - 6:33 
Hi dudes.,
 
my question sounds.., how can i hook function from user32.dll space? i thing this tutorial works under kernel32.dll .. library only....please share this information, thanx for reply.

modified 28 Oct '11 - 12:49.

AnswerRe: hooking of user32.dllmemberjohn-6553716 Nov '11 - 18:10 
You may hook user32 functions later.
I mean you don't/can't hook them in DllMain, instead hook them in other functions afterwards.
For example, just create a thread in DllMain, later the thread hooks user32 functions.
AnswerRe: hooking of user32.dllmemberSergey Podobry16 Nov '11 - 23:44 
That's right. Also you can hook LoadLibrary from kernel32.dll and detect when user32.dll gets loaded and set hooks to it.
GeneralRe: hooking of user32.dllmemberdc_200019 Aug '12 - 17:36 
Thanks, but there're too many variables to this process that almost deserve the part II for this article. For instance:
 
1. There're two versions of the API: LoadLibraryA and LoadLibraryW. Which one do we need to hook to?
 
2. There's also LoadLibraryExA and LoadLibraryExW that could be used to load a DLL.
 
3. Any of the LoadLibrary(Ex) APIs can be called repeatedly for the same DLL, what shall be done then?
 
4. When do we need to unhook, during the FreeLibrary call (by previously hooking to it)?
 
So it would be nice if you could explain all this...
AnswerRe: hooking of user32.dllmemberSergey Podobry20 Aug '12 - 3:24 
Thanks for the good food for the part II Smile | :)
 
Here is a short guide:
 
1. You have to hook LoadLibrary. You need to hook all function: LoadLibraryA/W and LoadLibraryExA/W. If your dll will never be run under WOW64 then you may hook only LoadLibraryExW.
2. After executing the original function call GetModuleHandleEx with the name of the dll you want to hook.
3. If GetModuleHandleEx returns a valid handle hook the dll and make it unloadable (don't call FreeLibrary).
4. Make sure that operations above are atomic. Use critical section for that.
5. Don't hook twice (unless you really want to do that).
QuestionFreezing issue in PowerPoint 2007membernick_qi2 Mar '11 - 17:03 
I've coded a simple project to hook StartDocW function from Windows GDI using mHook. It basically pops up a modal MessageBox upon intercepting StartDocW calls then return the values from the original function. Nothing fancy.
 
It worked for all Windows applications I tested, except PowerPoint 2007 on Windows 7. After closing the MessageBox, PowerPoint 2007 would stop accepting user inputs.
 
I did a bit of trial and error and I found that:
 
* To replicate the issue, I must have a Word 2007 instance running in the background.
* It's not a problem for PowerPoint 2007 on Windows XP.
 
Anyone has any ideas if it's hooking related?
QuestionRe: Freezing issue in PowerPoint 2007memberSergey Podobry6 Mar '11 - 22:29 
What if remove MessageBox? Just call the original function.
AnswerRe: Freezing issue in PowerPoint 2007membernick_qi8 Mar '11 - 13:46 
That's not a problem with an UI.
QuestionAny other resource?memberXercoy25 Jan '11 - 12:21 
I'm trying to learn how to use mhook to do some API hooking, and even after studying and reading this article thoroughly, I'm not having any luck creating my own hook. I was wondering if you could provide any other links or resources for me to learn from. I'm trying to hook the InternetOpenUrl function of the WinINet.dll API, but I'm not having any luck. I'd rather not ask you for help every step of the way, I would much rather be able to learn myself. Thank you for taking the time to both write this article and read my post!

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 19 Mar 2012
Article Copyright 2009 by Sergey Podobry, Apriorit Inc
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid