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

HookImportFunctionByName v1.0

By , 3 Mar 2000
 
  • Download source files - 6 Kb
  • Introduction

    Enclosed is MFC source code for a function which can be used to hook any imported function call which your application makes. Since most of the Win32 API is implemented using import functions in dlls, this means that you hook Win32 API calls. This is useful when for example you want to be called for every call to the file system (::CreateFile() & CloseHandle()) which your app makes. This example of hooking the file system calls your app makes could form the basis of code to ensure you do not have any handle leaks in your application. You could also use this code to spy on COM port activity in remote processes by injecting the DLL into the remote process.

    The code is based on the code developed by John Robbins for his "BugSlayer" articles in the MSJ magazine. I have removed the dependencies on his other DLL functions, converted the code to MFC and addition of numerous ASSERTs.


    History
    API
    Planned Enhancements
    Contacting the Author


    History

    V1.0 (24 December 1999)
    • Initial Public Release.


    API

    The API consists of the single global function:

    HookImportFunctionsByName

    HookImportFunctionsByName

    BOOL HookImportFunctionsByName(HMODULE hModule, LPCSTR szImportMod, UINT uiCount, LPHOOKFUNCDESC paHookArray, PROC* paOrigFuncs, UINT* puiHooked);

    Return Value:
    TRUE if the specified API call(s) were hooked, therwise FALSE. To get extended error information, call ::GetLastError().

    Parameters:

    • hModule -- This is the instance handle of the process calling the function. Normally in MFC you can obtain this from the function AfxGetInstanceHandle().
    • szImportMod -- This is the name of the module which contains the functions which you want to hook. e.g. for hooking file system calls, this would be KERNEL32.DLL.
    • uiCount -- This is the size of the paHookArray parameter.
    • paHookArray -- This is an array which specifies what functions to hook. The members of the HOOKFUNCDESC are "szFunc", which is the name of your function to hook, and "pProc", which is a function pointer to the function which you want to have called instead of normal unhooked case.
    • paOrigFuncs -- Upon successful return this will contain the original unhooked function pointers. These would be useful if you want to pass the request onto the original function after your hook function has been called.
    • puiHooked -- Upon return this will contain the number of functions which were hooked. This will be less than or equal to "uiCount".

    Remarks:
    If you are hooked standard Win32 API calls then make sure that your hook function is using the right calling convention namely STDCALL. This is one of the most common problems encountered when using the hooking function.



    Planned Enhancements

    • Provide a sample app. I started using this code for a number of private contracts which I have been working on. Some ideas for sample apps would be a serial port monitor, a file system monitor to do the same as the Filemon application on the System Internals Web site.
    • If you have any other suggested improvements, please let me know so that I can incorporate them into the next release.


    Contacting the Author

    PJ Naughter
    Email: pjn@indigo..ie
    Web: http://www.naughter.com
    24 November 1999


    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here

    About the Author

    PJ Naughter
    United States United States
    Member
    No Biography provided

    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   
    GeneralThanx for the articlememberbnc2 May '09 - 19:58 
    Thanx for this innovative article
    QuestionSerial port monitormemberMariano Capezzani30 Apr '08 - 10:52 
    Hi,
     
    You suggested this function could be used for a serial port monitor. Could you please give more detail on how this could be done? Other serial port sniffers I've found have the problem of using up the port connection they are sniffing, rendering it unusable to other applications.
     
    The idea of what I want to do is be able to "listen" what any application is sending to a COM port without interrumping it (defying Heisenberg´s uncertainty principle...)
     
    Could you suggest any clues on how to do this?
     
    Thanks,
    Regards.
    NewsThanks for Postmembersatish_abiram11 Jul '07 - 4:26 
    Hello
    Your Post help me a lot Smile | :)
    once again Thanks for the Post
    Generalneed help serial port hookingmemberfionashrek0328 Jun '06 - 2:22 
    I am a beginner, trying to make an application in Borland C++ builder that can monitor the chat communication(openned port as file using windows API) going on serial port, I read different funcitons but couldn't understand. it will be so kind of you to guide me how to create a hook to sniff the in and out traffic on serial port thanks
     
    Akram Mahmood
    GeneralMonitor WriteProcessMemorymemberVitoto12 Jan '06 - 6:50 
    Is posible use you code for detect any program using API WriteProcessMemory ?
     
    This dll working when is used in .Net ?
     
    Thank you.
    QuestionWho can give me a example of use HookImportFunctionByName v1.0?memberdimu28 Mar '05 - 2:31 
    Thanks!Rose | [Rose]
    Generalkernel hooking pleasmembereslamspider26 Mar '05 - 22:01 
    i dont know how to use this function can u provide me with a working project i'm new in useing vc++
    pleas can u support me with a way to hook the "system calls" i need it
    thnak u
    GeneralRe: kernel hooking pleasmemberpjnaughter27 Mar '05 - 1:38 
    As pointed out on my web site at www.naughter.com, I've stopped developing this and instead refer you to the Jeffrey Richter implementation in his book
    GeneralCAPIHook another Processmemberneo260077728 May '04 - 6:01 
    Where can I get this class? That book has been out of print for quite some time. Will it for for hooking the API calls of another process?
    GeneralRe: CAPIHook another Processmemberpjnaughter28 May '04 - 6:33 
    Try the following URL: http://www.microsoft.com/learning/books/howtobuy/buy.asp
    GeneralRe: CAPIHook another Processmemberneo260077728 May '04 - 8:06 
    before I buy a used $300 book, do you know if that class with willwork to hook another process?
    GeneralRe: CAPIHook another Processmemberpjnaughter28 May '04 - 9:42 
    CAPIHook will work on other processes as easily as your process. There are various techniques used to implement the hooking and it really depends on what your requirements are as to which one are best:
     
    Win9x: Cannot hook calls above 2GB due to OS limitations
     
    AppInit_Dlls: This technique does not work on Win9x. Also will not work on apps which do not link to user32.dll. Mapped into all GUI apps for the lifetime of each app.
    SetWindowsHooksEx:
     
    Remote Threads: Does not work on Win9x due to lack of CreateRemoteThread support.
     
    Using a Trojan DLL: Requires that you export all the functions of the dll you are replacing and can cause problems when new versions of the dll being replaced are released.
     
    Injecting a DLL as a Debugger: Requires machine specific assembly language + the only way to release the hook is to terminate the debuggee (unless you are using XP or greater)
     
    Using a Memory Mapped file: Only works on Win9x, plus requires hand crafted X86 assembler.
     
    Using CreateProcess: Can only be used if the application being hooked is a child process, the most complicated mechanism, but the most flexible plus it works on Win9x as well as NT Kernels.
     
    It you can provide further info on what you are trying to do, they I may be able to advise your better.
     
    Also make sure you get the fourth edition of the book as I believe the API hook section is now available in earlier copies.
    GeneralRe: CAPIHook another Processmemberneo260077728 May '04 - 11:29 
    I have a process that is spawning a child process with CreateProcess. I want to filter the files that it is opening. (Allow or deny access to files). So I was going to hook all the open file API calls.
     
    The book is not availiable at the link you listed. Like I said it has been out of print for some time. I can't find any resource to find this class.
    GeneralCan't hook into the kernel under Win9xmemberHotFox8 Oct '03 - 16:29 
    If only want to hook the functions called by my own app, I am sure that it works well. But if I want to hook functions imported by the kernel(kernel32.dll/gdi32.dll/user32.dll), which are in the protected memory block above 2G under Win9x, the function shown above will lead to a critical failure.
    Any hints about patching the IAT above 2G memory under Win9x?Confused | :confused:
    Thanks.
    GeneralRe: Can't hook into the kernel under Win9xmemberpjnaughter9 Oct '03 - 2:30 
    Patching the IAT above 2G on Win9x: First off the code explicitely handles the case of disallowing this. I'd suggest you get the latest version from my web site (www.naughter.com).
     
    Also I'd suggest you get a copy of the book "Programming Applications for Microsoft Windows" by Jeffrey Richter for further discussion on this topic.
    GeneralRe: Can't hook into the kernel under Win9xsussvawksel10 Oct '03 - 23:41 
    Hey, first off, great piece of code you have done! It works really well in almost all cases I personally need.
     
    I am at a wall though, I have my dll injected into every process on Win9x through WinXP, but alas, I can not patch into kernel32.dll to monitor CreateFile() and CloseHandle() for the simple reason of the 2gb barrier.
     
    Is this possible at all? Should I drop this method and find another way? I have Jeffrey Richter's books btw Wink | ;) Very good books indeed.
     
    - Jeff
     

    GeneralRe: Can't hook into the kernel under Win9xsussvawksel10 Oct '03 - 23:43 
    Actually, I would like to add to my previous problem, I am only supporting Windows 98 and ME. I am not supporting Windows 95. I dont know if this will make it easier for me to find a way to patch kernel32.dll or not.
     
    Thanks for your insight.

    GeneralRe: Can't hook into the kernel under Win9xmemberpjnaughter11 Oct '03 - 6:04 
    I think you will need to look into some other mechanism as this is a defficiency of any Win9x OS.
    GeneralRe: Can't hook into the kernel under Win9xmembervawksel11 Oct '03 - 9:50 
    Thank you for your help. Actually, I didn't realize I was missing Edition 4 of Jeffrey Richters Windows book, chapter 22 on CApiHook, will that help me?
     

    GeneralRe: Can't hook into the kernel under Win9xmemberpjnaughter12 Oct '03 - 4:07 
    Ya, I think so. The reason I gave up development of HookImportFunctionByName is because the CApiHook code is so much more comprehensive.
    GeneralA ProblemmemberKevinBai13 Jan '02 - 15:52 
    Dear Naughter,
    I'm a Chinese student in the Institute of Remote Sensing Applications,Chinese Academy of Sciences.
    In recent days,I took much time on programming about Hook.It's not very easy for me until I searched one of your paper,HookImportFunctionByName, on The CODE PROJECT.It works well and you really did a good job.
    After downloaded the souch code,I made some tests on it,but have some problems.Would you mind giving me some help?
    I made a dialog based MFC EXE project ,adding the HookImportFunction.h and HookImportFunction.cpp to the project, puting two buttons on it,just call them button1 and button2.
    For the button1,useing the HookImportFunctionsByName() to try filter some particular function,for example, function1().For the button2,it will call function1(),no matter it was hooked or not.
    For this testing program, the user is supposed to press the button2 first, and then press the button1,and then press button2 at last.
    If the function1 is hooked, the latter pressing of button2 will not do the same way with the first one.

    I first try to filter the Beep function in the KERNEL32.DLL,It did work well. After the calling of HookImportFunctionsByName, the sixth parameter was set to 1,it means that one function had be changed.For the latter push of button2, it just show a dialog with a message of "I'm here!".
    But if I changed the params to TextOutA() in the GDI32.DLL, the HookImportFunctionsByName() didn't find the corresponding the thunk area and the sixth parameter was set to 0, the same value with the initial value before calling HookImportFunctionsByName().
    And then I tried to test the GetDlgItem() in the USER32.DLL, but it also didn't work.
    So, could you please give me some help?
    Bye the way, I've visited your homepage and your new house is very beautiful,I hope you'll enjoy more fun there!
    Truely sorry for interrupting you and wasting much of your time.
    Best regards,

    Confused | :confused:
     
    Yuqi Bai
    kevinbaisoft@263.net
    GeneralRe: A ProblemmemberTom Daffin24 Apr '03 - 15:40 
    You need to use the names of these functions somewhere in your code, so that they get into the import descriptor; to be sure they get in, but don't get optimized out by the compiler you could use something like this;
     
         int k = 0;
         if ( k )
         {
              ::TextOutA(whatever parameters will keep the compiler happy);
              ::GetDlgItem(whatever parameters will keep the compiler happy);
         }
    GeneralRe: A Problemmemberespboy18 May '03 - 3:29 
    Could u show me how can it work in serial port monitor?
    puzzled me for long time
     

    555555~~~~~~~~~~~
     
    Confused | :confused: Confused | :confused: Confused | :confused: Confused | :confused: Confused | :confused:
     
    yes!
    GeneralRe: A Problemmemberpjnaughter18 May '03 - 5:54 
    You would need to hook the calls CreateFile filter on the filename it opens looking for serial port devices. You would also need to hook all the serial port functions you are interesting in. Depending on what you want, you may need to arrange for the dll to be injected into the address spaces of the processes you want to monitor. As I have documented on http://www.naughter.com/hookimportfunction.html, I have not given up supporting this code and point people to the Richter implementation from the book "Programming Applications for Microsoft Windows".
    GeneralRe: A Problemmemberdimu28 Mar '05 - 2:24 
    Smile | :) Dear Yuqi Bai,
    I'm also a chinese student.how can i contact you.
    I have some question to ask you.

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

    Permalink | Advertise | Privacy | Mobile
    Web02 | 2.6.130516.1 | Last Updated 4 Mar 2000
    Article Copyright 2000 by PJ Naughter
    Everything else Copyright © CodeProject, 1999-2013
    Terms of Use
    Layout: fixed | fluid