Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2011-10-25 20:35:58 +0400
committerCorinna Vinschen <corinna@vinschen.de>2011-10-25 20:35:58 +0400
commitbe2280986de5339bca3d648ec0e7538541dcd674 (patch)
treed31ee4917ee5b00f024ce32b89a065c8204f85b6 /winsup/cygwin/hookapi.cc
parent4c28f4392a52852d34acd04cc698047bc21375ea (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.cc38
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);