выгрузить длл

Тема в разделе "WASM.WIN32", создана пользователем Velheart, 7 мар 2012.

  1. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    527
    Есть длл, грузится через appinit_dlls, после проверок нужно из дллмэйна инициировать ее выгрузку. Но есть ограничения:

    1. Нельзя создавать новый поток из DllMain
    2. Нельзя возвращать FALSE из DllMain

    Есть идеи, что еще можно сделать? В идеале, вызывая только ntdll-апи из DllMain.
     
  2. Lunar_

    Lunar_ New Member

    Публикаций:
    0
    Регистрация:
    3 май 2011
    Сообщения:
    53
    Выполнить код выгрузки в другом потоке, перехватив что-то/перезаписав где-то ? Сделать из DllMain джамп в FreeLibrary, предварительно изменив стек так, чтобы управление из FreeLibrary вернулось туда, откуда была вызвана DllMain() ?
     
  3. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    527
    На момент вызова дллмэйна для библиотек из appinit_dlls еще нету других потоков + они вообще не всегда есть, а нужно универсально. Там с аппинит все хитрожопо сильно, особенно с дотнет-приложениями. С джампом и стеком - сильно геморно, нужно и х64 решение, там нужно бэктрэйсить вызов тада LdrLoadDll в недры user32, в общем из пушки по воробьям стрелять, если надежно реализовывать.
     
  4. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Velheart
    DisableThreadLibraryCalls
    После чего вроде как можно создовать поток в DllMain.

    DllMain()
    {
    // by Reason
    DisableThreadLibraryCalls ( hModule );
    CreateThread();
    }
     
  5. Lunar_

    Lunar_ New Member

    Публикаций:
    0
    Регистрация:
    3 май 2011
    Сообщения:
    53
    Дык первое условие задачи - нельзя создавать поток. Кстати, в общем случае, поток создавать на самом деле можно, просто он запускается не сразу.

    Ну засплайсь что-то, что запустится при любом раскладе. Поставь сплайс/бряк на entry point приложения, которое подгружает DLL (я так понял, через импорт? или какая-то сложная конструкция? если да - надо понимать). Помню, была у меня аналогичная задача с подменой "setupapi.dll" (все помнят, наверное). Её надо было подгрузить, поставить сплайс на ЕП и выгрузить, а с ЕП уже работать. Как-то так.

    Не очень понял. (нужно x64 решение) и (там нужно бектрэйсить) - это как-то связано ? Если да, то почему именно на 64 нужно бэк-трейсить ? И зачем вообще бэк-трейсить и что такое бэк-трейсить в данном случае ?

    Охотно верится, но ты уж детали расскажи - что там с дотнет-приложенияим, почему с ними проблема ?
    А то разве что гадать теперь.
     
  6. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Lunar_
    А не заметил :)

    В каком сейчас будет хранится Ldr*** список и прочие данные ?

    Если не создовать новый тред , то придется выполнить бактрейс , думаю дальше ясно...
     
  7. Lunar_

    Lunar_ New Member

    Публикаций:
    0
    Регистрация:
    3 май 2011
    Сообщения:
    53
    Какие ещё бек-трейсы, коля, кто все эти люди ?!

    Код (Text):
    1. #include <windows.h>
    2.  
    3. // linker: /entry:Entry
    4.  
    5. void some_payload()
    6. {
    7.   MessageBox(HWND_DESKTOP, TEXT("We are demonstrating that everything is kinda good with a stack frame here"), TEXT("Information"), MB_ICONINFORMATION);
    8. }
    9.  
    10. void __declspec(naked) Entry()
    11. {
    12.   some_payload();
    13.   __asm
    14.   {
    15.     push [esp]
    16.     push [esp+8]
    17.     push dword ptr [RegEnumKeyA] // any function that can process 4 random args without exceptions and return any value except FALSE (!0)
    18.     // RegEnumKeyA is useful in this case because if we'll call it with a bad args it returns LSTATUS error code in eax (not zero if error)
    19.     // and make ntdll caller of DllMain() to guess that DllMain() has succeeded. Also, RegEnumKeyA doesn't crash/corrupt/etc. if we pass malformed/random arguments.
    20.     // Try any other function that meets this two conditions. I've come up with regenumkey first.
    21.     jmp dword ptr [FreeLibrary]
    22.   }
    23. }
     
  8. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    527
    Там во-первых нельзя в некоторых дотнет приложениях возвращать фолс, потому что тогда фэйлит инициализация гди, я сейчас уже всех подробностей не помню, но точно помню что из-за фэйла гди-инита крэшилось приложение или не отображались ресурсы.И помню, что проблема возникала где-то в районе LdrpInitializeProcess, олли не мог даж продебажить, потому как юзал высокоуровневый слой дебагапи который создавал для ремоут-брэйкина поток, в котором все и происходило =( но как бы это не суть + В кернел32 в этот момент еще не все крит секции проиничены, поэтому даже что-то совсем невинное типа креэйтхип крэшит процесс иногда. + 100% помню, что была система, на которой createthread из dllmain длл которая через appinit грузилась в какой-то процесс типа юзеринит или еще чето такое на старте системы со 100% воспроизводимостью. Сейчас системы этой уже нет, но остались воспоминания =) Вообще проблема оч старая, просто опять про нее напомнили, поэтому всех подробностей тупо не помню.

    Да, думаю идея с бряком на еп мэйн модуля должна прокатить, сенкс.
     
  9. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    527
    Lunar_
    Есть подозрение, что этот код тоже может скрэшить и чегонить поломать, хотя вроде как ни странно, нормально отрабатывает. Но все равно имхо стремновато в коммерческом по такое юзать =)
     
  10. Lunar_

    Lunar_ New Member

    Публикаций:
    0
    Регистрация:
    3 май 2011
    Сообщения:
    53
    Ну ок, замени RegEnumKeyA на пару инструкий, делающих RET 0x10, которые записаны в НЕ-хип (в шаред-структуру, етц.), вероятность падения всего остального уже зависит от того, что будет внутри FreeLibrary, если её запустить на этапе, когда kernel32 ещё абонент не абонент. Но это, вроде, как и требовалось ? Если даже так нельзя, вариант остается один, он определяется чисто логически до любых возможных опытов: перехватить управление на EP главного образа процесса (ЕХЕ-шник, т.е.) и оттуда начать выгрузку. перехват можно поставить и куда-то в другое место, не суть. Более надежных и стабильных вариантов заведомо нет.

    Если ты о моём примере - там есть коммент, возвращается TRUE, стек не повреждается, всё как надо.
     
  11. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    527
    Ага, я вот про это и говорил. В общем буду хукать еп и там анлоадить, с этим точно все должно быть ок
     
  12. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Lunar_
    Бактрейс выполняется из LdrDllLoad. и все норма работает.
     
  13. Malfoy

    Malfoy New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2012
    Сообщения:
    698
    Velheart
    1. Вы не правы.
    2. Вы правы.

    Lunar_
    Ну признавайтесь, что вы там вынюхали, выпили или вкололи ?
     
  14. Lunar_

    Lunar_ New Member

    Публикаций:
    0
    Регистрация:
    3 май 2011
    Сообщения:
    53
    Что конкретно не понравилось в предложенном варианте ?