* Makefile.in (DLL_OFILES): Add hookapi.o. Eliminate some cruft.
* cygheap.h (cygheap_types): Add new enum: HEAP_1_HOOK. (hook_chain): New struct. (init_cygheap::hooks): Define new element. * cygheap.cc (cygheap_fixup_in_child): Zero hook chain on exec. * dcrt0.cc (dll_crt0_1): Call ld_preload just before calling main function. * external.cc (cygwin_internal): Implement CW_HOOK. * fork.cc (fork_child): Call fixup_hooks_after_fork. * init.cc (cygwin_hmodule): Reinstate after a long absence. * include/sys/cygwin.h: Define CW_HOOK. * hookapi.cc: New file. * select.cc (start_thread_socket): Add debugging output. * fhandler_disk_file.cc (fhandler_disk_file::fchmod): gcc 4.x accommodation. * fhandler_socket.cc (fhandler_socket::connect): Make sure that err is initialized.
This commit is contained in:
parent
7e3fd32b1c
commit
b1d9a0bd41
|
@ -1,3 +1,25 @@
|
||||||
|
2005-03-22 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
|
* Makefile.in (DLL_OFILES): Add hookapi.o. Eliminate some cruft.
|
||||||
|
* cygheap.h (cygheap_types): Add new enum: HEAP_1_HOOK.
|
||||||
|
(hook_chain): New struct.
|
||||||
|
(init_cygheap::hooks): Define new element.
|
||||||
|
* cygheap.cc (cygheap_fixup_in_child): Zero hook chain on exec.
|
||||||
|
* dcrt0.cc (dll_crt0_1): Call ld_preload just before calling main function.
|
||||||
|
* external.cc (cygwin_internal): Implement CW_HOOK.
|
||||||
|
* fork.cc (fork_child): Call fixup_hooks_after_fork.
|
||||||
|
* init.cc (cygwin_hmodule): Reinstate after a long absence.
|
||||||
|
* include/sys/cygwin.h: Define CW_HOOK.
|
||||||
|
* hookapi.cc: New file.
|
||||||
|
|
||||||
|
* select.cc (start_thread_socket): Add debugging output.
|
||||||
|
|
||||||
|
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): gcc 4.x
|
||||||
|
accommodation.
|
||||||
|
|
||||||
|
* fhandler_socket.cc (fhandler_socket::connect): Make sure that err is
|
||||||
|
initialized.
|
||||||
|
|
||||||
2005-03-22 Corinna Vinschen <corinna@vinschen.de>
|
2005-03-22 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* cygwin.din (__ctype_ptr): Export.
|
* cygwin.din (__ctype_ptr): Export.
|
||||||
|
|
|
@ -117,7 +117,7 @@ MALLOC_OFILES=@MALLOC_OFILES@
|
||||||
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libadvapi32.a
|
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libadvapi32.a
|
||||||
|
|
||||||
MT_SAFE_OBJECTS:=
|
MT_SAFE_OBJECTS:=
|
||||||
# Please maintain this list in sorted order, with maximum files per 80 col line
|
# Please maintain this list in sorted order, with maximum files per 85 col line
|
||||||
#
|
#
|
||||||
DLL_OFILES:=assert.o autoload.o bsdlib.o cxx.o cygheap.o cygthread.o cygtls.o \
|
DLL_OFILES:=assert.o autoload.o bsdlib.o cxx.o cygheap.o cygthread.o cygtls.o \
|
||||||
dcrt0.o debug.o delqueue.o devices.o dir.o dlfcn.o dll_init.o dtable.o \
|
dcrt0.o debug.o delqueue.o devices.o dir.o dlfcn.o dll_init.o dtable.o \
|
||||||
|
@ -127,12 +127,12 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o cxx.o cygheap.o cygthread.o cygtls.o \
|
||||||
fhandler_nodevice.o fhandler_proc.o fhandler_process.o \
|
fhandler_nodevice.o fhandler_proc.o fhandler_process.o \
|
||||||
fhandler_random.o fhandler_raw.o fhandler_registry.o fhandler_serial.o \
|
fhandler_random.o fhandler_raw.o fhandler_registry.o fhandler_serial.o \
|
||||||
fhandler_socket.o fhandler_tape.o fhandler_termios.o \
|
fhandler_socket.o fhandler_tape.o fhandler_termios.o \
|
||||||
fhandler_tty.o fhandler_virtual.o fhandler_windows.o \
|
fhandler_tty.o fhandler_virtual.o fhandler_windows.o fhandler_zero.o \
|
||||||
fhandler_zero.o flock.o fnmatch.o fork.o getopt.o glob.o grp.o heap.o \
|
flock.o fnmatch.o fork.o getopt.o glob.o grp.o heap.o hookapi.o \
|
||||||
init.o ioctl.o ipc.o iruserok.o localtime.o malloc_wrapper.o miscfuncs.o \
|
init.o ioctl.o ipc.o iruserok.o localtime.o malloc_wrapper.o miscfuncs.o \
|
||||||
mmap.o msg.o net.o netdb.o ntea.o passwd.o path.o pinfo.o pipe.o \
|
mmap.o msg.o net.o netdb.o ntea.o passwd.o path.o pinfo.o pipe.o \
|
||||||
poll.o pthread.o regcomp.o regerror.o regexec.o regfree.o registry.o \
|
poll.o pthread.o regcomp.o regerror.o regexec.o regfree.o \
|
||||||
resource.o scandir.o sched.o sec_acl.o sec_helper.o security.o \
|
registry.o resource.o scandir.o sched.o sec_acl.o sec_helper.o security.o \
|
||||||
select.o sem.o shared.o shm.o sigfe.o signal.o sigproc.o smallprint.o \
|
select.o sem.o shared.o shm.o sigfe.o signal.o sigproc.o smallprint.o \
|
||||||
spawn.o strace.o strsep.o strsig.o sync.o syscalls.o sysconf.o \
|
spawn.o strace.o strsep.o strsig.o sync.o syscalls.o sysconf.o \
|
||||||
syslog.o termios.o thread.o timer.o times.o tty.o uinfo.o uname.o \
|
syslog.o termios.o thread.o timer.o times.o tty.o uinfo.o uname.o \
|
||||||
|
@ -254,6 +254,7 @@ grp_CFLAGS:=-fomit-frame-pointer
|
||||||
malloc_CFLAGS:=-fomit-frame-pointer
|
malloc_CFLAGS:=-fomit-frame-pointer
|
||||||
malloc_wrapper_CFLAGS:=-fomit-frame-pointer
|
malloc_wrapper_CFLAGS:=-fomit-frame-pointer
|
||||||
miscfuncs_CFLAGS:=-fomit-frame-pointer
|
miscfuncs_CFLAGS:=-fomit-frame-pointer
|
||||||
|
net_CFLAGS:=-fomit-frame-pointer
|
||||||
passwd_CFLAGS:=-fomit-frame-pointer
|
passwd_CFLAGS:=-fomit-frame-pointer
|
||||||
regcomp_CFLAGS=-fomit-frame-pointer
|
regcomp_CFLAGS=-fomit-frame-pointer
|
||||||
regerror_CFLAGS=-fomit-frame-pointer
|
regerror_CFLAGS=-fomit-frame-pointer
|
||||||
|
@ -267,7 +268,7 @@ uinfo_CFLAGS:=-fomit-frame-pointer
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: all force dll_ofiles install all_target install_target all_host install_host \
|
.PHONY: all force dll_ofiles install all_target install_target all_host install_host \
|
||||||
install install-libs install-headers -lgcc
|
install install-libs install-headers
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.SUFFIXES: .c .cc .def .a .o .d .s
|
.SUFFIXES: .c .cc .def .a .o .d .s
|
||||||
|
@ -434,11 +435,6 @@ winver_stamp: mkvers.sh include/cygwin/version.h winver.rc $(DLL_OFILES)
|
||||||
$(COMPILE_CXX) -o version.o version.cc && \
|
$(COMPILE_CXX) -o version.o version.cc && \
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
-lgcc:
|
|
||||||
:
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
Makefile: cygwin.din
|
Makefile: cygwin.din
|
||||||
|
|
||||||
$(DEF_FILE): gendef cygwin.din $(srcdir)/tlsoffsets.h
|
$(DEF_FILE): gendef cygwin.din $(srcdir)/tlsoffsets.h
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "child_info.h"
|
#include "child_info.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "shared_info.h"
|
|
||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
|
|
||||||
init_cygheap NO_COPY *cygheap;
|
init_cygheap NO_COPY *cygheap;
|
||||||
|
@ -185,6 +184,7 @@ cygheap_fixup_in_child (bool execed)
|
||||||
|
|
||||||
if (execed)
|
if (execed)
|
||||||
{
|
{
|
||||||
|
cygheap->hooks.next = NULL;
|
||||||
cygheap->user_heap.base = NULL; /* We can allocate the heap anywhere */
|
cygheap->user_heap.base = NULL; /* We can allocate the heap anywhere */
|
||||||
/* Walk the allocated memory chain looking for orphaned memory from
|
/* Walk the allocated memory chain looking for orphaned memory from
|
||||||
previous execs */
|
previous execs */
|
||||||
|
|
|
@ -21,6 +21,7 @@ enum cygheap_types
|
||||||
HEAP_ARCHETYPES,
|
HEAP_ARCHETYPES,
|
||||||
HEAP_TLS,
|
HEAP_TLS,
|
||||||
HEAP_1_START,
|
HEAP_1_START,
|
||||||
|
HEAP_1_HOOK,
|
||||||
HEAP_1_STR,
|
HEAP_1_STR,
|
||||||
HEAP_1_ARGV,
|
HEAP_1_ARGV,
|
||||||
HEAP_1_BUF,
|
HEAP_1_BUF,
|
||||||
|
@ -262,6 +263,13 @@ struct user_heap_info
|
||||||
unsigned chunk;
|
unsigned chunk;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct hook_chain
|
||||||
|
{
|
||||||
|
void **loc;
|
||||||
|
const void *func;
|
||||||
|
struct hook_chain *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct init_cygheap
|
struct init_cygheap
|
||||||
{
|
{
|
||||||
_cmalloc_entry *chain;
|
_cmalloc_entry *chain;
|
||||||
|
@ -291,6 +299,7 @@ struct init_cygheap
|
||||||
int open_fhs;
|
int open_fhs;
|
||||||
pid_t pid; /* my pid */
|
pid_t pid; /* my pid */
|
||||||
HANDLE pid_handle; /* handle for my pid */
|
HANDLE pid_handle; /* handle for my pid */
|
||||||
|
hook_chain hooks;
|
||||||
void close_ctty ();
|
void close_ctty ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,8 @@ details. */
|
||||||
|
|
||||||
#define PREMAIN_LEN (sizeof (user_data->premain) / sizeof (user_data->premain[0]))
|
#define PREMAIN_LEN (sizeof (user_data->premain) / sizeof (user_data->premain[0]))
|
||||||
|
|
||||||
|
void ld_preload ();
|
||||||
|
|
||||||
HANDLE NO_COPY hMainProc = (HANDLE) -1;
|
HANDLE NO_COPY hMainProc = (HANDLE) -1;
|
||||||
HANDLE NO_COPY hMainThread;
|
HANDLE NO_COPY hMainThread;
|
||||||
|
|
||||||
|
@ -857,6 +859,7 @@ dll_crt0_1 (char *)
|
||||||
do this for noncygwin case since the signal thread is blocked due to
|
do this for noncygwin case since the signal thread is blocked due to
|
||||||
LoadLibrary serialization. */
|
LoadLibrary serialization. */
|
||||||
wait_for_sigthread ();
|
wait_for_sigthread ();
|
||||||
|
ld_preload ();
|
||||||
if (user_data->main)
|
if (user_data->main)
|
||||||
exit (user_data->main (__argc, __argv, *user_data->envptr));
|
exit (user_data->main (__argc, __argv, *user_data->envptr));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ details. */
|
||||||
#include "pwdgrp.h"
|
#include "pwdgrp.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
|
|
||||||
|
void *hook_cygwin (const char *, const void *);
|
||||||
|
|
||||||
static external_pinfo *
|
static external_pinfo *
|
||||||
fillout_pinfo (pid_t pid, int winpid)
|
fillout_pinfo (pid_t pid, int winpid)
|
||||||
{
|
{
|
||||||
|
@ -298,6 +300,12 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
||||||
}
|
}
|
||||||
return p.binmode ();
|
return p.binmode ();
|
||||||
}
|
}
|
||||||
|
case CW_HOOK:
|
||||||
|
{
|
||||||
|
const char *name = va_arg (arg, const char *);
|
||||||
|
const void *hookfn = va_arg (arg, const void *);
|
||||||
|
return (unsigned long) hook_cygwin (name, hookfn);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return (DWORD) -1;
|
return (DWORD) -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -429,9 +429,9 @@ fhandler_disk_file::fchmod (mode_t mode)
|
||||||
|
|
||||||
/* if the mode we want has any write bits set, we can't be read only. */
|
/* if the mode we want has any write bits set, we can't be read only. */
|
||||||
if (mode & (S_IWUSR | S_IWGRP | S_IWOTH))
|
if (mode & (S_IWUSR | S_IWGRP | S_IWOTH))
|
||||||
(DWORD) pc &= ~FILE_ATTRIBUTE_READONLY;
|
pc &= (DWORD) ~FILE_ATTRIBUTE_READONLY;
|
||||||
else
|
else
|
||||||
(DWORD) pc |= FILE_ATTRIBUTE_READONLY;
|
pc |= (DWORD) FILE_ATTRIBUTE_READONLY;
|
||||||
|
|
||||||
if (!SetFileAttributes (pc, pc))
|
if (!SetFileAttributes (pc, pc))
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
|
|
|
@ -698,7 +698,9 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
|
||||||
|
|
||||||
res = ::connect (get_socket (), (sockaddr *) &sin, namelen);
|
res = ::connect (get_socket (), (sockaddr *) &sin, namelen);
|
||||||
|
|
||||||
if (res)
|
if (!res)
|
||||||
|
err = 0;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
err = WSAGetLastError ();
|
err = WSAGetLastError ();
|
||||||
/* Special handling for connect to return the correct error code
|
/* Special handling for connect to return the correct error code
|
||||||
|
|
|
@ -154,6 +154,7 @@ sync_with_parent (const char *s, bool hang_self)
|
||||||
static int __stdcall
|
static int __stdcall
|
||||||
fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
|
fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
|
||||||
{
|
{
|
||||||
|
extern void fixup_hooks_after_fork ();
|
||||||
extern void fixup_timers_after_fork ();
|
extern void fixup_timers_after_fork ();
|
||||||
debug_printf ("child is running. pid %d, ppid %d, stack here %p",
|
debug_printf ("child is running. pid %d, ppid %d, stack here %p",
|
||||||
myself->pid, myself->ppid, __builtin_frame_address (0));
|
myself->pid, myself->ppid, __builtin_frame_address (0));
|
||||||
|
@ -232,6 +233,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
|
||||||
|
|
||||||
pthread::atforkchild ();
|
pthread::atforkchild ();
|
||||||
fixup_timers_after_fork ();
|
fixup_timers_after_fork ();
|
||||||
|
fixup_hooks_after_fork ();
|
||||||
cygbench ("fork-child");
|
cygbench ("fork-child");
|
||||||
cygwin_finished_initializing = true;
|
cygwin_finished_initializing = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
#include "winsup.h"
|
||||||
|
#include "cygerrno.h"
|
||||||
|
#include "security.h"
|
||||||
|
#include "path.h"
|
||||||
|
#include "fhandler.h"
|
||||||
|
#include "dtable.h"
|
||||||
|
#include "cygheap.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <imagehlp.h>
|
||||||
|
#include <alloca.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)
|
||||||
|
{
|
||||||
|
PIMAGE_NT_HEADERS pNTHeader = NULL;
|
||||||
|
|
||||||
|
if (PIMAGE_DOS_HEADER(hModule) ->e_magic != IMAGE_DOS_SIGNATURE)
|
||||||
|
/* nothing */;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pNTHeader = PIMAGE_NT_HEADERS (PBYTE (hModule)
|
||||||
|
+ PIMAGE_DOS_HEADER (hModule) ->e_lfanew);
|
||||||
|
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
|
||||||
|
pNTHeader = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pNTHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
putmem (PIMAGE_THUNK_DATA pi, const void *hookfn)
|
||||||
|
{
|
||||||
|
|
||||||
|
DWORD flOldProtect, flNewProtect, flDontCare;
|
||||||
|
MEMORY_BASIC_INFORMATION mbi;
|
||||||
|
|
||||||
|
/* Get the current protection attributes */
|
||||||
|
VirtualQuery (pi, &mbi, sizeof (mbi));
|
||||||
|
|
||||||
|
/* Remove ReadOnly and ExecuteRead attributes, add on ReadWrite flag */
|
||||||
|
flNewProtect = mbi.Protect;
|
||||||
|
flNewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ);
|
||||||
|
flNewProtect |= PAGE_READWRITE;
|
||||||
|
|
||||||
|
if (!VirtualProtect (pi, sizeof (PVOID), flNewProtect, &flOldProtect) )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
void *origfn = (void *) pi->u1.Function;
|
||||||
|
pi->u1.Function = (DWORD) hookfn;
|
||||||
|
|
||||||
|
(void) VirtualProtect (pi, sizeof (PVOID), flOldProtect, &flDontCare);
|
||||||
|
return origfn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Builds stubs for and redirects the IAT for one DLL (pImportDesc) */
|
||||||
|
|
||||||
|
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 (HEAP_1_HOOK, sizeof (hook_chain));
|
||||||
|
hc->next->loc = (void **) pi;
|
||||||
|
hc->next->func = fh.hookfn;
|
||||||
|
hc->next->next = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
get_export (function_hook& fh)
|
||||||
|
{
|
||||||
|
extern HMODULE cygwin_hmodule;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top level routine to find the EXE's imports, and redirect them
|
||||||
|
void *
|
||||||
|
hook_cygwin (const char *name, const void *fn)
|
||||||
|
{
|
||||||
|
HMODULE hm = GetModuleHandle (NULL);
|
||||||
|
PIMAGE_NT_HEADERS pExeNTHdr = PEHeaderFromHModule (hm);
|
||||||
|
|
||||||
|
if (!pExeNTHdr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DWORD importRVA = pExeNTHdr->OptionalHeader.DataDirectory
|
||||||
|
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
||||||
|
if (!importRVA)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Convert imports RVA to a usable pointer
|
||||||
|
PIMAGE_IMPORT_DESCRIPTOR pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, hm, importRVA);
|
||||||
|
|
||||||
|
function_hook fh;
|
||||||
|
fh.origfn = NULL;
|
||||||
|
fh.hookfn = fn;
|
||||||
|
char *buf = (char *) alloca (strlen (name) + strlen ("64") + sizeof ("_"));
|
||||||
|
int i = -1;
|
||||||
|
while (!fh.origfn && (fh.name = makename (name, buf, i, 1)))
|
||||||
|
{
|
||||||
|
// Iterate through each import descriptor, and redirect if appropriate
|
||||||
|
for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++)
|
||||||
|
{
|
||||||
|
PSTR modname = rva (PSTR, hm, pd->Name);
|
||||||
|
if (strcasematch (modname, "cygwin1.dll"))
|
||||||
|
RedirectIAT (fh, pd, hm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (!LoadLibrary (lib))
|
||||||
|
{
|
||||||
|
__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);
|
||||||
|
}
|
|
@ -49,6 +49,7 @@ struct __cygwin_perfile
|
||||||
|
|
||||||
/* External interface stuff */
|
/* External interface stuff */
|
||||||
|
|
||||||
|
/* Always add at the bottom. Do not add new values in the middle. */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CW_LOCK_PINFO,
|
CW_LOCK_PINFO,
|
||||||
|
@ -78,7 +79,8 @@ typedef enum
|
||||||
CW_GET_SHMLBA,
|
CW_GET_SHMLBA,
|
||||||
CW_GET_UID_FROM_SID,
|
CW_GET_UID_FROM_SID,
|
||||||
CW_GET_GID_FROM_SID,
|
CW_GET_GID_FROM_SID,
|
||||||
CW_GET_BINMODE
|
CW_GET_BINMODE,
|
||||||
|
CW_HOOK
|
||||||
} cygwin_getinfo_types;
|
} cygwin_getinfo_types;
|
||||||
|
|
||||||
#define CW_NEXTPID 0x80000000 /* or with pid to get next one */
|
#define CW_NEXTPID 0x80000000 /* or with pid to get next one */
|
||||||
|
|
|
@ -108,6 +108,8 @@ respawn_wow64_process ()
|
||||||
|
|
||||||
extern void __stdcall dll_crt0_0 ();
|
extern void __stdcall dll_crt0_0 ();
|
||||||
|
|
||||||
|
HMODULE NO_COPY cygwin_hmodule;
|
||||||
|
|
||||||
extern "C" int WINAPI
|
extern "C" int WINAPI
|
||||||
dll_entry (HANDLE h, DWORD reason, void *static_load)
|
dll_entry (HANDLE h, DWORD reason, void *static_load)
|
||||||
{
|
{
|
||||||
|
@ -116,6 +118,7 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
|
||||||
switch (reason)
|
switch (reason)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
|
cygwin_hmodule = (HMODULE) h;
|
||||||
/* Is the stack at an unusual high address? Check if we're running on
|
/* Is the stack at an unusual high address? Check if we're running on
|
||||||
a 64 bit machine. If so, respawn. */
|
a 64 bit machine. If so, respawn. */
|
||||||
if (&is_64bit_machine >= (PBOOL) 0x400000
|
if (&is_64bit_machine >= (PBOOL) 0x400000
|
||||||
|
|
|
@ -1394,6 +1394,7 @@ start_thread_socket (select_record *me, select_stuff *stuff)
|
||||||
SetHandleInformation ((HANDLE) si->exitsock, HANDLE_FLAG_INHERIT, 0);
|
SetHandleInformation ((HANDLE) si->exitsock, HANDLE_FLAG_INHERIT, 0);
|
||||||
/* else
|
/* else
|
||||||
too bad? */
|
too bad? */
|
||||||
|
select_printf ("opened new socket %p", _my_tls.locals.exitsock);
|
||||||
}
|
}
|
||||||
|
|
||||||
select_printf ("exitsock %p", si->exitsock);
|
select_printf ("exitsock %p", si->exitsock);
|
||||||
|
|
Loading…
Reference in New Issue