* dlfcn.cc (dlopen): Reimplement RTLD_NODELETE for Windows 2000 using
internal datastructures. Explain the code. * ntdll.h (struct _LDR_DATA_TABLE_ENTRY): Define. (struct _PEB_LDR_DATA): Define. (struct _PEB): Change PVOID LoaderData to PPEB_LDR_DATA Ldr. * fhandler_process.cc (format_process_maps): Call NtQueryVirtualMemory with valid return length pointer. Explain why.
This commit is contained in:
parent
9d3b795b47
commit
833db5481f
|
@ -1,3 +1,14 @@
|
|||
2011-08-16 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dlfcn.cc (dlopen): Reimplement RTLD_NODELETE for Windows 2000 using
|
||||
internal datastructures. Explain the code.
|
||||
* ntdll.h (struct _LDR_DATA_TABLE_ENTRY): Define.
|
||||
(struct _PEB_LDR_DATA): Define.
|
||||
(struct _PEB): Change PVOID LoaderData to PPEB_LDR_DATA Ldr.
|
||||
|
||||
* fhandler_process.cc (format_process_maps): Call NtQueryVirtualMemory
|
||||
with valid return length pointer. Explain why.
|
||||
|
||||
2011-08-16 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
|
||||
|
|
|
@ -120,12 +120,27 @@ dlopen (const char *name, int flags)
|
|||
(HMODULE *) &ret))
|
||||
{
|
||||
/* Windows 2000 is missing the GetModuleHandleEx call, so we
|
||||
just use a trick. Call LoadLibrary 10 times more if the
|
||||
RTLD_NODELETE flag has been specified. That makes it
|
||||
unlikely (but not impossible) that dlclose will actually
|
||||
free the library. */
|
||||
for (int i = 0; i < 10; ++i)
|
||||
LoadLibraryW (path);
|
||||
use a non-documented way to set the DLL to "don't free".
|
||||
This is how it works: Fetch the Windows Loader data from
|
||||
the PEB. Iterate backwards through the list of loaded
|
||||
DLLs and compare the DllBase address with the address
|
||||
returned by LoadLibrary. If they are equal we found the
|
||||
right entry. Now set the LoadCount to -1, which is the
|
||||
marker for a DLL which should never be free'd. */
|
||||
PPEB_LDR_DATA ldr = NtCurrentTeb ()->Peb->Ldr;
|
||||
|
||||
for (PLDR_DATA_TABLE_ENTRY entry = (PLDR_DATA_TABLE_ENTRY)
|
||||
ldr->InLoadOrderModuleList.Blink;
|
||||
entry && entry->DllBase;
|
||||
entry = (PLDR_DATA_TABLE_ENTRY)
|
||||
entry->InLoadOrderLinks.Blink)
|
||||
{
|
||||
if (entry->DllBase == ret)
|
||||
{
|
||||
entry->LoadCount = (WORD) -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -960,12 +960,16 @@ format_process_maps (void *data, char *&destbuf)
|
|||
// if a new allocation, figure out what kind it is
|
||||
if (newbase && !last_pass && mb.State != MEM_FREE)
|
||||
{
|
||||
/* If the return length pointer is missing, NtQueryVirtualMemory
|
||||
returns with STATUS_ACCESS_VIOLATION on Windows 2000. */
|
||||
ULONG ret_len = 0;
|
||||
|
||||
st.st_dev = 0;
|
||||
st.st_ino = 0;
|
||||
if ((mb.Type & (MEM_MAPPED | MEM_IMAGE))
|
||||
&& NT_SUCCESS (NtQueryVirtualMemory (proc, cur.abase,
|
||||
&& NT_SUCCESS (status = NtQueryVirtualMemory (proc, cur.abase,
|
||||
MemorySectionName,
|
||||
msi, 65536, NULL)))
|
||||
msi, 65536, &ret_len)))
|
||||
{
|
||||
PWCHAR dosname =
|
||||
drive_maps.fixup_if_match (msi->SectionFileName.Buffer);
|
||||
|
|
|
@ -579,6 +579,34 @@ typedef struct _KERNEL_USER_TIMES
|
|||
LARGE_INTEGER UserTime;
|
||||
} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES;
|
||||
|
||||
typedef struct _LDR_DATA_TABLE_ENTRY
|
||||
{
|
||||
LIST_ENTRY InLoadOrderLinks;
|
||||
LIST_ENTRY InMemoryOrderLinks;
|
||||
LIST_ENTRY InInitializationOrderLinks;
|
||||
PVOID DllBase;
|
||||
PVOID EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STRING FullDllName;
|
||||
UNICODE_STRING BaseDllName;
|
||||
ULONG Flags;
|
||||
WORD LoadCount;
|
||||
/* More follows. Left out since it's just not used. The aforementioned
|
||||
part of the structure is stable from at least NT4 up to Windows 7,
|
||||
including WOW64. */
|
||||
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
|
||||
|
||||
typedef struct _PEB_LDR_DATA
|
||||
{
|
||||
ULONG Length;
|
||||
UCHAR Initialized;
|
||||
PVOID SsHandle;
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
PVOID EntryInProgress;
|
||||
} PEB_LDR_DATA, *PPEB_LDR_DATA;
|
||||
|
||||
typedef struct _RTL_USER_PROCESS_PARAMETERS
|
||||
{
|
||||
ULONG AllocationSize;
|
||||
|
@ -616,7 +644,7 @@ typedef struct _PEB
|
|||
BYTE Reserved1[2];
|
||||
BYTE BeingDebugged;
|
||||
BYTE Reserved2[9];
|
||||
PVOID LoaderData;
|
||||
PPEB_LDR_DATA Ldr;
|
||||
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
|
||||
BYTE Reserved3[4];
|
||||
PVOID ProcessHeap;
|
||||
|
|
Loading…
Reference in New Issue