Собственно такой вопрос возник, по технологии шифрования(криптования) dll: Каким образом восстановить работу оригинальной DLL ? Ситуация такая: 1) в EntryPoint при DLL_PROCESS_ATTACH начинается расшифровка DLL 2) непосредственно восстановление DLL делает шелкод 3) шелкод вызывается где-то глубоко внутри кода. И вот получаются такая глюки: [Технология 1]: 1) Если DLL восстанавливать на место (которое занято шифрованной dll), то возврат из EntryPoint расшифрованной dll идет в шелкод, а возврат из шелкода уже идет в некуда (т.к. код уже подменился) 2) Найти адрес возврата в ntdll нереально, потому что если раскручивать фреймы, то неизвестным остаются то, на сколько чистить стек, т.к. каждая функций вызывается с разным числом параметров. К тому же очень сильная привязка к структуре генерации фрейма 3) Даже если както найти точку возврата, то получится что надо будет как-то хитро править структуры системные (список модулей в PEB) [Технология 2]: 1) Если DLL загружать в любое место (благо релоки помогают это сделать), то возврат из EntryPoint расшифрованной dll идет в шелкод, а далее рекурсивно при завершении функций он будут передаваться обратно и тогда всё норм. 2) но тогда придется делать проброс экспорта и события DLL_PROCESS_DETACH, а также некоторые функции не смогут работать так. К томуже из-за проброса экспорта будет светить имя функции. Вообще весь этот проброс будет довольно проблематично выглядеть [Технология 3]: 1) Тоже что и у технологии 2 2) Вместо проброса экспорта и прочих хреней, сразу подставить в PEB новые значения для DLL (ImageBase и EntryPoint) таким образом вроде как сразу отбрасывается необходимость в пробросе экспорта, события DLL_PROCESS_DETACH, а также многие функции будут работать корректно. 3) Но придется сильно привязываться к структуре PEB и списку DLL, если это еще не проблема, то еще неизвестно как отреагирует на это LoadLibrary т.к. по факту DLL загружена по одному адресу (и секция DLL туда же), а по структурам из PEB будут другое место. Вернее сказать неизвестно что вернет LoadLibrary - адрес по которому загрузилась DLL или уже подправленный адрес из PEB. Если бы не была бы обязательна поддержка экспорта и DLL_PROCESS_DETACH то не было бы проблем. Кто что может посоветовать в данном случае? Какую технологию выбрать? Или может есть еще какой-либо способ?
мне кажется с 3 технологией меньше всего проблем.Опробуй ее.Кстати ,можно поинтересоваться от чего возникла такая необходимость?
а если взять протектор какой нить,или криптор?или ,допустим организовать сравнение контрольной суммы? это если я правильно понял.
Криптеры - дают паливность рано или поздно, а нормальному софту както некрасиво палиться из-за того что там криптер какойто. почти все протекторы снимаются очень легко. Я тоже склоняюсь к третьему варианту, но есть одно но - чтобы получить доступ к списку загруженных модулей, необходимо получить доступ к PEB (а это ассемблер, а при компиляции Си под x64 нельзя использовать ассемблер)
Насколько мне известно, можно, если ассемблерные функции в отдельный файл собрать, скомпилить его в объектник отдельно, а из сишного кода дергать.
http://exelab.ru/faq/Armadillo Нельзя ли подобный подход применить к шифрованию экспортируемых ф-ций длл?
2 __nic есть свои заморочки, нужен именно такой подход как я описал. Скорее всего попробую реализовать третий вариант. судя по исходникам win 2k LoadLibrary ведет далеко во внутрь и вызывает LdrpLoadDll, которая возвращает DllHandle И код там: *DllHandle = (PVOID)LdrDataTableEntry->DllBase; т.е. можно смело говорить что LoadLibrary вернет адрес не тот по которому загружена DLL, а тот который в таблице. (и который собственно говоря можно подменить) 2 GRRRL Power на васме подсказали про Intrinsics. Которые дают возможность без асма юзать многие асм команды. к примеру для x32 mov eax, fs:[0x30] ret равноценно сишной строке __readfsdword(0x30);
Знаю я про Intrinsics, но забыл про них написать Для X64 получение указателя на PEB это __readgsqword( 0x60 )
GRRRL Power, спас меня прям. а то я тыкаюсь в gs:0x30 а там какая-то фигня. думал структура PEB другая )
конечно достаточно завести в проекте один файлик с чистым ассемблером Code: hack.asm include \masm32\include\masm32rt.inc .code dummy proc uses esi mov esi, 100 .while esi invoke Beep, 700, 10 dec esi .endw ret dummy endp end настроить ему custom build step чтобы компилился вместе с сишными файлами Code: Command Line: ml.exe /c /coff /nologo /Zi /Fo $(InputDir)$(IntDir)\$(InputName).obj $(InputName).asm Description: Assembling... Outputs: $(InputDir)$(IntDir)\$(InputName).obj и все инлайн вставки оформлять отдельными процедурами и дергать их из сишных файлов Code: main.cpp extern "C" void __stdcall dummy(); int main() { dummy(); } очень удобно имхо компиляется все за один клик и из встроеннрого дебаггера можно не вылазить для отладки асмокода