LoadLibrary внутри DllMain

Тема в разделе "WASM.WIN32", создана пользователем techgl, 31 авг 2005.

  1. techgl

    techgl New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2004
    Сообщения:
    42
    В одной библиотеке встретил вызов LoadLibrary для kernel32 и advapi32 в DllMain, далее она получает адреса некоторых функций, но это не важно. Если библиотеку загружать через LoadLibrary и использовать ее функции, то она работает как надо. Но при попытке прохода в user mode(OllyDbg) отладчике - получаю исключение "Неверный хенлд". Это исключение происходит в DllMain библиотеки при вызове CloseHandle для закрытия хендлов двух перечисленных выше библиотек. При проходе того же кода в kernel mode(SoftIce) отладчике - все нормально, никаких исключений.

    Я прочитал в MSDN что LoadLibrary внутри DllMain безопасен только для kernel32, а для advapi32 уже нет.

    Помогите разобраться с проблемой, необходима работа именно в OllyDbg, да и вообще надо разобраться почему происходит исключение.
     
  2. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    techgl

    CloseHandle какое имеет отношение к DLL? Может лучше использовать FreeLibrary?
     
  3. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    The CloseHandle function closes handles to the following objects:
    Код (Text):
    1. ·  Console input or output
    2. ·  Event file
    3. ·  File mapping
    4. ·  Mutex
    5. ·  Named pipe
    6. ·  Process
    7. ·  Semaphore
    8. ·  Thread
    9. ·  Token (Windows NT only)
    Юзай The FreeLibrary function decrements the reference count of the loaded dynamic-link library (DLL) module. When the reference count reaches zero, the module is unmapped from the address space of the calling process and the handle is no longer valid.
     
  4. techgl

    techgl New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2004
    Сообщения:
    42
    Меня немного не поняли, сам виноват. Данная библиотека уже написана и работает, и исходный код мне не доступен. Мне необходимо с ней работать под отладчиком, причем очень желателен OllyDbg.

    Меня интересует, почему код работоспособен при проходе под SoftIce и при обычном запуске, но вызывает исключение при проходе под user mode отладчиком.
     
  5. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    techgl

    Патч на либу, чтобы не вызывала CloseHandle для "хэндлов" DLL. Мало когда-что от этого в системе нарушится. В идеале пропатчить, чтобы вызывалась FreeLibrary заместо CloseHandle.
     
  6. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Какие проблемы если в OllyDbg добавить в Exceptions\Ignore - Add Last Exception или в .ini прописать?



    [Exceptions]

    Custom[0]=C0000008,C0000008
     
  7. techgl

    techgl New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2004
    Сообщения:
    42
    bogrus

    Добавлял в список, но продолжает ловиться. Видимо его нельзя игнорировать.

    alpet

    А вот старый добрый патч (забивание nop'ов) сработал. А функции FreeLibrary в импорте нет, и заменить на нее CloseHandle не получится.

    Но вопрос почему же при работе не в отладчике все нормально пока остается открытым.
     
  8. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    techgl

    Оно просто ловится тихо. А в импорт таки можно FreeLibrary и добавить.
     
  9. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Код (Text):
    1. ;========================================================
    2. ;           testexe.exe
    3. ;========================================================
    4. entry       $
    5.             invoke  LoadLibrary,testdll
    6.             invoke  ExitProcess,0
    7. ;========================================================
    8. testdll     db      'testdll.dll',0
    9. ;========================================================
    10. ;           testdll.dll
    11. ;========================================================
    12. proc        dll_entry
    13.             invoke  GetModuleHandle,kernel32
    14.             invoke  CloseHandle,eax           ; Exception
    15.             xor     eax,eax
    16.             inc     eax
    17.             retn    0x0c
    18. endp
    19. ;========================================================
    20. kernel32    db      'kernel32.dll',0
    21. ;========================================================
    Там получается если в OllyDbg игнорировать этот Exception в dll_entry, то LoadLibrary возвращает 0 и testdll.dll выгружается, но если проходить как обычно по F7\F8\F9, без Ignore (SHIFT+F7\F8\F9), то все нормально отрабатывает (testdll.dll загружается), я не понимаю - почему ты не можешь пройти это исключение ... что потом происходит? И вообще какого в проге используется CloseHandle для этого?
     
  10. techgl

    techgl New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2004
    Сообщения:
    42
    Если следовать оригиналу то вот так:
    Код (Text):
    1.  
    2. ;========================================================
    3. ;           testdll.dll
    4. ;========================================================
    5. proc        dll_entry
    6.             invoke  LoadLibraryA,kernel32
    7.             invoke  CloseHandle,eax           ; Exception
    8.             xor     eax,eax
    9.             inc     eax
    10.             retn    0x0c
    11. endp
    12. ;========================================================
    13. kernel32    db      'kernel32.dll',0
    14. ;========================================================
    15.  


    Я получаю исключение и если его пропустить по Shift+F8, то будет возврат нуля и ошибка "Неверный дескриптор" (если после LoadLibrary вызвать GetLastError). Библиотека не загрузится, нельзя будет потом использовать GetProcAddress (именно для этого в обсуждаемой библиотеке используется загрузка kernel32 и advapi32).

    Игнорировать же у меня не получилось: я добавил это исключение в список, но отладчик все равно останавливается на нем.

    Попробуй не GetModuleHandle а LoadLibrary.



    Я не знаю для чего так сделали разработчики, но это явно не ляп. Приследовалась какая-то цель.
     
  11. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    1. LoadLibrary выполняется без ошибок, т.ч. kernel32 и advapi32 загружаются, можно использовать их ф-ции

    2. Игнорирование исключения (по SHIFT в отладчике) выгружает testdll.dll и возможно пропадают хендлы загруженых библиотек, из-за чего и не хочет работать

    3. Не игнорирование, а обычный проход (без SHIFT) позволяет загрузить библиотеку







    Убери игнорирование и после того как остановится, просто иди дальше (F7\F8\F9)
     
  12. techgl

    techgl New Member

    Публикаций:
    0
    Регистрация:
    5 авг 2004
    Сообщения:
    42
    А вот что можно видеть в MSDN по теме "Writing the Debugger's Main Loop":
    Код (Text):
    1.  
    2. ...
    3. case LOAD_DLL_DEBUG_EVENT:
    4. // Read the debugging information included in the newly
    5. // loaded DLL. Be sure to close the handle to the loaded DLL with CloseHandle.
    6. break;
    7. ...
    8.  


    Так что программисты не "ошиблись".
     
  13. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Это для хендлов hFile, а не hModule, т.е. отладчик должен вызвать CloseHandle([LOAD_DLL_DEBUG_INFO.hFile]), к чему это делать после LoadLibraryA мне не понятно



    When a CREATE_PROCESS_DEBUG_EVENT occurs, the debugger application receives a handle to the image file of the process being debugged, a handle to the process being debugged, and a handle to the initial thread of the process being debugged in the DEBUG_EVENT structure. The members these handles are returned in are u.CreateProcessInfo.hFile (image file), u.CreateProcessInfo.hProcess (process), and u.CreateProcessInfo.hThread (initial thread). If the system previously reported an EXIT_PROCESS_DEBUG_EVENT debugging event, the system closes the handles to the process and thread when the debugger calls the ContinueDebugEvent function. The debugger should close the handle to the image file by calling the CloseHandle function.



    When a LOAD_DLL_DEBUG_EVENT occurs, the debugger application receives a handle to the loaded DLL in the u.LoadDll.hFile member of the DEBUG_EVENT structure. This handle should be closed by the debugger application by calling the CloseHandle function.
     
  14. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Кстати, исключение "invalid handle" возникает по следующей причине: CloseHandle передает управление в ядро (NtClose), ядро определяет что хэндл не является хэндлом объекта ядра, после чего явно определяет, не подключен ли отладчик, и если не подключен, то просто возвращает ошибку, а если подключен, то бросает исключение. Это относится только к отладчикам 3-кольца (случай либо DebugActiveProcess либо CreateProcess(...DEBUG_PROCESS...)).

    Хэндл DLLки и хэндл объекта ядра - совершенно разные вещи, их видно даже по типу: HMODULE = HINSTANCE для DLL и HANDLE для CloseHandle. Фактически HINSTANCE - указатель на первый быйт DLL, а HANDLE - индекс во внутренней таблице.