diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2011-10-25 20:35:58 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2011-10-25 20:35:58 +0400 |
commit | be2280986de5339bca3d648ec0e7538541dcd674 (patch) | |
tree | d31ee4917ee5b00f024ce32b89a065c8204f85b6 /winsup/cygwin/hookapi.cc | |
parent | 4c28f4392a52852d34acd04cc698047bc21375ea (diff) |
* hookapi.cc (hook_or_detect_cygwin): Take additional handle
to a file mapping as parameter. If this handle is not NULL,
create another file mapping for the IAT.
* spawn.cc (av::fixup): Only map the first 64K of an image and
keep the mapping handle to use as argument to hook_or_detect_cygwin.
* winsup.h (hook_or_detect_cygwin): Add mapping handle as default
parameter in declaration.
Diffstat (limited to 'winsup/cygwin/hookapi.cc')
-rw-r--r-- | winsup/cygwin/hookapi.cc | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/winsup/cygwin/hookapi.cc b/winsup/cygwin/hookapi.cc index b82e4b4c5..8137b85d2 100644 --- a/winsup/cygwin/hookapi.cc +++ b/winsup/cygwin/hookapi.cc @@ -10,6 +10,7 @@ details. */ #include "winsup.h" #include <stdlib.h> +#include <sys/param.h> #include "ntdll.h" #include "cygerrno.h" #include "security.h" @@ -226,7 +227,7 @@ out: // 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) +hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys, HANDLE h) { HMODULE hm = fn ? GetModuleHandle (NULL) : (HMODULE) name; PIMAGE_NT_HEADERS pExeNTHdr = PEHeaderFromHModule (hm); @@ -238,15 +239,36 @@ hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys) DWORD importRVA = pExeNTHdr->OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + DWORD importRVASize = pExeNTHdr->OptionalHeader.DataDirectory + [IMAGE_DIRECTORY_ENTRY_IMPORT].Size; if (!importRVA) return false; long delta = fn ? 0 : rvadelta (pExeNTHdr, importRVA); if (delta < 0) return false; + importRVA -= delta; // Convert imports RVA to a usable pointer - PIMAGE_IMPORT_DESCRIPTOR pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, hm, importRVA - delta); + PIMAGE_IMPORT_DESCRIPTOR pdfirst; + char *map = NULL; + DWORD offset = 0; + if (h && importRVA + importRVASize > wincap.allocation_granularity ()) + { + /* 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. */ + offset = rounddown (importRVA, wincap.allocation_granularity ()); + DWORD size = importRVA - offset + importRVASize; + map = (char *) MapViewOfFile (h, FILE_MAP_READ, 0, offset, size); + if (!map) + return false; + pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, map, importRVA - offset); + } + else + pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, hm, importRVA); function_hook fh; fh.origfn = NULL; @@ -256,10 +278,15 @@ hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys) // Iterate through each import descriptor, and redirect if appropriate for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++) { - if (!ascii_strcasematch (rva (PSTR, hm, pd->Name - delta), "cygwin1.dll")) + if (!ascii_strcasematch (rva (PSTR, map ?: (char *) hm, + pd->Name - delta - offset), "cygwin1.dll")) continue; if (!fn) - return (void *) "found it"; // just checking if executable used cygwin1.dll + { + if (map) + UnmapViewOfFile (map); + return (void *) "found it"; // just checking if executable used cygwin1.dll + } i = -1; while (!fh.origfn && (fh.name = makename (name, buf, i, 1))) RedirectIAT (fh, pd, hm); @@ -267,6 +294,9 @@ hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys) break; } + if (map) + UnmapViewOfFile (map); + while (!fh.origfn && (fh.name = makename (name, buf, i, -1))) get_export (fh); |