Hijack Textout Calls From Notepad | CodeGuru

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 […]

Written By
CodeGuru Staff
CodeGuru Staff
Apr 4, 2002
1 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

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

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.