/*
Module : HookImportFunction.cpp
Purpose: Defines the implementation for code to hook a call to any imported Win32 SDK
Created: PJN / 23-10-1999
History: PJN / 01-01-2001 1. Now includes copyright message in the source code and documentation.
                          2. Fixed an access violation in where I was getting the name of the import
                          function but not checking for failure.
                          3. Fixed a compiler error where I was incorrectly casting to a PDWORD instead
                          of a DWORD
         PJN / 20-04-2002 1. Fixed a potential infinite loop in HookImportFunctionByName. Thanks to
                          David Defoort for spotting this problem.

Copyright (c) 1996 - 2002 by PJ Naughter.  (Web: www.naughter.com, Email: pjna@naughter.com)

All rights reserved.

Copyright / Usage Details:

You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
when your product is released in binary form. You are allowed to modify the source code in any way you want 
except you cannot modify the copyright details at the top of each module. If you want to distribute source 
code with your application, then you are only allowed to distribute versions released by the author. This is 
to maintain a single distribution point for the source code. 

*/


////////////////// Includes ////////////////////////////////////

#include <windows.h>
#include "HookImportFunction.h"

#define ASSERT(e)
#define VERIFY(e) e
#define TRACE0(s) OutputDebugString(s)
#define _T(s) s

////////////////// Defines / Locals ////////////////////////////

#ifdef _DEBUG
  #define new DEBUG_NEW
  #undef THIS_FILE
  static char THIS_FILE[] = __FILE__;
#endif

#define MakePtr(cast, ptr, AddValue) (cast)((DWORD)(ptr)+(DWORD)(AddValue))

BOOL IsNT();



////////////////// Implementation //////////////////////////////

BOOL HookImportFunctionsByName(HMODULE hModule, LPCSTR szImportMod, UINT uiCount, 
                               LPHOOKFUNCDESC paHookArray, PROC* paOrigFuncs, UINT* puiHooked)
{
  // Double check the parameters.
  ASSERT(szImportMod);
  ASSERT(uiCount);
  ASSERT(!IsBadReadPtr(paHookArray, sizeof(HOOKFUNCDESC)*uiCount));

#ifdef _DEBUG
  if (paOrigFuncs)
    ASSERT(!IsBadWritePtr(paOrigFuncs, sizeof(PROC)*uiCount));
  if (puiHooked)
    ASSERT(!IsBadWritePtr(puiHooked, sizeof(UINT)));

  //Check each function name in the hook array.
  for (UINT i = 0; i<uiCount; i++)
  {
    ASSERT(paHookArray[i].szFunc);
    ASSERT(*paHookArray[i].szFunc != _T('\0'));

    //If the proc is not NULL, then it is checked.
    if (paHookArray[i].pProc)
      ASSERT(!IsBadCodePtr(paHookArray[i].pProc));
  }
#endif

  //Do the parameter validation for real.
  if (uiCount == 0 || szImportMod == NULL || IsBadReadPtr(paHookArray, sizeof(HOOKFUNCDESC)* uiCount))
  {
    ASSERT(FALSE);
    SetLastErrorEx(ERROR_INVALID_ADDRESS, SLE_ERROR);
    return FALSE;
  }

  if (paOrigFuncs && IsBadWritePtr(paOrigFuncs, sizeof(PROC)*uiCount))
  {
    ASSERT(FALSE);
    SetLastErrorEx(ERROR_INVALID_ADDRESS, SLE_ERROR);
    return FALSE;
  }

  if (puiHooked && IsBadWritePtr(puiHooked, sizeof(UINT)))
  {
    ASSERT(FALSE);
    SetLastErrorEx(ERROR_INVALID_ADDRESS, SLE_ERROR );
    return FALSE;
  }

  //Is this a system DLL, which Windows95 will not let you patch
  //since it is above the 2GB line?
  if (!IsNT() && ((DWORD)hModule >= 0x80000000))
  {
    #ifdef _DEBUG
    CString sMsg;
    sMsg.Format(_T("Could not hook module %x because we are on Win9x and it is in shared memory\n"), hModule);
    OutputDebugString(sMsg);
    #endif
    SetLastErrorEx(ERROR_INVALID_HANDLE, SLE_ERROR);
    return FALSE;
  }

  //TODO TODO
  // Should each item in the hook array be checked in release builds?

  if (puiHooked)
    *puiHooked = 0; //Set the number of functions hooked to zero.

  //Get the specific import descriptor.
  PIMAGE_IMPORT_DESCRIPTOR pImportDesc = GetNamedImportDescriptor(hModule, szImportMod);
  if (NULL == pImportDesc)
    return FALSE; // The requested module was not imported.

  HINSTANCE hImportMod = GetModuleHandle(szImportMod);
  if (NULL == hImportMod)
  {
    ASSERT(FALSE);
    SetLastErrorEx(ERROR_HOOK_NEEDS_HMOD, SLE_ERROR);
    return FALSE; // The requested module was not available.
  }

  //Set all the values in paOrigFuncs to NULL.
  if (NULL != paOrigFuncs)
    memset(paOrigFuncs, NULL, sizeof(PROC)*uiCount);

  //Get the original thunk information for this DLL.  I cannot use
  // the thunk information stored in the pImportDesc->FirstThunk
  // because the that is the array that the loader
  // has already bashed to fix up all the imports. 
  // This pointer gives us acess to the function names.
  PIMAGE_THUNK_DATA pOrigThunk = MakePtr(PIMAGE_THUNK_DATA, hModule, pImportDesc->OriginalFirstThunk);

  //Get the array pointed to by the pImportDesc->FirstThunk. 
  // This is where I will do the actual bash.
  PIMAGE_THUNK_DATA pRealThunk = MakePtr(PIMAGE_THUNK_DATA, hModule, pImportDesc->FirstThunk);

  //Loop through and look for the one that matches the name.
  for (; NULL != pOrigThunk->u1.Function;
      // Increment both tables.
      pOrigThunk++, pRealThunk++)
  {
    //Only look at those that are imported by name, not ordinal.
    if (IMAGE_ORDINAL_FLAG == (IMAGE_ORDINAL_FLAG & pOrigThunk->u1.Ordinal))
      continue;

    //Look get the name of this imported function.
    PIMAGE_IMPORT_BY_NAME pByName = MakePtr(PIMAGE_IMPORT_BY_NAME, hModule, pOrigThunk->u1.AddressOfData);

    if (IsBadReadPtr(pByName, MAX_PATH+4))
    {
      SetLastErrorEx(ERROR_INVALID_ADDRESS, SLE_ERROR);
      continue;
    }

    //If the name starts with NULL, then just skip to next.
    if (_T('\0') == pByName->Name[0])
      continue;

    //Determines if we do the hook.
    BOOL bDoHook = FALSE;

    //TODO {
    // Might want to consider bsearch here.
    //TODO }
    //See if the particular function name is in the import
    // list.  It might be good to consider requiring the
    // paHookArray to be in sorted order so bsearch could be
    // used so the lookup will be faster.  However, the size of
    // uiCount coming into this function should be rather small
    // but it is called for each function imported by szImportMod.
    for (UINT i = 0; i<uiCount; i++)
    {
      if ((paHookArray[i].szFunc[0] == pByName->Name[0]) &&
        (strcmpi(paHookArray[i].szFunc, (char*)pByName->Name) == 0))
      {
        //If the proc is NULL, kick out, otherwise
        // go ahead and hook it.
        if (paHookArray[i].pProc)
          bDoHook = TRUE;
        break;
      }
    }

    if (FALSE == bDoHook)
      continue;

    // I found it.  Now I need to change the protection to
    //  writable before I do the blast.  Note that I am now
    //  blasting into the real thunk area!
    MEMORY_BASIC_INFORMATION mbi_thunk;
    VirtualQuery(pRealThunk, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
    VERIFY(VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect));

    // Get fast/simple pointer
    PROC* pFunction = (PROC*) &(pRealThunk->u1.Function);
    if (*pFunction == paHookArray[i].pProc)
    {
      SetLastErrorEx(ERROR_ALREADY_INITIALIZED, SLE_ERROR);
      return FALSE;
    }
    if (IsBadCodePtr(*pFunction))
    {
      ASSERT(FALSE);
      SetLastErrorEx(ERROR_INVALID_ADDRESS, SLE_ERROR);
      return FALSE;
    }
    //Save the original address if requested.
    if (NULL != paOrigFuncs)
    {
      if ((DWORD)(*pFunction) < (DWORD)hImportMod && ((DWORD)(0x80000000) > (DWORD)hImportMod))
      {
        ASSERT(FALSE);
        SetLastErrorEx(ERROR_INVALID_ADDRESS, SLE_ERROR);
        return FALSE;
      }
      if (*pFunction != paOrigFuncs[i])
      {
        if (NULL != paOrigFuncs[i])
        {
          if (paHookArray[i].pProc != paOrigFuncs[i])
          {
            ASSERT(FALSE);
            SetLastErrorEx(ERROR_INVALID_ADDRESS, SLE_ERROR);
            return FALSE;
          }
        }
        paOrigFuncs[i] = * pFunction;
      }
    }
    //Do the actual hook.
    *pFunction = paHookArray[i].pProc;

    //Increment the total number hooked.
    if (puiHooked)
      *puiHooked += 1; 

    //Change the protection back to what it was before I blasted.
    DWORD dwOldProtect;
    VERIFY(VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, mbi_thunk.Protect, &dwOldProtect));
  }
  //All OK, JumpMaster!
  SetLastError(ERROR_SUCCESS);
  return TRUE;
}

PIMAGE_IMPORT_DESCRIPTOR GetNamedImportDescriptor(HMODULE hModule, LPCSTR szImportMod)
{
  //Always check parameters.
  ASSERT(szImportMod);
  ASSERT(hModule);
  if ((szImportMod == NULL) || (hModule == NULL))
  {
    ASSERT(FALSE);
    SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
    return NULL;
  }

  //Get the Dos header.
  PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER) hModule;

  // Is this the MZ header?
  if (IsBadReadPtr(pDOSHeader, sizeof(IMAGE_DOS_HEADER)) || (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE))
  {
    #ifdef _DEBUG
    CString sMsg;
    sMsg.Format(_T("Could not find the MZ Header for %x\n"), hModule);
    OutputDebugString(sMsg);
    #endif
    SetLastErrorEx( ERROR_BAD_EXE_FORMAT, SLE_ERROR);
    return NULL;
  }

  // Get the PE header.
  PIMAGE_NT_HEADERS pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDOSHeader, pDOSHeader->e_lfanew);

  //Is this a real PE image?
  if (IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) || (pNTHeader->Signature != IMAGE_NT_SIGNATURE))
  {
    ASSERT(FALSE);
    SetLastErrorEx( ERROR_INVALID_EXE_SIGNATURE, SLE_ERROR);
    return NULL;
  }

  //If there is no imports section, leave now.
  if (pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0)
    return NULL;

  // Get the pointer to the imports section.
  PIMAGE_IMPORT_DESCRIPTOR pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDOSHeader, pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

  //Loop through the import module descriptors looking for the module whose name matches szImportMod.
  while (pImportDesc->Name)
  {
    PSTR szCurrMod = MakePtr(PSTR, pDOSHeader, pImportDesc->Name);
    if (stricmp(szCurrMod, szImportMod) == 0)
      break; // Found it.

    //Look at the next one.
    pImportDesc++;
  }

  //If the name is NULL, then the module is not imported.
  if (pImportDesc->Name == NULL)
    return NULL;

  //All OK, Jumpmaster!
  return pImportDesc;
}

BOOL IsNT()
{
  OSVERSIONINFO stOSVI;
  memset(&stOSVI, NULL, sizeof(OSVERSIONINFO));
  stOSVI.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

  BOOL bRet = GetVersionEx(&stOSVI);
  ASSERT(TRUE == bRet);
  if (FALSE == bRet)
  {
    TRACE0("GetVersionEx failed!\n");
    return FALSE;
  }

  //Check the version and call the appropriate thing.
  return (VER_PLATFORM_WIN32_NT == stOSVI.dwPlatformId);
}
