* 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>
|
2011-08-16 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
|
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
|
||||||
|
|
|
@ -120,12 +120,27 @@ dlopen (const char *name, int flags)
|
||||||
(HMODULE *) &ret))
|
(HMODULE *) &ret))
|
||||||
{
|
{
|
||||||
/* Windows 2000 is missing the GetModuleHandleEx call, so we
|
/* Windows 2000 is missing the GetModuleHandleEx call, so we
|
||||||
just use a trick. Call LoadLibrary 10 times more if the
|
use a non-documented way to set the DLL to "don't free".
|
||||||
RTLD_NODELETE flag has been specified. That makes it
|
This is how it works: Fetch the Windows Loader data from
|
||||||
unlikely (but not impossible) that dlclose will actually
|
the PEB. Iterate backwards through the list of loaded
|
||||||
free the library. */
|
DLLs and compare the DllBase address with the address
|
||||||
for (int i = 0; i < 10; ++i)
|
returned by LoadLibrary. If they are equal we found the
|
||||||
LoadLibraryW (path);
|
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 a new allocation, figure out what kind it is
|
||||||
if (newbase && !last_pass && mb.State != MEM_FREE)
|
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_dev = 0;
|
||||||
st.st_ino = 0;
|
st.st_ino = 0;
|
||||||
if ((mb.Type & (MEM_MAPPED | MEM_IMAGE))
|
if ((mb.Type & (MEM_MAPPED | MEM_IMAGE))
|
||||||
&& NT_SUCCESS (NtQueryVirtualMemory (proc, cur.abase,
|
&& NT_SUCCESS (status = NtQueryVirtualMemory (proc, cur.abase,
|
||||||
MemorySectionName,
|
MemorySectionName,
|
||||||
msi, 65536, NULL)))
|
msi, 65536, &ret_len)))
|
||||||
{
|
{
|
||||||
PWCHAR dosname =
|
PWCHAR dosname =
|
||||||
drive_maps.fixup_if_match (msi->SectionFileName.Buffer);
|
drive_maps.fixup_if_match (msi->SectionFileName.Buffer);
|
||||||
|
|
|
@ -579,6 +579,34 @@ typedef struct _KERNEL_USER_TIMES
|
||||||
LARGE_INTEGER UserTime;
|
LARGE_INTEGER UserTime;
|
||||||
} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES;
|
} 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
|
typedef struct _RTL_USER_PROCESS_PARAMETERS
|
||||||
{
|
{
|
||||||
ULONG AllocationSize;
|
ULONG AllocationSize;
|
||||||
|
@ -616,7 +644,7 @@ typedef struct _PEB
|
||||||
BYTE Reserved1[2];
|
BYTE Reserved1[2];
|
||||||
BYTE BeingDebugged;
|
BYTE BeingDebugged;
|
||||||
BYTE Reserved2[9];
|
BYTE Reserved2[9];
|
||||||
PVOID LoaderData;
|
PPEB_LDR_DATA Ldr;
|
||||||
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
|
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
|
||||||
BYTE Reserved3[4];
|
BYTE Reserved3[4];
|
||||||
PVOID ProcessHeap;
|
PVOID ProcessHeap;
|
||||||
|
|
Loading…
Reference in New Issue