[PATCH 01/10] ntdll: Fixup imports after CREATE_PROCESS_DEBUG_EVENT.
Henri Verbeet
hverbeet at codeweavers.com
Mon Mar 15 15:07:22 CDT 2010
---
dlls/kernel32/tests/debugger.c | 98 +++++++++++++++++++++++++++++++++++++++-
dlls/ntdll/loader.c | 7 ++-
2 files changed, 101 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/debugger.c b/dlls/kernel32/tests/debugger.c
index 057b977..f9b3889 100644
--- a/dlls/kernel32/tests/debugger.c
+++ b/dlls/kernel32/tests/debugger.c
@@ -555,8 +555,10 @@ static void doChild(int argc, char **argv)
static void test_debug_loop(int argc, char **argv)
{
const char *arguments = " debugger child ";
+ IMAGE_DATA_DIRECTORY import_dir = {0};
struct child_blackbox blackbox;
char blackbox_file[MAX_PATH];
+ const char *base = NULL;
PROCESS_INFORMATION pi;
STARTUPINFOA si;
BOOL debug;
@@ -597,13 +599,107 @@ static void test_debug_loop(int argc, char **argv)
ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
if (!ret) break;
- if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break;
+ switch (ev.dwDebugEventCode)
+ {
+ case CREATE_PROCESS_DEBUG_EVENT:
+ {
+ IMAGE_THUNK_DATA *imports, *thunks;
+ IMAGE_IMPORT_DESCRIPTOR *desc;
+ IMAGE_DOS_HEADER dos;
+ IMAGE_NT_HEADERS nt;
+ unsigned int i, j;
+ char *data;
+
+ base = ev.u.CreateProcessInfo.lpBaseOfImage;
+
+ ret = ReadProcessMemory(pi.hProcess, base, &dos, sizeof(dos), NULL);
+ ok(ret, "ReadProcessMemory failed, last error %#x.\n", GetLastError());
+ ok(dos.e_magic == IMAGE_DOS_SIGNATURE, "Wrong DOS signature %#x.\n", dos.e_magic);
+
+ ret = ReadProcessMemory(pi.hProcess, base + dos.e_lfanew, &nt, sizeof(nt), NULL);
+ ok(ret, "ReadProcessMemory failed, last error %#x.\n", GetLastError());
+ ok(nt.Signature == IMAGE_NT_SIGNATURE, "Wrong NT signature %#x.\n", nt.Signature);
+
+ import_dir = nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
+
+ data = HeapAlloc(GetProcessHeap(), 0, import_dir.Size);
+ ret = ReadProcessMemory(pi.hProcess, base + import_dir.VirtualAddress, data, import_dir.Size, NULL);
+ ok(ret, "ReadProcessMemory failed, last error %#x.\n", GetLastError());
+ desc = (IMAGE_IMPORT_DESCRIPTOR *)data;
+
+ i = 0;
+ while (desc[i].Name && desc[i].FirstThunk)
+ {
+ thunks = (IMAGE_THUNK_DATA *)(data + (desc[i].FirstThunk - import_dir.VirtualAddress));
+ imports = (IMAGE_THUNK_DATA *)(data + (U(desc[i]).OriginalFirstThunk - import_dir.VirtualAddress));
+
+ j = 0;
+ while (imports[j].u1.Ordinal)
+ {
+ ok(!thunks[j].u1.Function || thunks[j].u1.Function == imports[j].u1.Function,
+ "desc %u, import %u is already resolved, %#x -> %#x.\n",
+ i, j, imports[j].u1.Function, thunks[j].u1.Function);
+ ++j;
+ }
+ ++i;
+ }
+
+ HeapFree(GetProcessHeap(), 0, data);
+ break;
+ }
+
+ case EXCEPTION_DEBUG_EVENT:
+ {
+ IMAGE_THUNK_DATA *imports, *thunks;
+ IMAGE_IMPORT_DESCRIPTOR *desc;
+ unsigned int i, j;
+ char *data;
+
+ if (ev.u.Exception.ExceptionRecord.ExceptionCode != EXCEPTION_BREAKPOINT)
+ {
+ ok(0, "Received unexpected exception %#x.\n", ev.u.Exception.ExceptionRecord.ExceptionCode);
+ break;
+ }
+
+ data = HeapAlloc(GetProcessHeap(), 0, import_dir.Size);
+ ret = ReadProcessMemory(pi.hProcess, base + import_dir.VirtualAddress, data, import_dir.Size, NULL);
+ ok(ret, "ReadProcessMemory failed, last error %#x.\n", GetLastError());
+ desc = (IMAGE_IMPORT_DESCRIPTOR *)data;
+
+ i = 0;
+ while (desc[i].Name && desc[i].FirstThunk)
+ {
+ thunks = (IMAGE_THUNK_DATA *)(data + (desc[i].FirstThunk - import_dir.VirtualAddress));
+ imports = (IMAGE_THUNK_DATA *)(data + (U(desc[i]).OriginalFirstThunk - import_dir.VirtualAddress));
+
+ j = 0;
+ while (imports[j].u1.Ordinal)
+ {
+ ok(thunks[j].u1.Function && thunks[j].u1.Function != imports[j].u1.Function,
+ "desc %u, import %u isn't resolved yet, %#x -> %#x.\n",
+ i, j, imports[j].u1.Function, thunks[j].u1.Function);
+ ++j;
+ }
+ ++i;
+ }
+
+ HeapFree(GetProcessHeap(), 0, data);
+ break;
+ }
+
+ case EXIT_PROCESS_DEBUG_EVENT:
+ goto done;
+
+ default:
+ break;
+ }
ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
if (!ret) break;
}
+done:
ret = CloseHandle(pi.hThread);
ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
ret = CloseHandle(pi.hProcess);
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 1723f18..fbdda00 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -2533,10 +2533,14 @@ PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
*/
static NTSTATUS attach_process_dlls( void *wm )
{
+ LPCWSTR load_path;
NTSTATUS status;
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
+ load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
+ if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) return status;
+
RtlEnterCriticalSection( &loader_section );
if ((status = process_attach( wm, (LPVOID)1 )) != STATUS_SUCCESS)
{
@@ -2622,7 +2626,6 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2,
static const WCHAR globalflagW[] = {'G','l','o','b','a','l','F','l','a','g',0};
NTSTATUS status;
WINE_MODREF *wm;
- LPCWSTR load_path;
PEB *peb = NtCurrentTeb()->Peb;
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
@@ -2652,8 +2655,6 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2,
if ((status = server_init_process_done()) != STATUS_SUCCESS) goto error;
actctx_init();
- load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
- if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) goto error;
if ((status = alloc_process_tls()) != STATUS_SUCCESS) goto error;
if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto error;
heap_set_debug_flags( GetProcessHeap() );
--
1.6.4.4
More information about the wine-patches
mailing list