Предыдущий шаг здесь.
Появилась новая версия библиотеки для работы с PE-файлами (0.1.9). Никакие баги там поправлены не были, был добавлен функционал, который упаковщик не использует, так что ваше дело, перекачивать ее или нет :)
В этом шаге мы запилим нашему упаковщику хороший интерфейс командной строки. Я возьму вариант из старого упаковщика и модифицирую его.
Сперва нам потребуется собранная библиотека Boost. Если вы разбирали предыдущие шаги, то она уже должна у вас быть. Если вы ее еще не собрали, то поясню, как это делается. Например, вы распаковали архив с библиотекой в директорию C:\boost. Заходим в эту директорию и запускаем файл bootstrap.bat. Через какое-то время в той же директории появится файл bjam.exe. Запустим консоль (cmd) и перейдем в директорию C:\boost с помощью команды cd. Наберем команду
1 |
bjam variant=debug link=static threading=multi runtime-link=static |
и подождем, пока соберется debug-вариант со статической линковкой, а затем наберем
1 |
bjam variant=release link=static threading=multi runtime-link=static |
и соберем аналогично release-вариант. Boost собран, и можно переходить к упаковщику (проект simple_pe_packer). В файл main.cpp добавим два include:
1 2 |
#include <boost/program_options.hpp> #include <boost/timer.hpp> |
Первый необходим для реализации интерфейса командной строки, второй мы используем для подсчета времени упаковки файла. Заменим строки
1 2 3 4 5 6 7 8 9 |
//Говорим пользователю, как использовать наш упаковщик //На текущем шаге никаких опций упаковки не будет, просто //необходимо будет запускать упаковщик, передав через командную строку //имя файла, который мы хотим упаковать if(argc != 2) { std::cout << "Usage: simple_pe_packer.exe PE_FILE" << std::endl; return 0; } |
на такие:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
//Чтобы не писать всегда полное имя неймспейса namespace po = boost::program_options; //Таймер будет считать, сколько времени //ушло на упаковку файла boost::timer pack_timer; //Принудительная упаковка - будет упакован даже //потенциально некорректный файл bool force_mode = false; //Перепаковывать ли ресурсы bool repack_resources; //Перепаковывать ли директорию конфигурации загрузки bool rebuild_load_config; //Обрезать ли DOS-заголовок bool strip_dos_headers; //Файловое выравнивание после упаковки unsigned long file_alignment; //Путь к исходному файлу std::string input_file_name; //Путь для упакованного файла std::string output_file_name; //Создаем описание опций po::options_description visible_options("DXPack Packer 1.0\nCommand Line Options"); try { //Создаем список допустимых опций //Добавляем для них дефолтовые значения (не для всех) po::options_description cmdline; //out-file,o - значит, что имя опции "--out-file" //и короткий ее псевдоним "-o" visible_options.add_options() ("out-file,o", po::value<std::string>(&output_file_name), "Output file name") ("file-align,a", po::value<unsigned long>(&file_alignment)->default_value(512), "Packed file alignment") ("strip-dos,s", po::value<bool>(&strip_dos_headers)->default_value(true), "Strip DOS headers") ("repack-res,r", po::value<bool>(&repack_resources)->default_value(true), "Repack resources") ("build-load-config,l", po::value<bool>(&rebuild_load_config)->default_value(true), "Rebuild Load Config directory") ("force,f", "Force packing of possibly incorrect binaries") ; cmdline.add(visible_options); //Скрытая опция - имя файла для упаковки cmdline.add_options() ("image", po::value<std::string>(&input_file_name), "PE image to pack") ; //Безымянная (имя файла для упаковки должно стоять на первой позиции) po::positional_options_description desc_pos; desc_pos.add("image", 1); //Парсим командную строку po::variables_map vm; po::store(po::command_line_parser(argc, argv). options(cmdline).positional(desc_pos).run(), vm); po::notify(vm); //Если не указан путь к исходному файлу if(input_file_name.empty()) throw std::runtime_error("No input file specified"); //Если указан режим принудительной упаковки if(vm.count("force")) { std::cout << "Force mode is active!" << std::endl; force_mode = true; } } catch(const std::exception& e) { //Если что-то пошло не так - выведем описание опций std::cout << e.what() << std::endl << std::endl; std::cout << visible_options << std::endl; system("pause"); return 0; } |
Не буду подробно описывать этот кусок кода, скажу лишь, что здесь мы удобно и просто с помощью библиотеки boost::program_options обрабатываем командную строку нашего упаковщика. Все опции, доступные через командную строку (bool force_mode, bool repack_resources, bool rebuild_load_config, bool strip_dos_headers, unsigned long file_alignmen, std::string input_file_name, std::string output_file_name), я рассовал в исходник упаковщика, и не буду пояснять, что именно изменилось, так как по мелочам поменялись многие части кода. Кроме того, в конце исходника я сделал вывод затраченного на упаковку времени, просчитанного с помощью библиотеки boost::timer. Все изменения вы, как всегда, сможете оценить, скачав полный солюшен упаковщика.
Пожалуй, эту версию упаковщика уже можно назвать законченной. Да, он создает подозрительные импорты и, возможно, имеет еще какие-то недостатки, однако он полностью работоспособен, поддерживает то, чего некоторые другие упаковщики не умеют (например, TLS с коллбэками или перепаковку конфигурации загрузки) и имеет интерфейс командной строки. Поэтому помимо полного исходного кода я выложу и exe-файл упаковщика, вдруг кому-то пригодится. На этом я закрываю цикл статей про написание упаковщика.
Полный солюшен для этого шага: own-packer-step-11
Упаковщик в собранном виде (EXE): DXPack.zip
UPD: версия с исправленной ошибкой здесь
Почитал все, большое спасибо, было интересно.
>имеет еще какие-то не достатки
Слово 'недостатки' пишется вместе.
Да, странная опечатка, и Kaimi не заметил :)
Спасибо за отличный учебный материал.
То что надо, спасибо.
Очень интересный материал, но можно было проще расписать.
Отличный цикл статей, уникальный в своем роде. Это большой труд - не только написать такое, а еще и доступно объяснить.
Пожалуйста сделайте DXPack GUI, многим будет очень удобно))
Не понимаю зачем стока извратов. Следует запилить враппер для нтлдр, далее будет полноценная загрузка из памяти. Прикручиваем декомпрессор и получаем пакер. Добавляем немного антиэмуля, генератора импорта и морфа и получаем криптор.
Кстате автор насколько понимаю не пилил обход NXSEH, тоесть SEH не будет робить, ежели включена DEP.
Вот пример(блокнот), запакованный лзетом http://rghost.ru/45533554
Ну так и запили свой крутой пакер-криптор, и напиши об этом статью, где всё поясняешь, а я почитаю и почерпну для себя что-то новое. Я свой упаковщик проверял на всяких программах типа Notepad++, Firefox, на каких-то бинарниках VMWare, все работало хорошо. С DEP не уверен, надо проверять, но во всех случаях тестирования SEH работал нормально.
Да и код в областях памяти, не помеченных как исполняемые, я не выполняю, насколько помню, так что не должно быть проблем с DEP'ом.
Моё решенье совершенно. Сех у вас не робит - мну уверен(ибо не дорос есчо мой друг до маршрутизаций, хоть они и примитивны).
Статьи - накой они нужны, незачем всякой школоте типо вас знать матчать и засорять сеть всякой поганью.
> все работало хорошо.
Работало оно хорошо сугубо In Vitro. Реально же нтлдр поддерживает огромное число механизмов, которые есно тупым ручным мапом не реализовать. Ваш код унылое говно во всех смыслах, такой и тс, лишь только враппер может рассматриваться как приемлемый.
Да у вас же мания величия. А сех робит, я проверял.
dx
Системе похуй на то что память исполняемая. Она проверяет тип памяти и ежели она не образ, то не раскрутит цепь сех. Вот вы же и представленья про сие не имеете, а вещаете про трушность вашего говна. Не годно.
Ну окей, вот не имею я представления, потому что SEH недокументирован, и вообще я низкоуровневым программированием не занимаюсь, драйверов не писал в жизни. Про трушность я не вещаю, это ты тут вещаешь про то, что твое творение идеально. Я просто написал мануал, как сделать что-то более-менее рабочее. А от тебя никаких деталей либо советов, как сделать лучше, я не вижу, более того, ты в принципе не желаешь их давать. Смысл писать негативные комментарии, чтобы что-либо обосрать, если я все равно не узнаю, как сделать лучше? Или мне просто прийти на ваш форум, отписаться, какое у вас охуенное творение и отсосать ваш огромный хуй, о великий господин задрот?
На вт детекты(https://www.virustotal.com/ru/file/04691dea485d5914eb9c7ecf879efbcbc9a7e0ae7a904e2727ceb922ecec7e15/analysis/1366841978/) из за отсутствия импорта, так что не обращайте вниманья.
Лог анубиса http://anubis.iseclab.org/?action=result&task_id=173f09ee67c5ef9a4a93e2d2e8d56e454&format=html
Кто хочет обсудить, добро http://vx.security-portal.cz/showthread.php?tid=3
dx
> Смысл писать негативные комментарии, чтобы что-либо обосрать, если я все равно не узнаю, как сделать лучше?
Инде не писал есчо негативное.
> А от тебя никаких деталей либо советов, как сделать лучше, я не вижу
Ну собстно вопросов то и небыло. А писать в пустоту мну особо не любитъ.
> Или мне просто прийти на ваш форум, отписаться, какое у вас охуенное творение и отсосать ваш огромный хуй
Не нужно :D
Вот сейчас я специально проверил, работает ли упакованный моим пакером бинарник, использующий SEH и с включенным DEP. Работает, да.
Есть одна мелкая проблема, правда, которую я возможно пофикшу попозже, связанная с реализацией обработки исключений в VC++ и IMAGE_LOAD_CONFIG, но к DEP это отношения не имеет.
Кстати да, почему бы ему не работать, если память, в которой исполняется код - это память образа? Весь код находится в пределах одной исполняемой секции PE-файла.
Вот уже и баг с IMAGE_LOAD_CONFIG поправил, скоро залью и будет вообще всегда работать.
dx
Без семпла это не более чем спам, ваш ответ. Или быть может мне из вас есчо одного бога сделать ?
Давайте семпл, блокнот накрытый вашим лодером. Мы оценим. Но я так полагаю что сего не будет.
Берешь и пакуешь, али рук нет?
http://www.sendspace.com/file/edsu2l
Вот тебе сразу и exe, и dll упакованные, первый грузит вторую, и там и там есть релоки и SEH. Можешь хоть узапускаться под DEP'ом.
dx
Крэшится ваша хуйня http://anubis.iseclab.org/?action=result&task_id=11dabe21e1fb3f07409327808e31944ed&format=html
Мы тут прогнали на варе, выводит мессагу, собстно как и в анубисе. Никаких образов в памяти не обнаружено. Так что пошёл ты нахуй мой обосравшийся юный кулцхэккер!
Конечно крешнется. Потому что в анубис ты загрузил только exe, а он требует еще и dll, которую я заботливо приложил тебе в архив
Кстати, до вызова функции из DLL исполнение прошло отлично, даже эксепшен обработался, который я кидаю.
В общем, братец, если руки у тебя кривые, а самооценка выше некуда, то видимо не судьба.
Сорс экзешника: http://pastebin.com/bRm8MPXT
Сорс DLL: http://pastebin.com/7qThAEgA
dx
Что значит требует, лол. Она из памяти грузится должна. Друг мой походу ты не осознаёшь о чём тут речь идёт :D
А по-моему ты не осознаешь, что делает пример, который я привел. Исходники посмотри, если в дебаггер заглянуть не судьба.
dx
Он не делает сабжевых задач, левые значенья не имеют. Ежели вы мне про сех хотите впарить, то также ваш семпл идёт лесом, ибо у вас дисковый образ(MEM_IMAGE).
Ты слишком уныл, и я не понимаю, чего ты от меня хочешь вообще. Пакер пакует? Пакует. TLS, импорты, экспорты, релокации, конфиг, ресурсы поддерживает? Поддерживает. С SEH при включенном DEP упакованные бинарники работают? Работают. Чего надо-то? В общем, не буду больше тратить личное время на то, чтобы отвечать на твои бессмысленные комменты, иди лучше обсирай разработчиков UPX.
Да он все обсирает) вот отзыв о UPX
http://wasm.ru/forum/viewtopic.php?pid=499677#p499677
"пакер говняный, все говно, но альтернативу не покажу".
Инди такой Инди.
Мну показал, но ты овцеёб паганый малолетний хуй не можешь даже десяток строк сконпилеть. Умственно отсталое мясо!
dx
Дибил ты нахуй какой то, иди обратно на клаб.
Да-да-да, отписаться больше некуда, везде побанили, вот печалька-то. Напомню тебе, что вообще-то это ты приперся в наш с Kaimi блог и пишешь какую-то еботу, так что будь добр сам убраться. Неадекват нашелся.
Indy он же Клерк - известный в узких кругах неадекват, асоциопат и наркоман (декстрометорфан) с форума киндеров wasm.ru. Никакого отношения к индустрии вредоносного ПО он не имеет. Никаких сколько-нибудь серьезных проектов или достижений у него нет. Все его так называемые "джиготели" это полурабочие высеры на 32 битном ассемблере, в основном, не представляющие интереса даже академически. Из сотен мегабайт бреда и срачей, что он там понаписал единственное применение получил раскопанный баг в проводнике (и то есть мнение что без Great ничего бы и не вышло), который используется в PowerLoader'e, ну и "опход" оутпост там же. В данный момент большинство или все из его многочисленных аккаунтов на васме забанены и поскольку у него зависимость - пациент шарахается по различным тематическим сайтам, разводя везде примерно такой же срач как выше. Забаньте это чудо, сэкономите кучу времени. c анти-малваре.
Ну хорошо тупые вы маглы. Раз не хотите сосать мой огромный хуй доставайте свой какой есть пососу я у вас мне вообще похуй я все равно останусь элитой а вы хуесосами!
Насчёт антивирусов, у них у всех есть политика. они не распаковывают для проверки, наложили маску получили что это пакер и будут визжать а возможно увас тама вирус.
Можете попробывать другие извесные упаковщики и протестить на вирусняк.
и ещё момент. если имя секции начать не с "." или "_" и если содержит больше 5 символов то получите оч неожиданные результат от AV сканеров. вот например имя секции напишите "fuck_off" и порадуйтесь
Дык чё за результаты? Ниужели бинарник компилить для этого?
Наконец то стасти стихли :)
И покуда никто более фикалиями не разбрызгивает, попытаюсь подытожить сказанное тут (покуда имею достаточного опыта этих областях).
Дабы не грузить мозг (а это я умею ;) ) я опишу в общих словах без терминологий и тому подобного, ведь сюда редко кто заглятывает из "форумчан wasm.ru" :)
Следовательно буду использовать термин "низкоуровневый аналог функции такой-то", за что сразу прошу знатоков, плз, не пинайте меня за это.
Начну с того, что опишу в общих словах обе идеи загрузки исполняемых модулей:
1. И так, что же нам сказал Indy - "Ребята, а давайте грузить приложение из ОЗУ!" (так звучат слова Indy после "фильтации", да простит он мне это)
2. DX'а уже все давно и так поняли - "А почему бы нам не узнать потроха исполняемых файлов, и заодно получить упаков исполняемых файлов"
Темы в принципе разные, но давайте заглямен на итог этих тем.
После того как мы, не без стараний DX'а, разберемся в формате РЕ, научимся упаковывать, распаковывать, запускать исполняемые файлы е чему мы придем? Конечно же к тому, что мы станем более крутыми, начнем упаковывать наше приложение...
Кстати, о "приложении", думаю все заметили, что я использовал это слово во фразе Indy? Так я имел ввиду, что в отличие от "исполняемых файлов", "приложение" может содержать много всяких ресурсов, среди которых имеются "исполняемые файлы".
Таким образом, наше приложение, состоит из нескольких исполняемых файлов. Которые аккуратненько лежат в папке, где находится наше приложение. При этом каждый файл упакован.
Конечно, если читателя это не беспокоит, то на этом этапе можно закончить.
Но Indy это объстоятельство уже давно побеспокоило и по этому он нам сказал то, что все учуяли ;)
Основная идея Indy лежит в "загрузке исполняемых модулей из памяти", а в его случае возможно будет и не только исполняемых ;). Но остановимся пока только на исполняемых.
Для этого он предлагает использовать так называемый лоадер (или "враппер для нтлдр"), который перехватит некоторые низкоуровневые функции работы с файлами (в основном открытие/закрытие файлов и файлмапинг).
Тут-то и происходит маленькое чудо - один исполняемый файл в несколько метров может оказаться очень даже серьезным и увесистым приложением, содержащий виджеты, зависящий от динамического CRT и ... что то меня понесло. В общем, не требующий более ничего кпоме себя самого.
В отличие от всяких там инсталлеров, ничего не распаковывает во временную папку, не засирает винт итд.
Конечно в обоих вариантах есть свои плюсы и минусы, ведь я написовал общую картинку, причем исключительно в "розовых тонах".
Но вот скажем, отчего же ув. Flisk так нелестно отозвался о предложении Indy, прошу прощения, о его реализации этого предложения - "Все его так называемые "джиготели" это полурабочие высеры на 32 битном ассемблере, в основном, не представляющие интереса даже академически." ?
Да очень просто - его "враппер" _может_ перестать работать с выходом очередного сервиспака или версии Винды. Но чтоб тут меня не закидали козявками, следует отметить, что до сих пор этого не случалось. И тем не менее, такое возможно - ведь Закона Мерфи еще никто не отменял ;)
Я ж в своей работе использую оба этих метода.
Почему? Да всё очень просто - нет смысла упаковывать методом Indy отдельные файлы, особенно если это длл-ки :)
Не слушайте этого ёбанова овоща, я у него отсосал и теперь у него батхёрт из за того что все равно он остался хуесосом. Мои двиг0тели совершенны, а вы все направитесь в биореактор!
Ув.Indy, если Ваше сообщение было направлено мне, то я искренне не хотел Вас обидиеть, или принизить Ваши труды!
Более того, в своих, так сказать "трудах" я использую так же и Ваши идеи, хотя и реализую их исключительно самостоятельно и на собственный лад.
И потому, за Ваши _идеи_ Вам лично от меня респект и уважуха!!!
А что мешает мне быть Indy или BOBAHом и хвалить самого себя?
А что нужно изменить, чтобы добавить еще 1 секцию, а то пишет, что недостаточно места для TLS?
Хотелось бы посмотреть на пример бинарника, для которого выдается такая ошибка
Как исправить оффсетрасположения сигнатуры?
Он был до репака: 00000110, а стал 00000010
Какой именно сигнатуры? Пакер с нуля пересобирает PE-файл по сути, расположения заголовков могут поменяться в том числе.
С этими проблемами вроде разобрался, хорошая библиотека получилась. Спасибо большое. У меня такой вопрос, как можно в реалтайме сломать библиотеку импорта и спрятать оригинальную точку входа?
Библиотека не поддерживает работу с бинарником, загруженным в память, к сожалению (а новая версия библиотеки, в которой я такую возмможность предусмотрел, еще не готова). Поэтому скорее всего придется вручную всё делать.