/* hookapi.cc

This file is part of Cygwin.

This software is a copyrighted work licensed under the terms of the
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
details. */

#include "winsup.h"
#include <stdlib.h>
#include <sys/param.h>
#include "ntdll.h"
#include "cygerrno.h"
#include "security.h"
#include "path.h"
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"

#define rva(coerce, base, addr) (coerce) ((char *) (base) + (addr))
#define rvacyg(coerce, addr) rva (coerce, cygwin_hmodule, addr)

struct function_hook
{
  const char *name;	// Function name, e.g. "DirectDrawCreateEx".
  const void *hookfn;	// Address of your function.
  void *origfn;		// Stored by HookAPICalls, the address of the original function.
};

/* Given an HMODULE, returns a pointer to the PE header. */
static PIMAGE_NT_HEADERS
PEHeaderFromHModule (HMODULE hModule, bool &is_64bit)
{
  PIMAGE_NT_HEADERS pNTHeader;

  if (PIMAGE_DOS_HEADER (hModule) ->e_magic != IMAGE_DOS_SIGNATURE)
    pNTHeader = NULL;
  else
    {
      pNTHeader = PIMAGE_NT_HEADERS (PBYTE (hModule)
				     + PIMAGE_DOS_HEADER (hModule) ->e_lfanew);
      if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
	pNTHeader = NULL;
      else if (pNTHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
      	is_64bit = true;
      else if (pNTHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
      	is_64bit = false;
      else
	pNTHeader = NULL;
    }

  return pNTHeader;
}

static long
rvadelta (PIMAGE_NT_HEADERS pnt, DWORD import_rva, DWORD &max_size)
{
  PIMAGE_SECTION_HEADER section = (PIMAGE_SECTION_HEADER) (pnt + 1);
  for (int i = 0; i < pnt->FileHeader.NumberOfSections; i++)
    if (section[i].VirtualAddress <= import_rva
	&& (section[i].VirtualAddress + section[i].Misc.VirtualSize) > import_rva)
      {
	max_size = section[i].SizeOfRawData
		   - (import_rva - section[i].VirtualAddress);
	return section[i].VirtualAddress - section[i].PointerToRawData;
      }
  return -1;
}

/* This function is only used for the current architecture.
   Just the size of the IMAGE_THUNK_DATA Function member differs. */
static void *
putmem (PIMAGE_THUNK_DATA pi, const void *hookfn)
{
#ifdef __x86_64__
#define THUNK_FUNC_TYPE ULONGLONG
#else
#define THUNK_FUNC_TYPE DWORD
#endif

  DWORD ofl;
  if (!VirtualProtect (pi, sizeof (THUNK_FUNC_TYPE), PAGE_READWRITE, &ofl) )
    return NULL;

  void *origfn = (void *) pi->u1.Function;
  pi->u1.Function = (THUNK_FUNC_TYPE) hookfn;

  VirtualProtect (pi, sizeof (THUNK_FUNC_TYPE), ofl, &ofl);
  return origfn;
}

/* Builds stubs for and redirects the IAT for one DLL (pImportDesc)
   This function is only used for the current architecture. */

static bool
RedirectIAT (function_hook& fh, PIMAGE_IMPORT_DESCRIPTOR pImportDesc,
	     HMODULE hm)
{
  // If no import names table, we can't redirect this, so bail
  if (pImportDesc->OriginalFirstThunk == 0)
      return false;

  /* import address table */
  PIMAGE_THUNK_DATA pt = rva (PIMAGE_THUNK_DATA, hm, pImportDesc->FirstThunk);
  /* import names table */
  PIMAGE_THUNK_DATA pn = rva (PIMAGE_THUNK_DATA, hm, pImportDesc->OriginalFirstThunk);

  /* Scan through the IAT, completing the stubs and redirecting the IAT
     entries to point to the stubs. */
  for (PIMAGE_THUNK_DATA pi = pt; pn->u1.Ordinal; pi++, pn++)
    {
      if (IMAGE_SNAP_BY_ORDINAL (pn->u1.Ordinal) )
	continue;

      /* import by name */
      PIMAGE_IMPORT_BY_NAME pimp = rva (PIMAGE_IMPORT_BY_NAME, hm, pn->u1.AddressOfData);

      if (strcmp (fh.name, (char *) pimp->Name) == 0)
	{
	  fh.origfn = putmem (pi, fh.hookfn);
	  if (!fh.origfn)
	    return false;
	  hook_chain *hc;
	  for (hc = &cygheap->hooks; hc->next; hc = hc->next)
	    continue;
	  hc->next = (hook_chain *) cmalloc_abort (HEAP_1_HOOK, sizeof (hook_chain));
	  hc->next->loc = (void **) pi;
	  hc->next->func = fh.hookfn;
	  hc->next->next = NULL;
	  break;
      }
  }

  return true;
}

/* This function is only used for the current architecture. */
static void
get_export (function_hook& fh)
{
  PIMAGE_DOS_HEADER pdh = (PIMAGE_DOS_HEADER) cygwin_hmodule;
  if (pdh->e_magic != IMAGE_DOS_SIGNATURE)
    return;
  PIMAGE_NT_HEADERS pnt = (PIMAGE_NT_HEADERS) ((char *) pdh + pdh->e_lfanew);
  if (pnt->Signature != IMAGE_NT_SIGNATURE || pnt->FileHeader.SizeOfOptionalHeader == 0)
    return;
  PIMAGE_EXPORT_DIRECTORY pexp =
    rvacyg (PIMAGE_EXPORT_DIRECTORY,
	 pnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
  if (!pexp)
    return;

  PDWORD pfuncs = rvacyg (PDWORD, pexp->AddressOfFunctions);
  PDWORD pnames = rvacyg (PDWORD, pexp->AddressOfNames);
  for (DWORD i = 0; i < pexp->NumberOfNames; i++)
    if (strcmp (fh.name, rvacyg (char *, pnames[i])) == 0)
      {
	fh.origfn = rvacyg (void *, pfuncs[i]);
	break;
      }
}

static const char *
makename (const char *name, char *&buf, int& i, int inc)
{
  i += inc;
  static const char *testers[] = {"NOTUSED", "64", "32"};
  if (i < 0 || i >= (int) (sizeof (testers) / sizeof (testers[0])))
    return NULL;
  if (i)
    {
      __small_sprintf (buf, "_%s%s", name, testers[i]);
      name = buf;
    }
  return name;
}

static HMODULE
remap (PIMAGE_IMPORT_DESCRIPTOR &pdfirst, long &delta, HANDLE hc,
       DWORD importRVA, DWORD importRVASize, DWORD importRVAMaxSize)
{
  /* If h is not NULL, the calling function only mapped at most the first
     64K of the image.  The IAT is usually at the end of the image, so
     what we do here is to map the IAT into our address space if it doesn't
     reside in the first 64K anyway.  The offset must be a multiple of the
     allocation granularity, though, so we have to map a bit more. */
  HMODULE map;
  DWORD offset = rounddown (importRVA, wincap.allocation_granularity ());
  /* But that's not all, unfortunately.  Apparently there's a difference
     between the importRVASize of applications built with gcc and those
     built with Visual Studio.  When built with gcc, importRVASize contains
     the size of the import RVA table plus the size of the referenced
     string table with the DLL names.  When built with VS, it only contains
     the size of the naked import RVA table.  The following code handles
     the situation.  importRVAMaxSize contains the size of the remainder
     of the section.  If the difference between importRVAMaxSize and
     importRVASize is less than 64K, we just use importRVAMaxSize to
     compute the size of the memory map.  Otherwise the executable may be
     very big.  In that case we only map the import RVA table and ... */
  DWORD size = importRVA - offset + ((importRVAMaxSize - importRVASize
				      <= wincap.allocation_granularity ())
				     ? importRVAMaxSize : importRVASize);
  map = (HMODULE) MapViewOfFile (hc, FILE_MAP_READ, 0, offset, size);
  if (!map)
    return NULL;
  pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, map, importRVA - offset);
  /* ... carefully check the required size to fit the string table into
     the map as well.  Allow NAME_MAX bytes for the DLL name, but don't
     go beyond the remainder of the section. */
  if (importRVAMaxSize - importRVASize > wincap.allocation_granularity ())
    {
      DWORD newsize = size;
      for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++)
	if (pd->Name - delta - offset + (NAME_MAX + 1) > newsize)
	  newsize = pd->Name - delta - offset + (NAME_MAX + 1);
      if (newsize > size)
	{
	  if (newsize > importRVA - offset + importRVAMaxSize)
	    newsize = importRVA - offset + importRVAMaxSize;
	  UnmapViewOfFile (map);
	  map = (HMODULE) MapViewOfFile (hc, FILE_MAP_READ, 0, offset, newsize);
	  if (!map)
	    return NULL;
	  pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, map, importRVA - offset);
	}
    }
  delta += offset;
  return map;
}

/* Find first missing dll in a given executable.
   FIXME: This is not foolproof since it doesn't look for dlls in the
   same directory as the given executable, like Windows.  Instead it
   searches for dlls in the context of the current executable.
   It also only finds direct dependencies, not indirect ones. */
const char *
find_first_notloaded_dll (path_conv& pc)
{
  const char *res = "?";
  HANDLE hc = NULL;
  HMODULE hm = NULL;
  OBJECT_ATTRIBUTES attr;
  IO_STATUS_BLOCK io;
  HANDLE h;
  NTSTATUS status;
  LARGE_INTEGER size;
  PIMAGE_NT_HEADERS pExeNTHdr;
  DWORD importRVA, importRVASize, importRVAMaxSize;
  HMODULE map;
  long delta;

  status = NtOpenFile (&h, SYNCHRONIZE | GENERIC_READ,
		       pc.get_object_attr (attr, sec_none_nih),
		       &io, FILE_SHARE_VALID_FLAGS,
		       FILE_SYNCHRONOUS_IO_NONALERT
		       | FILE_OPEN_FOR_BACKUP_INTENT
		       | FILE_NON_DIRECTORY_FILE);
  if (!NT_SUCCESS (status))
    goto out;
  /* Just as in hook_or_detect_cygwin below, we have to take big executables
     into account.  That means, we must not try to map the entire file, since
     there's no guarantee that the current process has enough VM in one block
     left for this mapping.  The offset computation below ignores very big
     executables for now.  In theory, since the import RVA table appears to
     be more or less at the end of the data section, independent of the used
     compiler, that shouldn't matter. */
  if (!GetFileSizeEx (h, &size))
    {
      NtClose (h);
      goto out;
    }
  if (size.QuadPart > (LONGLONG) wincap.allocation_granularity ())
    size.LowPart = wincap.allocation_granularity ();
  hc = CreateFileMapping (h, &sec_none_nih, PAGE_READONLY, 0, 0, NULL);
  NtClose (h);
  if (!hc)
    goto out;
  hm = (HMODULE) MapViewOfFile(hc, FILE_MAP_READ, 0, 0, size.LowPart);
  if (!hm)
    goto out;

  bool is_64bit;
  pExeNTHdr = PEHeaderFromHModule (hm, is_64bit);

  if (!pExeNTHdr)
    goto out;

#ifdef __x86_64__
  if (!is_64bit)
#else
  if (is_64bit)
#endif
    goto out;

  importRVA = pExeNTHdr->OptionalHeader.DataDirectory
			[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  importRVASize = pExeNTHdr->OptionalHeader.DataDirectory
			[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
  if (!importRVA)
    goto out;

  delta = rvadelta (pExeNTHdr, importRVA, importRVAMaxSize);
  if (delta < 0)
    goto out;
  importRVA -= delta;
  map = NULL;

  PIMAGE_IMPORT_DESCRIPTOR pdfirst;

  if (importRVA + importRVAMaxSize > wincap.allocation_granularity ())
    {
      map = remap (pdfirst, delta, hc, importRVA, importRVASize,
		   importRVAMaxSize);
      if (!map)
	goto out;
    }
  else
    pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, hm, importRVA);

  /* Iterate through each import descriptor, and check if DLL can be loaded. */
  for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++)
    {
      const char *lib = rva (PSTR, map ?: hm, pd->Name - delta);
      if (!LoadLibraryEx (lib, NULL, DONT_RESOLVE_DLL_REFERENCES
				     | LOAD_LIBRARY_AS_DATAFILE))
	{
	  static char buf[MAX_PATH];
	  strlcpy (buf, lib, MAX_PATH);
	  res = buf;
	}
    }
  if (map)
    UnmapViewOfFile (map);

out:
  if (hm)
    UnmapViewOfFile (hm);
  if (hc)
    CloseHandle (hc);

  return res;
}

// Top level routine to find the EXE's imports and redirect them
void *
hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys, HANDLE h)
{
  HMODULE hm = fn ? GetModuleHandle (NULL) : (HMODULE) name;
  bool is_64bit;
  PIMAGE_NT_HEADERS pExeNTHdr = PEHeaderFromHModule (hm, is_64bit);

  if (!pExeNTHdr)
    return NULL;

  /* Shortcut.  We don't have to do anything further from here, if the
     executable's architecture doesn't match, unless we want to support
     a mix of 32 and 64 bit Cygwin at one point. */
#ifdef __x86_64__
  if (!is_64bit)
#else
  if (is_64bit)
#endif
    return NULL;

  DWORD importRVA, importRVASize;
  subsys = pExeNTHdr->OptionalHeader.Subsystem;
  importRVA = pExeNTHdr->OptionalHeader.DataDirectory
			[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  importRVASize = pExeNTHdr->OptionalHeader.DataDirectory
			[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
  if (!importRVA)
    return NULL;

  DWORD importRVAMaxSize = 0;
  long delta = fn ? 0 : rvadelta (pExeNTHdr, importRVA, importRVAMaxSize);
  if (delta < 0)
    return NULL;
  importRVA -= delta;

  // Convert imports RVA to a usable pointer
  PIMAGE_IMPORT_DESCRIPTOR pdfirst;
  char *map = NULL;
  if (h && importRVA + importRVAMaxSize > wincap.allocation_granularity ())
    {
      map = (char *) remap (pdfirst, delta, h, importRVA, importRVASize,
			    importRVAMaxSize);
      if (!map)
	return NULL;
    }
  else
    pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, hm, importRVA);

  function_hook fh;
  fh.origfn = NULL;
  fh.hookfn = fn;
  char *buf = NULL;
  if (fn)
    buf = (char *) alloca (strlen (name) + sizeof ("_64"));
  int i = 0;
  // Iterate through each import descriptor, and redirect if appropriate
  for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++)
    {
      if (!ascii_strcasematch (rva (PSTR, map ?: (char *) hm, pd->Name - delta),
			       "cygwin1.dll"))
      	continue;
      if (!fn)
	{
	  /* Just checking if executable used cygwin1.dll. */
	  if (map)
	    UnmapViewOfFile (map);
	  return (void *) "found it";
	}
      i = -1;
      while (!fh.origfn && (fh.name = makename (name, buf, i, 1)))
	RedirectIAT (fh, pd, hm);
      if (fh.origfn)
	break;
    }

  if (map)
    UnmapViewOfFile (map);
  if (!fn)
    return NULL;

  while (!fh.origfn && (fh.name = makename (name, buf, i, -1)))
    get_export (fh);

  return fh.origfn;
}

void
ld_preload ()
{
  char *p = getenv ("LD_PRELOAD");
  if (!p)
    return;
  char *s = (char *) alloca (strlen (p) + 1);
  strcpy (s, p);
  char *here = NULL;
  for (p = strtok_r (s, ":\t\n", &here); p; p = strtok_r (NULL, ":\t\n", &here))
    {
      path_conv lib (p);
      WCHAR libname[lib.get_wide_win32_path_len () + 1];
      if (!LoadLibraryW (lib.get_wide_win32_path (libname)))
	{
	  __seterrno ();
	  api_fatal ("error while loading shared libraries: %s: "
		     "cannot open shared object file: %s", p,
		     strerror (get_errno ()));
	}
    }
}

void
fixup_hooks_after_fork ()
{
  for (hook_chain *hc = &cygheap->hooks; (hc = hc->next); )
    putmem ((PIMAGE_THUNK_DATA) hc->loc, hc->func);
}
