Hijack Textout Calls From Notepad

Environment: VC6, Win2000 Professional

Based on APIHijack - A Library for Easy DLL Function Hooking, by Wade Brainerd. Wade Brainerd gave us an excellent sample to hook DLL function calls. Yet there's still some aspects the sample didn't cover. If the DLL is loaded by calling LoadLibrary or the DLL isn't used by the hooked module directly, the sample doesn't work. So I made these changes:

//apihijack.h

//the maximum dll number can be hooked
const int MAX_DLL_NUMBER = 100;
...
struct SDLLHook
{
    // DLL name array, terminated with a NULL field;
    char* Name[MAX_DLL_NUMBER];

    // Set true to call the default for all non-hooked
    // functions before they are executed.
    bool UseDefault;
    void* DefaultFn;

    // Function hook array.  Terminated with a NULL Name field.
    SFunctionHook Functions[];
};
...
// Hook functions one or more DLLs.
bool HookAPICalls( SDLLHook* Hook, 
                   HMODULE hModule = GetModuleHandle(0));

//apihijack.cpp
#include 

std::set setModules;
...
bool HookAPICalls( SDLLHook* Hook, HMODULE hModule )
{
  char *fName = new char[100];
  GetModuleFileName(hModule, fName, 100);
  if (setModules.find(fName)!=setModules.end())
    return true;
  else
    setModules.insert(fName);
  OutputDebugString("filename=");
  OutputDebugString(fName);
  OutputDebugString("\n");
  delete[] fName;
  ....
  while ( pImportDesc->FirstThunk )
  {
      PSTR pszImportModuleName = 
            MakePtr( PSTR, hModule, pImportDesc->Name);

    for (int iNameIndex=0;
         iNameIndex<MAX_DLL_NUMBER;
         iNameIndex++)
    {
       char *dllName = Hook->Name[iNameIndex];
       if (!dllName)
         break;
       if ( lstrcmpi( pszImportModuleName, dllName ) == 0 )
       {
         OutputDebugString( "Found " );
         OutputDebugString( dllName );
         OutputDebugString( "...\n" );

         RedirectIAT( Hook, pImportDesc, (PVOID)hModule );
         break;
       }
    }
    HookAPICalls(Hook, GetModuleHandle(pszImportModuleName));
        
    pImportDesc++;  // Advance to next import descriptor
  }

  return true;  
}

//dllmain.cpp
SDLLHook TextHook = 
{
    {
       "GDI32.DLL",
       "KERNEL32.DLL",
       NULL
    },
    false,
    NULL,  // Default hook disabled, NULL function pointer.
    {
      { "ExtTextOutW", MyExtTextOutW },
      { "LoadLibraryA", MyLoadLibraryA }, 
      { "LoadLibraryW", MyLoadLibraryW },
      { "LoadLibraryExA", MyLoadLibraryExA }, 
      { "LoadLibraryExW", MyLoadLibraryExW },
      { NULL, NULL }
    }
};

// Hook function.
BOOL WINAPI MyExtTextOutW( HDC hdc,
                           int nXStart,
                           int nYStart,
                           UINT fuOptions,
                           const RECT FAR *lprc,
                           LPCSTR lpszString,
                           UINT cbString,
                           int FAR *lpDx)
{
  MessageBeep(MB_ICONINFORMATION);
  ExtTextOutW_Type OldFn = (ExtTextOutW_Type)
        TextHook.Functions[GDI32_ExtTextOutW].OrigFn;
  return OldFn( hdc, 
                nXStart,
                nYStart,
                fuOptions,
                lprc,
                lpszString,
                cbString,
                lpDx);
}

// The LoadLibrary Function 
HMODULE WINAPI MyLoadLibraryA(LPCSTR lpLibFileName) 
{ 
  // Get the old function 
  LoadLibrary_Type OldFn = (LoadLibrary_Type)
       TextHook.Functions[KERNEL32_LoadLibraryA].OrigFn;

  // A Place to store the module, that is returned 
  HMODULE retval; 

  OutputDebugString("LoadLibraryA( lpLibFileName "); 
  OutputDebugString(lpLibFileName); 
  OutputDebugString(" )\n"); 

  // Time to call the original function 
  retval = OldFn(lpLibFileName); 

  HookAPICalls(&TextHook, retval); 
  
  return retval;
} 

HMODULE WINAPI MyLoadLibraryW(LPCSTR lpLibFileName) 
{ 
  // Get the old function 
  LoadLibrary_Type OldFn = (LoadLibrary_Type)
        TextHook.Functions[KERNEL32_LoadLibraryW].OrigFn;

  // A Place to store the module, that is returned 
  HMODULE retval; 

  OutputDebugString("LoadLibraryW( lpLibFileName "); 
  OutputDebugString(lpLibFileName); 
  OutputDebugString(" )\n"); 

  // Time to call the original function 
  retval = OldFn(lpLibFileName); 

  HookAPICalls(&TextHook, retval); 
  
  return retval;
} 

HMODULE WINAPI MyLoadLibraryExA(LPCTSTR lpFileName,
                                HANDLE hFile,
                                DWORD dwFlags)
{
  // Get the old function 
  LoadLibraryEx_Type OldFn = (LoadLibraryEx_Type)
          TextHook.Functions[KERNEL32_LoadLibraryExA].OrigFn;

  // A Place to store the module, that is returned 
  HMODULE retval; 

  OutputDebugString("LoadLibraryExA( lpLibFileName "); 
  OutputDebugString(lpFileName); 
  OutputDebugString(" )\n"); 

  // Time to call the original function 
  retval = OldFn(lpFileName, hFile, dwFlags); 

  HookAPICalls(&TextHook, retval); 
  
  return retval;
}

HMODULE WINAPI MyLoadLibraryExW( LPCTSTR lpFileName,
                                 HANDLE hFile,
                                 DWORD dwFlags)
{
  // Get the old function 
  LoadLibraryEx_Type OldFn = (LoadLibraryEx_Type)
       TextHook.Functions[KERNEL32_LoadLibraryExW].OrigFn;

  // A Place to store the module, that is returned 
  HMODULE retval; 

  OutputDebugString("LoadLibraryExW( lpLibFileName ");
  OutputDebugString(lpFileName); 
  OutputDebugString(" )\n"); 

  // Time to call the original function 
  retval = OldFn(lpFileName, hFile, dwFlags); 

  HookAPICalls(&TextHook, retval);
  
  return retval;
}

// CBT Hook-style injection.
BOOL APIENTRY DllMain( HINSTANCE hModule,
                       DWORD fdwReason,
                       LPVOID lpReserved )
{
  if ( fdwReason == DLL_PROCESS_ATTACH ) // When initializing...
  {
     hDLL = hModule;

     // We don't need thread notifications for what we're 
     // doing.  Thus, get rid of them, thereby eliminating
     // some of the overhead of this DLL
     DisableThreadLibraryCalls( hModule );

     // Only hook the APIs if this is the Everquest proess.
     GetModuleFileName( GetModuleHandle( NULL ),
                        Work,
                        sizeof(Work) );
     PathStripPath( Work );

     OutputDebugString( "TESTDLL checking process: " );
     OutputDebugString( Work );
     OutputDebugString( "\n" );

     if ( stricmp( Work, "notepad.exe" ) == 0 )
     {
       HookAPICalls( &TextHook );
     }
  }

  return TRUE;
}

Downloads

Download demo project - 13 Kb


Comments

  • Could it cause an access violation error ?

    Posted by Legacy on 09/23/2003 12:00am

    Originally posted by: H.T.

    Could hijacking routines cause this error ? maybe because of security on a computer.. is it possible..?

    Reply
  • Just use SetWindowsHookEx to address mouse,keyboard,system event, and so on...

    Posted by Legacy on 01/10/2003 12:00am

    Originally posted by: zhenyong hu

    You can find more details in MSDN, just use SetWindowsHookEx as the keyword for index.

    Reply
  • To Hook APIs not in the IAT

    Posted by Legacy on 08/21/2002 12:00am

    Originally posted by: Wei Junping

    I'm sorry I made a mistake when I wrote this article. My program can only solve the problem with indirect call, but  not the problem with dynamical call ( call a function by LoadLibrary followed by GetProcAddress ). To solve the problem, please reference http://www.codeguru.com/mfc/comments/29915.shtml.
    

    Reply
  • Don't work for win98/95!!

    Posted by Legacy on 06/19/2002 12:00am

    Originally posted by: lsyca

    Why?

    Reply
  • doesn't work on my pc!!!

    Posted by Legacy on 06/17/2002 12:00am

    Originally posted by: lsyca

    I use win2k professional + vc6

    Reply
  • Title bar text, and others..

    Posted by Legacy on 05/31/2002 12:00am

    Originally posted by: Eduard

    I hooked the following functions:
    (Ext,Poly,Tabbed)TextOut, DrawText(Ex)
    both unicode and non-unicode (i.e. xxxW, and xxxA )

    But still there is a lot of text, in any application, that is not going through my functions, and an example of that is the title bar text.

    Any ideas why??

    Reply
  • doenst work for edit box in notepad

    Posted by Legacy on 05/29/2002 12:00am

    Originally posted by: habib

    Dear All,
    
    I downloaded the sample project but it doesnt catch when I type in edit box of note pad.
    yours,
    Habib

    Reply
  • How do you load Hook DLL in the same address space as Notepad??

    Posted by Legacy on 05/01/2002 12:00am

    Originally posted by: MS

    How do you load Hook DLL in the same address space as Notepad??

    Thanks

    Reply
  • Thanks Good Work But I need som help

    Posted by Legacy on 04/09/2002 12:00am

    Originally posted by: Ahmed A. Korany

    Thank you man for this excellent explaination
    
    Please could you help me and tel me how

    1-Modify the outed text when i change the lpszstring mebmber unknown letters appears.
    2-Modify the message in the WH_GETMESSAGE before it reaches the destination window

    3-in WH_JOURNALRECORD the journaling activity stops whet i press the windows key from the key board how can i prevent this.

    plz relpy me at Ahmed_Korany@hotmail.com
    thant you. :|

    Ahmed_Korany

    Reply
  • Why not Mathias Rauen's MadCodeHookLib?

    Posted by Legacy on 04/05/2002 12:00am

    Originally posted by: Miklos Pal

    link: http://www.madshi.net
    Commercial, but not expensive at all. Downloadable trial version. Not open source.

    Detours had a licence only for research when I tried. They did not answer my e-mail when I asked them about a commercial licence.

    I have tried both and found excellent.

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: September 10, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild". This loop of continuous delivery and continuous feedback is …

  • As mobile devices have pushed their way into the enterprise, they have brought cloud apps along with them. This app explosion means account passwords are multiplying, which exposes corporate data and leads to help desk calls from frustrated users. This paper will discover how IT can improve user productivity, gain visibility and control over SaaS and mobile apps, and stop password sprawl. Download this white paper to learn: How you can leverage your existing AD to manage app access. Key capabilities to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds