· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› LOAD_DLL_DEBUG_EVENT нужно получить имя dll

Посл.отвђт Сообщен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