* 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.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user