|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Мар 26, 2004 15:50:49 · Поправил: MarsRover Проблема: при обработке LOAD_DLL_DEBUG_EVENT нужно получить имя dll. WinXP SP1 1) можно через DEBUG_EVENT.u.LoadDll.lpImageName и ReadProcessMemory(). Но указатель по адресу lpImageName очень часто NULL (я заметил, что он NULL когда dll подгружается через LoadLibrary(), а не из таблицы импорта). 2) Можно через PSAPI и DEBUG_EVENT.u.LoadDll.lpBaseOfDll (GetModuleFileNameEx), но этот способ не работает наоборот, когда через таблицу импорта грузится. (видать в момент обработки LOAD_DLL_DEBUG_EVENT модуль еще не занесен в список, т.к. EnumProcessModules() его не видит). 3) Можно через DEBUG_EVENT.u.LoadDll.hFile, указанным Dr. Golova способом. [url=http://msdn.microsoft.com/library/default.asp?url=/library/en-u s/fileio/base/obtaining_a_file_name_from_a_file_handle.asp][/url]) Но судя по описанию LOAD_DLL_DEBUG_INFO hFile может тоже быть NULL. Вопрос: Неужели нет универсального надежного способа получить имя файла DLL при обработке LOAD_DLL_DEBUG_EVENT? Сейчас использую все 3, пока какой-либо не даст результата. 3-й оказался самый надежный. 1 и 2 оказались взаимоисключающими (тоесть если работает 1 то не работает 2, и наоборот). P.S. В принципе, я не встречал чтобы DEBUG_EVENT.u.LoadDll.hFile был NULL. Бывает такое реально? В MSDN сказано, что бывает. P.P.S. Может EnumerateLoadedModules() из dbghelp.dll поможет? Хотя она скорее всего работает так-же как и EnumProcessModules(). |
|
|
Дата: Мар 26, 2004 16:47:58 · Поправил: MarsRover почитал Debugging Applications by John Robbins. В главе WDBG: A Real Debugger есть описание этой проблемы. Решает он её не очень хорошо (для меня), он ставит задачу определения имени dll в очередь и определяет её имя когда PSAPI начнет работать, в фоновом режиме. А если мне нужно бряк на EP dll конкретной (имя файла известно), как быть? Вижу только один выход - ставить HWBP на EP каждой подгружаемой dll и потом уже узнавать её имя через PSAPI. Есть еще идеи? |
|
|
Дата: Мар 26, 2004 17:36:43 Проблема решилась для NT-систем. LOAD_DLL_DEBUG_EVENT.u.LoadDll.lpBaseOfDll всегда не NULL. Вызываем для него GetMappedFileName(), затем преобразуем из строки с именами девайсов в строку с буквой диска. а вот для 95 и иже с ними не ясно, не на чем поэксперементировать. |
|
|
Дата: Мар 27, 2004 11:24:06 · Поправил: Peshuha Самое прикольное посмотреть как определяет имя dll MSVC60. :)))) Никаких PSAPI !!! Там идет попытка исп сначала PSAPI, а потом просматривается (похоже) OptionalHeader и вытаскивается имя а затем путь по SearchPath !!! в NT Я делал так :ZwQueryObject. работает железобетонно !: // m_ZwQueryObject - адрес NTDLL.ZwQueryObject CString CPSAPI::GetFileName(HANDLE hFile) { char b[1024]; WCHAR wName[MAX_PATH+10]; DWORD Size = sizeof(wName); ULONG br; ASSERT(!m_ZwQueryObject(hFile, 1, &b, sizeof(b), &br)); ASSERT(br < Size); LPWSTR p = ((POBJECT_NAME_INFORMATION)b)->Name.Buffer; // Последовательно просматриваем имена устройств for(int i = 0; i < m_nDisks; i++) { int devlen = wcslen(m_lpdd[i].Device); if(::CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, m_lpdd[i].Device, devlen, p, devlen) == CSTR_EQUAL) { // Заменяем swprintf(wName, L"%s%s", m_lpdd[i].Disk, p + devlen); return wName; } } ASSERT(0); return ""; } |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.080 |