Запускаю .ехе из памяти, примерно как тут http://www.wasm.ru/article.php?article=memfile, после чего не грузятся ресурсы.. Восстанавливаю все секции, настраиваю импорт и передаю управление на точку входа.. нужно ли еще что-то поправить, для корректного запуска? SizeOfImage в _LDR_DATA_TABLE_ENTRY, например?
holod Загрузка вручную морально устарела. Это плохие способы, приводящие к проблемам совместимости, ибо загрузка выполняется не системным загрузчиком, таким образом многие нюансы не учитываются или весьма трудно решаются. Следует использовать вызов нэйтивного загрузчика с эмуляцией файлов/секций и пр.
Expert, пе_хидер копируется полностью от оригинального файла.. Где его нужно восстановить? Clerk, есть пример?
holod Есть, воспользуйтесь поиском(не помню линк на архив). Это надстройка для загрузки длл, для экзе нужно немного поправить. Почему не грузятся, какие ошибки возвращает лодер ? Можите использовать логгер для выявления причин.
Clerk если мне надо будет определить то что грузится модуль, я поставлю бряк на системный загрузчик в случае с самодельным загрузчиком это не сработает
Семпл http://indy-vx.narod.ru/Temp/Res.zip В длл .wav в виде ресурса и функа, которая проигрывает из памяти звук. Экзешник грузит из памяти длл, вызывает её, та находит ресурс и проигрывает его.
Clerk, спасибо, но с .dll у меня тоже проблем не возникает. Вот файл - внутри калькулятор, как массив, выделяю память в старших адресах (выше ImageBase+SizeOfImage загружаемого файла), копирую туда лоадер и тело калькулятора, потом освобождаю необходимый регион для него, копирую заголовок, секции, настраиваю импорт и передаю управление на точку входа. В итоге точно не грузятся ресурсы ERROR_RESOURCE_DATA_NOT_FOUND (00000714) и возможно есть еще какие-то баги. Кто-нибудь может подсказать что еще необходимо настроить для корректного запуска .ехе? file: http://slil.ru/29176830
holod А вы пути настроили ? Системный лодер ничего про ваш модуль не знает, соответственно никакие апи с ним работать не могут. Если например приложение вызывает GetModuleHandle("calc.exe") вход не будет найден(calc юзает на сколько помню, теже траблы когдато были ) в базе данных, просто потому что его нет. Хотябы пофиксили базу в PEB.ImageBaseAddress, а то юзается вместо calc ваш модуль. У меня в сурсе ведь даже макро есть: Code (Text): ; + ; Поправка базы для GetModuleHandle(0). ; LDR_FIXUP_PEB macro DllHandle assume fs:nothing mov ecx,fs:[TEB.Peb] mov eax,DllHandle lock xchg PEB.ImageBaseAddress[ecx],eax endm Вобщем вам нужно всё настраивать, всё то что делает загрузчик системный. А вы просто промапили образ и настроили фиксапы.
Clerk Спасибо, фикс ImageBase заставил калькулятор работать как надо Теперь остаётся странная проблема с функциями gdi. После запуска лоадером тестового файла не корректно отрабатывает функция LoadBitmap. Было написано тестовое приложение, которое грузит битмапы и рисует их на форме, так вот запускаемый файл некоторые вызовы LoadBitmap отрабатывает правильно, а некоторые - нет! Стал сравнивать нормальный запуск программы с запуском лоадером дебажа недра LoadBitmap - выяснил, что неправильно отрабатывает функция GDI32!NtGdiSetDIBitsToDeviceInternal, которая является переходником я ядро. Стэк вызовов при этом такой: GDI32!SetDIBitsToDevice+0x5e7 GDI32!SetDIBits+0xd8 USER32!BitmapFromDIB+0x1ea USER32!ConvertDIBBitmap+0x10f USER32!ObjectFromDIBResource+0x88 USER32!LoadBmp+0x4c3 USER32!LoadBitmapA+0x46 Вопрос: что еще нужно настроить для стабильной работы этой функции? Тестовое приложение + оно же под лоадером: http://slil.ru/29225202
holod Это безнадёжно. Вы что не читаете что я написал ? Про модуль никто ничего не знает. Про него не знает загрузчик, для него он не существует. Ну выполняется поиск ресурсов в loader.exe, ясно что их там нет: В памяти модуль должен быть и описатели его, единственная разница что его нет на диске. Вот и настраивайте всё, описатели в лдр и прочие ссылки. Если хотите модуль скрыть, то придётся использовать продвинутые техники эмуляции/захвата на подобие IDP. Думаю вам до этого далеко и не нужно.
holod Итак о чём это я.. Значит юзает ваш модуль свой описатель. Ваш это модуль или целевой, кторый должен думать что он ваш безразницы. Короче обращается он к загрузчику, передав псевдохэндл(базу загрузки) модуля. Вы должны это изменить таким образом, дабы адресовался ваш модуль. Разумеется это не касается имён. Допустим выполняется вызов из целевого модуля для поиска ресурсов в нём. База загрузки может быть определена искодя из имени модуля, вызовом апи через передачу в них опциональных параметров(GetModuleHandle(NULL)), либо куда страшнее для вас - задана как константа, либо констнанта для которой определён фиксап. Таким образом вам нужно подменять данные для стандартных апи экспортируемых загрузчиком. Для этого нужно их захватить и подменять данные. Как вы это сделаете зависит от умения пользоваться поиском. Удачи.
holod, в статье концепт и идея. те кому надо было - доработале, переработале. вообще инде правильно говорит - юзайте загрузчик системы, это и проще и надежней
Flasher Возникает как видим. Просто модуль получает базу загрузки обращаясь к загрузчику, о чём уже много раз сказано. А возвращается база исходного модуля, который выполняет загрузку из памяти другого модуля. Тоесть мы вызываем LdrpSearchResourceSection_U(к этой функции сводятсся все функции работы с ресурсами) передав в неё базу загрузки не свою, а чужую. Разумеется обращение будет выполняться не к тому модулю. Если модуль скрыт, тоесть база его нигде не определена(в LDR_DATA_TABLE_ENTRY например), а необходимо перенаправлять обращения от одного модуля к другому логично сграбить RtlpImageNtHeader(опорная функция для работы с модулями), например изменив смещение в хидере таким образом, дабы ссылка опциональный заголовок бала инвалидной. Тогда можно отслеживать все обращения к целевому модулю. Это в теории, могут возникнуть некоторые проблемы.
Вот пример работы лоадера, выдрал из тела античита UCP. Внутри лоадера файл который вызывает FindResource и LoadResource и вроди как успешно Сам лоадер основан на технике Freeman'a, но не юзается api для выделения памяти под загрузчик, вместо этого изначально высчитываются адреса загрузок, и создаётся дополнительная секция под это дело Внутри исходника более подробно расписано формула подсчёта.