Имя вызываемой DLL (LOAD_DLL_DEBUG_INFO) дебажим

Тема в разделе "WASM.WIN32", создана пользователем swan, 16 фев 2009.

  1. swan

    swan New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2008
    Сообщения:
    29
    Буду краток
    Дебажим, ловим LOAD_DLL_DEBUG_EVENT, хотим имя вызываемой DLL

    Прошу практической помощи... кусок с проги
    ; -------------------------------------------------------------------------------------------------
    .elseif DBEvent.dwDebugEventCode==LOAD_DLL_DEBUG_EVENT ; если поймали эвент
    call write_clock ; залогил время эвента
    invoke WriteFile,hfile2,addr loaddll,15,addr number,0 ; залогил что за эвент

    ; ТУТ хочу залогить имя вызываемой DLL ! помогите плиз... ее выщемить...


    .elseif DBEvent.dwDebugEventCode==UNLOAD_DLL_DEBUG_EVENT ; это типа дальше...
    ; -------------------------------------------------------------------------------------------------
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    DBEvent.LoadDll.lpImageName
     
  3. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    n0name
    У меня возвращается в этом поле какойто мусор: (TEB + 0x14). База правильно возвращается. XPSP2.
     
  4. swan

    swan New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2008
    Сообщения:
    29
    Вот ты что хотел этим сказать...? Пример плиз - у кого то это получалось ?

    LOAD_DLL_DEBUG_EVENT. В структуре DEBUG_EVENT, в этом случае будет заполнена структура LOAD_DLL_DEBUG_INFO.

    typedef struct _LOAD_DLL_DEBUG_INFO {
    HANDLE hFile;
    LPVOID lpBaseOfDll;
    DWORD dwDebugInfoFileOffset;
    DWORD nDebugInfoSize;
    LPVOID lpImageName;
    WORD fUnicode;
    } LOAD_DLL_DEBUG_INFO, *LPLOAD_DLL_DEBUG_INFO;

    Значение lpImageName указывает на указатель, который, в свое время, указывает на имя загружаемой DLL. Естественно это имя находится в адресном пространстве исследуемого процесса. Используя функцию ReadProcessMemory(), можно узнать это имя. Если значение fUnicode равно TRUE, то строка, находящееся по адресу полученного из поля lpImageName, является двухбайтной.

    указатель на это самое имя! Но не тут-то было... MSDN говорит, что этот член структуры — "strictly optional", и на практике это подтверждается — во всех случаях, что я встречал, этот указатель есть круглый ноль... или же указатель на ноль — но только не на имя DLL :dntknw:

    народ пишет :
    XXX>Вопрос: как имея указанную выше информацию (структуру LOAD_DLL_DEBUG_INFO) узнать имя DLL? Думаю, это возможно, ведь реальные отладчики как-то ведь это делают! Может, зная хэндл можно как-то выудить имя файла?

    h_t.t.p://rsdn.ru/Forum/message/53663.flat.aspx подробнее... можно почитать....
     
  5. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Clerk
    А почему ты решил, что это мусор - это указатель на указатель в соответствии с мсдн:
    Т.е. читаем дворд по адресу TEB + 0x14 и получаем указатель на юникод-строку = короткое имя dll
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    swan
    Странно, у меня все норм.показывает. Вообще-то за показ имен отвечает NTGlobalFlg FLG_SHOW_LDR_SNAPS - может он у тебя в реестре выключен или может ты PEB.BeingDebugged раньше времени сбрасываешь ;)
     
  7. swan

    swan New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2008
    Сообщения:
    29
    Плиз примерчик... если возможно masm32
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    leo
    Ну да всё верно, не там посмотрел. Там указатель находится на TEB.StaticUnicodeBuffer, в нём имя.
    Впрочем в сурцах есть:
    swan
    http://wasm.ru/pub/1/files/tut30.zip
    Добавь тока событие загрузки.
     
  9. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    А может открыть файл из структуры DEBUG_EVENT:
    Вроде как должен быть файлом загружаемого модуля.
     
  10. swan

    swan New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2008
    Сообщения:
    29
    Отличный примерчик Илезрона для подсчета выполненных команд при трассировке !!!

    Мне бы имя DLL ... )))
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Первый ntdll.dll
    Кстати я бы заюзол MemorySectionName для получения полного имени модуля, но это в NT-формате, так как проецирует ядро ntdll, обойти посылку сообщения не получится, но в остальных случаях возможно что будет считано не то что там на самом деле должно быть.
     
  12. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    лео опередил.

    не подходит lpFileName, извлекай из hFile - NtQueryObject(),
     
  13. swan

    swan New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2008
    Сообщения:
    29
    неужели никто не пробовал ?!
     
  14. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    swan
    Чего не пробовал ? Ты мой пост #6 мимо уше пропустил ? Под XP SP2 нормально все через lpImageName читается, если не финтить с антидебагом
     
  15. swan

    swan New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2008
    Сообщения:
    29
    так пример скинь плиз...
     
  16. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    А-а, извиняюсь, проверил под XP SP2: названия статически загружаемых dll выводятся в lpImageName, а динамических по LoadLibrary - нет :dntknw:
     
  17. swan

    swan New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2008
    Сообщения:
    29
    Скажите кто то кодил или в отладчиках смотрим ?
     
  18. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Да кодил ес-но, только я такие "замуты" предпочитаю не на асме писать, а на дельфях, от которых тебя наверняка тошнит :)
    В чем проблема-то, если lpImageName != 0 читаешь по этому адресу дворд через ReadProcessMemory, проверяешь - если не 0, то читаешь строку в буфер (имена короткие поэтому достаточно байт эдак 64 с запасом), проверяешь флаг fUnicode - если не 0, то преобразовываешь в анси через WideCharToMultibyte. Или ты сам в асме не силен и нужен пример на блюдечке ;)

    PS: Для динамических dll в XP SP2 lpImageName указывает на "NO_NAME". Но зато если после загрузки ntdll включить в PEB.NtGlobalFlag флаг FLG_SHOW_LDR_SNAPS, то загрузчик по событию OUTPUT_DEBUG_STRING_EVENT будет выдавать много всякой всячины и перед LOAD_DLL_DEBUG_EVENT динамической либы выдаст строку с ее полным именем, типа
    "LDR: Loading (DYNAMIC, NON_REDIRECTED) C:\...\MyDll.dll"
     
  19. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Код (Text):
    1.     si.cb = sizeof(si);
    2.     CreateProcess(0, "test_app.exe", 0, 0, 0, DEBUG_PROCESS, 0, 0, &si, &pi);
    3.     while (1)
    4.     {
    5.         WaitForDebugEvent(&dbg, INFINITE);
    6.         if (dbg.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT)
    7.         {
    8.             if (dbg.u.LoadDll.lpImageName)
    9.             {
    10.                 ReadProcessMemory(pi.hProcess, dbg.u.LoadDll.lpImageName, &addr, 4, &br);
    11.                 ReadProcessMemory(pi.hProcess, addr, s, 260 * 2, &br);
    12.                 printf("DLL loaded: %ws.\n", s);
    13.             } else
    14.                 printf("DLL loaded: UNKNOWN.\n");
    15.         } else
    16.             if (dbg.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
    17.                 break;
    18.         ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, DBG_CONTINUE);
    19.     }
    Как ни странно выводит имена и статически и динамически подгружаемых dll.
     
  20. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Можно из хендла как я писал в #12.
    Код (Text):
    1.        if (dbg.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT)
    2.         {
    3.             NtQueryObject(dbg.u.LoadDll.hFile, ObjectNameInfo, s, 260 * 2, &br);
    4.             printf("DLL loaded: %ws.\n", ((PUNICODE_STRING)s)->Buffer);
    5.         }