Сейчас на форуме: asfa, bartolomeo (+7 невидимых) |
![]() |
eXeL@B —› Вопросы новичков —› Исправить код. |
Посл.ответ | Сообщение |
|
Создано: 15 марта 2012 04:00 · Личное сообщение · #1 Доброе время суток. В общем наверно это будет стандартный вопрос, нежели уникальный. Хочу научится патчить программы(crackme). Возможно я даже выразился не так. Мне нужно исправить его(crackme). Удалить некоторые ассемблерные инструкции из кода, чтобы программа при последущем запуске решала ту или иную проблему. Ну это понятно что нужно разбераться в ассемблере чтобы что то удалять из программы. Дабы не нарушить её функционал и работу в общем. А вот как сделать так. Чтобы запуская экзешник(созданный мною) с именем path. Автоматически патчила нужную мне программу? Тобишь изменяла те самые инструкции которые я укажу в ней. Или там вообще надо исправлять hex код? или, или, или.. Я не знаю как. Может вы прольете истину на свет нужной статьей, или словами? Читал что есть некие loader'ы которые изменяют ассемблерные инструкции, распаковывают, снимают ненужные циклы в крекми. Это то что мне надо узнать поподробнее. Спасибо! ![]() |
|
Создано: 15 марта 2012 05:50 · Поправил: -Sanchez- · Личное сообщение · #2 |
|
Создано: 15 марта 2012 07:45 · Поправил: plutos · Личное сообщение · #3 Ну это понятно что нужно разбераться в ассемблере Ну, так начинай разбираться, раз понятно.... За чем дело-то стало? Все лучше, чем пальцем наугад тыкать: "...или, или, или.. Я не знаю как..." Здесь прольют тебе истину на свет, или свет на истину (как тебе больше нравится): http://www.wasm.ru/series.php?sid=17 http://www.cracklab.ru/kid.php http://win32assembly.online.fr/ http://exelab.ru/art/?action=view&id=125 http://www.rsdn.ru/article/baseserv/peloader.xml ----- Give me a HANDLE and I will move the Earth. ![]() |
|
Создано: 15 марта 2012 09:34 · Личное сообщение · #4 http://exelab.ru/art/ ![]() Есть примеры написания патчей и лоадеров ![]() |
|
Создано: 15 марта 2012 13:37 · Личное сообщение · #5 Спасибо большое что поняли меня. Почитаю. И еще вопросик маленький. Задам здесь - дабы не клепать темы. В общем тема вопроса такая. "Применение виртуальных машин" в реверсинге. Кто-что скажет по этому поводу? Какое отличие будет в отладчике если запустить что-либо в виртуальной среде, нежели на реальной машине? Спасибо. ![]() |
|
Создано: 15 марта 2012 14:09 · Личное сообщение · #6 opcodes 99% что с особенностями ВМ вы не столкнетесь на начальных этапах. Так что отличий никаких не будет. ----- старый пень ![]() |
|
Создано: 16 марта 2012 01:17 · Личное сообщение · #7 |
|
Создано: 16 марта 2012 01:32 · Личное сообщение · #8 |
|
Создано: 16 марта 2012 03:17 · Поправил: tempread · Личное сообщение · #9 opcodes пишет: Какое отличие будет в отладчике если запустить что-либо в виртуальной среде, нежели на реальной машине? Есть понятие виртуальной машины как виртуального компьютера(VmWare,VirtualBox),а есть понятие виртуальной машины, как методики защиты от взлома. Первое и второе значение в контексте вопросов "новичка" - совершенно разные вещи, нужно понимать это. А теперь собственно к первоначальному вопросу(предполагая что речь идет о "виртуальном компьютере"). В большинстве случаев разницы никакой не будет,но есть нюансы,например, некоторые защиты специально сопротивляются работе под виртуальной машиной,противодействуя исследованию себя. Обычно в крекми такие защиты не делают(в крекми для новичков точно этого нет). ![]() |
|
Создано: 16 марта 2012 07:37 · Личное сообщение · #10 Нашел в общем, почитал. Представление сложилось такое: создается(берется, etc) виртуальная среда, но ее перепрограммируют чтобы она выполняла совсем другие команды отличные от x86. Тобишь это обычная машина только анализатор машинного кода устроен по другому. И программа должна быть написана специально для этой машины чтобы она могла понять её. Но чаще это делает специальный протектор. В общих чертах верно же? ![]() |
|
Создано: 16 марта 2012 20:07 · Личное сообщение · #11 opcodes В общих чертах это выглядит примерно так. Некто придумывает свой абстрактный язык программирования, со своими синтаксисом и семантикой. Абстрактный потому, что ни одна существующая железка этот язык не понимает. Далее он придумавыет алгоритм, который инструкции с языка ассемблера для x86 (например) преобразует к его абстрактному языку. Т.е. вот есть код на ассемблере: Code:
Для некоего абстрактного языка аналогичный по функционалу код может выглядеть так: Code:
А может, в принципе, выглядеть как угодно. Когда ассемблерный код преобразован в эту лабуду, надо как-то пояснить процессору, как эту лабуду выполнять. Как хранить данные в регистрах, что такое вообще регистры в контексте этого самопального языка программирования и т.д. - всё это надо пояснить процессору. Поэтому помимо преобразованного кода вводится ещё понятие виртуальной машины. Это - именно та абстарктная машина, которая понимает новый самописный язык, подобно тому, как камни х86 понимают асм. Но разница в том, что эта железяка - не железяка, а виртуальная математическая модель. Грубо говоря, она представляет собой транслятор (не компилятор). Конечно, транслируемый код виртульной машины не хранится в виде текста, как в примере выше. Для него тоже задаются мнемоники, как для обычных ассемблерных инструкций (как правило). Это, обычно, делается для того, чтоб меньше места занимало, и реверсить сложнее было. Но если бы завтра какому-то автору захотелось хранить псевдокод в виде такого текста, и он бы заточил код ВМ под это, то это тоже работало бы. Под термином декомпилировать ВМ понимается написание компилятора для траснлятора ВМ и замещение кода ВМ откомпилированным кодом. Ну, это, думаю, непросто понять с первого раза. ----- Stuck to the plan, always think that we would stand up, never ran. ![]() |
|
Создано: 16 марта 2012 21:40 · Поправил: opcodes · Личное сообщение · #12 |
|
Создано: 16 марта 2012 22:11 · Личное сообщение · #13 ARCHANGEL пишет: В общих чертах это выглядит примерно так... Приветствую. Мне вот что-то не совсем понятна разница между интерпретатором (ну, скажем MSCIL-кода, например) и собственно ВМ. Суть, как я понимаю одна - создаем некий язык... хм, хотя тут главное, вероятно, не сам язык, а результат его трансляции в поток байтов. Короче говоря поток байтов, который имеем на выходе транслятора, и который не может корректно выполняться на процессоре (x86 архитектуры, например), реализуя заданный программистом алгоритм. Потом программируем для целевой архитектуры исполняющую среду - т.е. реализуем алгоритм, который преобразует эти байты в корректные машинные инструкции данной архитектуры. Например пишем в буфер преобразованные инструкции и передаем управление на этот буфер. Таким образом - это можно сравнить и с шифрованием/расшифровыванием кода... Вот такая каша у меня в голове. Буду благодарен, если объясните в чем я не прав. ![]() |
|
Создано: 16 марта 2012 22:20 · Личное сообщение · #14 krait, почти так. Правда шифрованием/расшифровыванием кода это назвать нельзя, ибо при последнем ты расшифровываешь и переходишь туда сразу. Т.е. выполняется у тебя на физическом процессоре. А ВМ - это создаётся виртуальный процесс( MSIL - эта вм не имеет процессора, она стековая только) , и код выполняется в виртуальной среде. Физический процессор лишь выполняет код ВМ. т.е. у ВМ есть свои регистры и стек одним словом. ![]() |
|
Создано: 16 марта 2012 22:35 · Личное сообщение · #15 |
|
Создано: 16 марта 2012 22:55 · Поправил: ARCHANGEL · Личное сообщение · #16 krait пишет: Суть, как я понимаю одна - создаем некий язык... хм, хотя тут главное, вероятно, не сам язык, а результат его трансляции в поток байтов Почему же? Допустим, вы анализируете виртуальную машину, исходные тексты которой у вас отсутствуют. Тогда процесс выглядит примерно так: 1. Устанавливается однозначное соответствие между мнемониками и хэндлерами. Его следует найти, ибо ВМ не может быть неконтролируемой, т.е. мы всегда знаем, что после виртуализации ВМ позволяет защищённому кода работать так же, как и без защиты. В случае невозможности найти биективное соотношение, (а такое вполне может быть, например, для х86 существуют мнемоники, которые дизассемблируются одинаково, что позволяет строить то более компактный, то более быстрый код) нужно просто искусствено его задать, выбрав какой-то один хэндлер. 2. Хэндлерам даются имена. В дальнейшем при анализе ВМ это позволит построить подобие дизассемблированных листингов асма, т.е. разбить промежуточное представление на терминалы и нетерминалы. 3. Генерируется промежуточный код. Операция, которая позволяет из мнемоник получить первое представление неизвестного нам языка в более понятной форме. Иногда это (ИМХО ошибочно) называют декомпиляцией. Например, вы выяснили, что 0x98 - эквивалент xor eax,eax + inc eax, тогда промежуточный код для такой мнемоники: R1,R1,XOR,++. Не обманывайтесь - очевидно же, что воссоздать те же имена терминалов вам не удастся, и максимум - ваше промежуточное представление будет напоминать абстрактный язык, который придумал автор ВМ, но не копировать его буква в букву. 4. Необязательный этап - оптимизация. Если вы получили на этом этапе пром. код, то, возможно, захотите его оптимизировать, а, может, и нет. В любом случае, пром.код удобнее оптимизировать, чем мнемоники, и, хотя я нигде не встречал строгого доказательства, мне кажется, что мнемоники нельзя оптимизировать в принципе, в том смысле, что их нельзя оптимизировать так же хорошо. 5. Устранение обфускации. Об этом часто умалчивают, видимо, потому, что далеко не все виртуальные машины так устроены, что этот этап необходим. Я попытаюсь обьяснить, что я имею ввиду. Всем известно понятие Штрих Шеффера, если нет, то !(a & b) - это он. Здесь два нетерминала a и b несут в себе какие-то значения. И одна инструкция абстрактного языка, получая результат этого штриха, распадается на несколько ассемблерных команд. Дальше - больше. Что, если a и b - резульата каких-то вычислительных операций, из которых добрая половина будут мусорными? Поэтому иногда бывает, что лобовое превращение мнемоник языка ВМ в ассемблерные команды - не лучший результат. Также следует подчеркнуть, что иногда оптимизацию и деобфускацию приравнивают, и они очень похожи по своей природе, но различны в том, что деобфускация должна увеличивать понимание кода, способствуя его разбору, а не благоприятно влиять, например, на скорость выполнения. 6. Генерация ассемблерного кода и мнемоник. Если вы получили асм-код, то получите мнемоники, надеюсь, что на данном этапе они будут соответствовать вашим ожиданиям. ----- Stuck to the plan, always think that we would stand up, never ran. ![]() |
|
Создано: 16 марта 2012 23:32 · Поправил: krait · Личное сообщение · #17 ARCHANGEL Суть ВМ вроде как понял, заглянув в Таненбаума, и найдя виденный мною ранее код, который демонстрирует пример ВМ. Хотя у него это называется интерпретатором. По пунктам все понятно, кроме разве что пункта номер 5. Точнее не понятна разница с оптимизацией и деобфускацией в приведенном примере. Суть деобфускации, насколько я понимаю, в том, чтобы понять что делает программа и привести к виду, когда это будет как можно более очевидно и при этом алгоритмически корректно и эквивалентно. В приведенном примере (с кучей мусорных инструкций) - деобфускация и оптимизация идут в ногу. Хотя понятно, что в общем целью обфускации является усложнение анализа кода, а вовсе не его деоптимизация. Спасибо за разъяснение. Если когда-нибудь решу разобраться с анализом ВМ, отправная точка есть. ![]() ![]() |
|
Создано: 17 марта 2012 00:51 · Поправил: neomant · Личное сообщение · #18 krait пишет: Хотя у него это называется интерпретатором. По сути виртуальная машина и является интерпретатором, то есть интерпретирует и выполняет команду за командой. Если нужно интепретировать и выполнить ранее уже выполнявшуюся команду, процесс повторяется. Кто-то интересовался здесь ВМ .Net, так эта не совсем виртуальная машина, так как содержит в себе JIT компилятор, который хоть и не компилирует весь код целиком, но повторной интерпритации или копиляции IL кода уже не происходит. ----- Следуй за белым кроликом ![]() |
![]() |
eXeL@B —› Вопросы новичков —› Исправить код. |