Руководство по ollydbg

Введение

В этом туториале я попытаюсь представить вам основы того, как использовать OllyDbg. Олли содержит множество функций и единственный путь по-настоящему освоить их – это практика и еще раз практика. Тут же я изложу вам самые основы, которых достаточно что бы начать. Какие-то вещи, не затронутые здесь, будут описаны позже, поэтому в итоге вы должны получить солидный багаж знаний и умений по использованию Олли.

Я добавил некоторые файлы в этот туториал. Они включают в себя простой бинарный файл, который мы откроем в Олли, справку по Олли, и мою версию этого отладчика с некоторыми косметическими изменениями и новый .ini файл, которым можно заменить дефолтный .ini файл в папке Олли. Все это можно скачать здесь (ссылка).

Открываем приложение

Первый шаг – это загрузка необходимого нам бинарника в Олли. Вы можете мышкой переместить иконку бинарника в окно Олли, либо кликнуть на иконку загрузки и выбрать нужный файл. В данном случае откройте файл “FirstProgram.exe”, который я прикрепил к этому туториалу. Олли сделает необходимый анализ и остановится на точке входа этой программы.

FirstProgram.exe

Первое, что можно заметить это то, что адрес точки входа – 401000, как видно в первом столбце. Это – стандартный адрес для точек входа в исполняемых файлах (по крайней мере если они не подвергались действию пакеров или крипторов). Если вдруг в вашем случае Олли не остановилась на точке входа, попробуйте зайти в меню Appearance и кликните на Debugging Options. Затем откройте вкладку Events и убедитесь, что бы флажок WinMane (if location is kown) был выбран. Затем, перезагрузите приложение. 

Давайте посмотрим снимок памяти, занятой нашей программой. Нажмите на икону Me:

Нажмите на икону Me

Если вы посмотрите на первую колонку, вы увидите, что напротив адреса 401000 указанно: размер 1000, имя “FirstPro” (сокращение от FirstProgram), имя секции .text и она содержит “SFX и Code”. Как мы узнаем позже, исполняемы файлы содержат в себе несколько секций, в которых хранятся различный данные. В секции, которую мы сейчас рассматриваем, указано, что она хранит код. Она иммет размер 1000h (h на конце означает, что это число представлено в шестандцатеричной системе счисления) байтов и начинается по адресу 401000. 

Ниже вы увидите другие секции нашей программы. Там находятся секция .rdata, которая содержит данный и импорт (по адресу 402000), секция .data, которая не содержит ничего (по адресу 403000) и, наконец, секция .rsrc, которая содержит ресурсы (такие как диалоговые окна, изображения, текстовые строки и т.д.). Необходимо понимать, что секции могут иметь любые имена – это зависит от программиста. 

Вы можете удивится тому факту, что секция .data является пустой. На самом деле она не пустая – в ней хранятся значение некоторых переменных, но анализатор Олли не совсем это понял :)  

Выше рассмотренных нами секций находится секция с названием “PE Header”. Это очень важная секция и мы подробнее изучим ее в будущем. На данный момент достаточно знать, что она хранит информацию для операционной системы – сколько место в памяти занимает эта программа, по какому адресу расположены те или иные вещи и т.д. Эта секция находится в начале любого исполняемого файла. 

Если вы посмотрите вниз, мы увидим имена не только нашей программы, но и других файлов. Мы увидим comctl32, imm32, gdi32, kernel32 и т.д. Это DLL файлы (или, как еще говорят – DLL библиотеки), в которых нуждается наша программа для своей работы. DLL файл представляет собой набор функций, которые программа может вызвать. Эти файлы предоставляет операционная система. Также они могут быть разработаны программистом самостоятельно. Они могут содержать такие функции, как отображение диалоговых окон, сравнение строк и т.д. Функции WindowsAPI как раз и предоставляются посредством DLL библиотек. Программист их использует, поскольку иначе ему пришлось бы реализовывать все эти функции самостоятельно. Даже такая простая, казалось бы функция, как отображение окна с сообщением, могла бы содержать в себе сотни строк кода. Поэтому, что бы помочь программистам и облегчить процесс разработки Wndows предоставляет готовые функции. 

Вам может быть любопытно, каким образом эти Dll библиотеки попадают а адресное пространство нашей программы и откуда Windows знает какие именно библиотеки необходимы данному приложению? Такого рода информация хранится в PE заголовке. Когда Windows загружает наш исполняемый фал в память, он считывает его заголовок и находит там имена необходимых DLL библиотек, а также какие функции из этих библиотек будут использоваться в программе. После этого операционная система подгружает в адресное пространство программы необходимые функции, что бы программа могла их вызывать. Если вы хотите узнать, какие именно функции используются в нашей программе, вы можете кликнуть правой кнопкой мыши в окне дизассемблера и выбрать “Search For” -> “All Intermodular Calls”. После этого вы увидите такое окно: 

какие функции используются в нашей программе

Это может показаться удивительным, но список довольно маленький. Обычно в реальных программах используются сотни или даже тысячи различных функций, но поскольку мы сейчас имеем дело с очень простым приложением, оно не нуждается в таком количестве функций. На самом деле, с точки зрения того, насколько проста наша программа, список функций, которые она использует довольно внушительный. Это окно отображает сначала имена Dll библиотек, а затем имена самих функций. Например в строчке “User32.LoadIconA”, User32 – это имя библиотеки, а LoadIconA – название функции. Это функция обычно загружает иконку в левый верхний угол окна приложения. 

Далее, давайте посмотрим все строки, которые используется в программе. Для этого кликните правой кнопкой мыши по окну дизассемблера и выберите “Search For” -> “All Referenced Text Strings: 

строки, которые используется в программе

Это окно показывает все текстовые строки, которые Олли смогла обнаружить в приложении. В большинстве реальных программ их будет намного больше (иногда – в сотни и тысячи раз), если, конечно, они не были запакованы или зашифрованы. В таком случае вы, вероятно, не увидите ни одной из них. Строки чаще всего шифруют, поскольку реверс-инженеры (по крайней мере – новички) сильно полагаются на текстовые строки при анализе того или иного приложения и если эти строки зашифровать – это может значительно усложнить анализ. Представьте, если вы просматриваете строки какой-либо программы и натыкаетесь на такую: “Поздравляем! Вы ввели верный код!”. Если наша цель – взлом программы, опираясь на эту строку мы легко можем выйти на код, проверяющий корректность введенного серийного номера и затем, и затем, изменить его. Если вы дважды кликните на какую-либо текстовую строчку, вас перекинет на инструкцию, которая использует эту строчку. Это очень удобная функция. 

Запуск программы

Если вы посмотрите в левый верхний угол Олли вы увидите желтое окно, на котором написано “Paused”. Это говорит нам о том, что выполнение программы на данный момент приостановлено (на точке входа в данном случае) и вы можете сделать необходимые вам действия. Так давайте что-нибудь сделаем! Нажмите клавишу F9 (либо кликните на “Run”). После этого наша программа начнет выполнение и высветит диалоговое окно. Это окно может отобразится позади окна Олли, так что если вы его вдруг не видите – попробуйте свернуть отладчик. 

Запуск программы

В том окне, где раньше было написано “Paused” теперь написано “Runned”. Это означает, что приложение на данный момент запущено, но запущено внутри Олли, что дает нам возможность взаимодействовать с этой программой. Давайте посмотрим, как это происходит. Если вы случайно закроете окно нашей программы, что бы загрузить ее снова,  – вернитесь к отладчику и нажмите комбинацию клавиш ctrl-F2 (или кликните на кнопку Restart из меню Debug). Так вы снова попадете на точку входа приложения и теперь можете снова его запустить. 

Теперь попробуйте следующее: когда программа запущена, нажмите на кнопу паузы в Олли (или клавишу F2, или кликните Debug-Pause). Это остановит выполнение программы в текущем месте исполнения. Если вы в этот момент обратите внимание на окно программы, вы увидите что оно как бы заморожено (либо оно может вообще не отображаться). Это так, потому что когда программа на паузе – ее окно не обновляется. Теперь нажмите F9 снова и приложение снова станет активным. Если что-то пойдет не так– вы всегда можете перезагрузить приложение, нажав комбинацию клавиш ctrl-F2, либо кликнув на Debug-Restart. И теперь, после перезагрузки, можете запускать программу снова. 

Пошаговое исполнение программы

Когда приложение просто запущено – это, конечно, уже хорошо – но это не дает нам большого количества информации о том, что именно происходит с программой. Для более детального анализа нам может такая функция как пошаговое исполнение. Перезагрузите приложение (нажав комбинацию клавиш ctrl-F2, либо кликнув на Debug-Restart) и вы, как вы наверно уже знаете, остановитесь на точке входа. Теперь нажмите клавишу F8. Вы заметите, что выделение строчки сдвинется вниз. Олли только что выполнила одну строчку кода и остановилась на следующей. Если вы наблюдательны, то вы заметили, что окно стека прокрутилось вниз и теперь имеет новое значение на своей вершине:

Пошаговое исполнение программы

Это случилось, потому что инструкция, которую мы выполняли, “PUSH 0”, поместила новое значение в стек. Это отобразилось в окне стека как “pModule = NULL”. Null – это еще один способ обозначения нуля. Вы могли также заметить, что в окне регистров, регистры ESP и EIP стали отображаться красным цветом: 

регистры ESP и EIP стали отображаться красным цветом

Когда регистр меняет цвет на красный, это означает что его содержимое, в результате выполнения последней инструкции, было изменено. В данном случае, регистр ESP (который указывает на адрес вершины стека) был увеличен на единицу, поскольку мы положили новое значение на вершину стека. Регистр EIP, который указывает на адрес инструкции, которая сейчас будет исполнятся увеличился на 2. Это случилось, потому инструкция по предыдущему адресу (401000) занимала два байта и уже была исполнена. После ее выполнения в регистр, соответственно, попало значение инструкции, которую надо исполнить сейчас (ее адрес – 401002). 

Инструкция, на которой мы сейчас остановились – это Call. Суть этой инструкции в том, что мы временно приостанавливаем выполнение той функции в которой мы сейчас находимся и начинаем исполнять другую функцию. Если проводить аналогию с высокоуровневыми  языками программирования – это как вызов функции внутри другой функции, например: 

int main()
{
int x = 1;
call doSomething();
x = x + 1;
}

В этом коде мы первым делом присвоили переменной x значение 1. После этого вы вызываем функцию doSomething(). Когда эта функция будет выполнена, мы продолжаем выполнение оригинальной функции main() и увеличиваем значение переменной x на единицу. 

Такой же порядок выполнения сохраняется и в ассемблере. Сначала мы поместили ноль на вершину стека, и теперь мы вызываем функцию, в данной случае это функция GetModuleHandleA() из Dll библиотеки Kernel32.dll. 

функция GetModuleHandleA

Теперь, нажмите на клавишу F8 еще раз. Выделение линии сместиться на одну строчку вниз, регистр EIP будет красным и увеличится на 5 (инструкция, которая сейчас была выполнена занимала имела размер 5 байтов) и стек вернулся к своему изначальному виду. Случилось следующее: т.к. мы нажали клавишу F8, что означает “Step-Over” (переступить через), Олли за один раз исполнила весь код внутри функции и затем остановилась на следующей за функцией команде. Внутри этой функции могла происходить что угодно, но мы пропустили ее и не стали вдаваться в детали. Если же мы хотим “шагнуть внутрь” функции, необходимо во-первых перезагрузить программу, потом снова исполнить первую строчку, нажав F8, но когда мы остановились на команде CALL нажать уже не F8, а F7, что бы начать исполнение самой функции, не пропуская ее. Если так сделать после выполнения команды CALL мы затем попадаем сюда: 

шагнуть внутрь

Мы попали сюда, потому что клавиша F7 выполняет команду “Step-IN”, которая означает, что в случае выполнения функции, Олли переходит на первую команду этой функции и там останавливается. В данном случае нас перебросило на другой участок памяти (EIP = 4012d6). В принципе, если мы продолжим пошаговое исполнение кода, мы в итоге вернемся в то место, откуда функция была вызвана, в следующую инструкцию, которая следовала за командой вызова функции (CALL). Но это может занять довольно много времени, так что давайте перезапустим в Олли нашу программу и начнем заново ее пошагово исполнять, без захода во внутренности этой функции (нажимая клавишу F8, а не F7). 

Итак, после перезагрузки, когда мы снова остановлены в точке входа, нажмите клавишу F8 (“Step-Over”) 4 раза и мы в итоге дойдем до данного места: 

Step-Over

Вы заметите 4 команды PUSH подряд. Если вы пошагово их исполните, то увидите как на вершину стека один за другим помещаются 4 новых значения. Думаю, у вас уже начала появляться интуиция относительно того, как работает стек. 

Вам может стать любопытно: почему мы поместили эти четыре значения в стек. Это произошло, потому что эти 4 значения передались функции в качестве аргументов. Сама команда вызова функции расположена по адресу 401021. Что бы лучше это все понять, давайте снова посмотрим на аналогию с кодом на высокоуровневом языке программирования: 

int main() 
{
int x = 1;
int y = 0;
call doSomething( x, y );
x = x + 1;
}

В этом коде мы сначала определяем две переменных: x и y, а затем передаем их как аргументы функции doSomething(). Функция doSomething, вероятно, будет как-то использовать эти переменные в свой работе, и после того как она выполнится управление передастся на код, который следует за этой функцией. Стек – это один из способов передать функции какие-либо переменные: необходимые переменные кладутся на вершину стека, функция вызывается и она уже через стек получает доступ к этим переменным (обычно с помощью команды POP – это команда, обратная PUSH — она снимает значения с вершины стека). 

Стек – не единственный способ передать функции переменные, но часто-встречающийся. Необходимые переменные могут быть также помещены в регистры, и функция через регистры получает доступ к этим переменным. Но в нашем случае, как мы видим, использовался именно стек. Это все станет понятней, когда вы поближе познакомитесь с ассемблером. Я еще немного затрону эту тему в будущем. 

Сейчас, если вы нажмете F8 еще один раз, вы увидите, что на панели статуса Олли высветится “Running” и наша программа отобразить диалоговое окно. Это случилось, потому что мы переступили через выполнение функции, а внутри этой функции и был основной код программы. Внутри этой функции запустился цикл, который ждет каких-то наших действий что бы прерваться, поэтому мы до стх пор не перешли к коду, который находится за вызовом функции. Давайте исправим это. Кликните по окну нашей программе и нажмите на крестик в левом верхнем углу, что бы закрыть ее. После этого Олли перейдет на данную строчку кода: 

После этого Олли перейдет на данную строчку кода

Вы также заметите, что окно программы пропало. Это случилось, потому что где-то внутри функции диалоговое окно было закрыто. Если вы обратите внимание на нижележащий код, вы увидите, что программа сейчас собирается вызвать функцию ExitProcess из библиотеки kernel32.dll. Это функция Windows API, которая закрывает приложение. Получается, мы поймали момент, когда окно программы уже было закрыто, но сама программа еще работала. Если вы сейчас нажмете клавишу F9 (продолжить исполнение), программа завершиться, на панели статуса Олли отобразиться “Terminated” и процесс отладки на этом завершиться.

Брейкпоинты (точки останова)

Давайте попробуем сделать что-нибудь еще. Перезагрузите приложение (ctrl-F2) и дважды кликните левой кнопкой мыши по второй колонке строчки по адресу 401011 (вы должны будете кликнуть по опкоду 6A 0A). Колонка с адресом в этой строчке после этого поменяет цвет на красный: 

Брейкпоинты

То что вы сейчас сделали – это установили точку останова (их еще называют брейкпоинтами или просто бряками) по адресу 401011. Брейкпоинты заставляют Олли останавливаться, когда исполнение дойдет до этого места. Существует несколько типов брейкпоинтов:

Программные брейкпоинты

Программный брейкпоинт заменяет байт по адресу, на который необходимо поставить брейкпоинт на CC, что означает команду int 3. Это является прерыванием, которое говорит операционной системе что отладчик хочет остановиться здесь и с этого момента получить контроль над выполнением кода. В коде программы, который отображает Олли вы не увидите, что байт был заменен на CC, т.к. Олли не отображает это, но она делает эту замену в любом случае. Когда в результате этой замены происходит прерывание Олли вступает в игру и ловит это прерывание, давая нам власть над дальнейшим исполнением программы. Если вы решите продолжить дальнейшее исполнение, то Олли за место CC вернет оригинальное значение измененного байта. 

Что бы поставить программный брейкпоинт, вы можете дважды кликнуть левой кнопкой мыши по колонке с опкодами на определенном адресе, или вы можете выделить мышкой строчку кода, на которую вы хотите установить брейкпоинт, затем кликнуть по ней правой кнопкой мыши и в выпадающем меню выбрать Breakpoints->Toggle (либо нажать клавишу F2). Что бы удалить уже установленный брейпоинт – дважды кликните левой кнокой мыши по колонке с опкодом на строчке, на которой брейкпоинт установлен, либо выделите эту строчку, кликните по ней правой кнопой мыши и выберите Breakpoint->Remove Software Breakpoint (или опять же нажмите клавишу F2). 

Сейчас, когда имеем брейкпоинт, установленный по адресу 401011, а наша программа стоит на точке входа, нажмите F9 (run). Наша программа запуститься и потом остановится на той строчке кода, на которой установлен наш брейкпоинт. 

Я хотел бы также дать один полезный прием. Нажмите на иконку “Br” на тулбаре или выберите View->Breakpoints. Должно открыться окно, которое отображает все брейкпоинты, установленные в программе: 

Программные брейкпоинты

Отсюда вы также можете быстро перейти к месту, в котором установлен брейкпоинт, для этого дважды кликните левой кнопкой мыши по нужному брейкпоинту из списка. Если вы выделите какой-либо брейкпоинт и потом нажмете на клавишу пробела, этот брейкпоинт поменяет свой статус с активного на выключенный и наоборот. Можно также удалить выделенный брекйкпоинт с помощью клавиши DEL. 

Даватй еще попробуем такую вещь: перезагрузите программу и откройте окно со списком брейкпоинтов, выделите брейкпоинт, который мы поставили по адресу 401011 и кликните на клавише пробела. “Active” смениться на “Disabled”. Теперь запустите программу (F9). На этот раз программа запустится без каких-либо остановок, потому что мы отключили установленный ранее брейкпоинт.

Аппаратные брейкпоинты

Аппаратные брейкпоинты используют отладочные регистры в процессоре. В процессоре есть 8 таких регистров: R0-R7. Несмотря на то, что их 8 мы реально можем использовать 4 из них. Они могут быть использованы для прерывания на чтении, записи или исполнении секции памяти. Разница в аппаратных и программных брейкпоинтов заключается в том, что аппаратные, в отличии от программных, не вносят изменения в память процесса, поэтому они могут быть более предпочтительными в случаях, когда мы имеем дело с защищенными программами. Что бы установить аппаратный брейкпоинт необходимо кликнуть правой кнопкой мыши по выбранной строке кода, в выпадающем меню выбрать “Breakpoint – Hardware, on Execution”: 

Аппаратные брейкпоинты

Брейкпоинты на память

Иногда вы можете найти строку или константу в памяти программы, но вы не знаете в каком месте в программе она используется. Используя брйкпоинты на память вы можете дать указание Олли остановиться в любом месте, где какая-либо команда в программе будет либо записывать либо считывать данные по адресу, с интересующими вас данными.  Существует три способа установить брейкпоинт на память: 

  1. Для инструкции: кликните по нужной строчке кода правой кнопкой мыши и выберите Breakpoint->Memory, On Access or Memory, On Write 
  2. Что бы установить брейкпоинт по какому-либо адресу в дампе памяти: выделите один или несколько байтов в окне дампа памяти, кликните по ней правой кнопкой мыши и выберите такие же опции, как указано выше. 
  3. Вы можете также установить брейкпоинт на целую секции памяти. Откройте окно Memory, кликните правой кнопкой мыши по нужной вам секции и выберите “Set Break On Acces” либо “Set Break On Write”. 

Брейкпоинты на память

Использование окна дампа

Вы можете использовать окно дампа что бы следить за значениями в памяти по каким-либо адресам в адресном пространстве процесса, который вы отлаживаете. Если инструкция, которую вы видите в окне дизассемблера, регистр или какой-либо элемент стека содержать адрес какой-либо локации памяти, вы можете кликнуть по ним правой кнопкой мыши и выбрать “Follow in Dump” – после этого окно дампа покажет вам содержимое этого адреса. Вы можете также кликнуть правой кнопкой мыши в пределах окна дампа, и выбрать “Go To”, что бы ввести туда адрес, по которому вы хотите перейти. Давайте попробуем теперь сделать это на практике. 

Убедитесь, что FirstProgram.exe загружена в Олли и остановлена на точке входа. Теперь начинаем пошаговое исполнение программы – нажмите F8 восемь раз и мы попадем на инструкцию по адресу 401021, которая выглядит как CALL FirstPro.40102C Если вы посмотрите на эту строчку, вы увидите что этот вызов функции перебросит нас на адрес 40102C, который находится на три строчки ниже нашей текущей позиции. Нажмите F7, что бы войти внутрь функции и мы, как и предполагалось, попадем на адрес 40102C.

Если вы вспомните, как работает инструкция CALL, то поймете что в конце концов, после выполнения функции, мы должны перейти на адрес, который идет сразу после 401021, то есть сразу после инструкции CALL. 

Использование окна дампа

А пока продолжайте пошаговое исполнение кода, пока мы не попадем на адрес 401062. Вы можете также установить брейкпоинт на эту строчку, нажать F9, что бы продолжить исполнение, и потом Олли остановиться, когда исполнение дойдет до инструкции по этому адресу. Вы помните как ставить брейкпоинты? Дважды кликните по месту с опкодом на строчке, на которую вы хотите поставить бряк. Вы можете также выделить нужную вам строку и после этого нажать клавишу F2. В итоге мы остановимся на адресе 401062: 

Использование окна дампа

Сейчас, давайте посмотрим на строчку кода, на которой мы стоим. Он выглядит как

MOV [LOCAL.3], FirstPro.00403009. Эта инструкция двигает значение, находящееся по адресу 403009 в стек (который Олли обозначает как LOCAL.3). Вы можете заметить в колонке с комментариями, что Олли обнаружила, что по этому адресу расположена строка “MyMenu”. Давайте сами в этом убедимся. Кликните по инструкции правой кнопкой мыши и выберите “Follow in Dump”. Вы заметите, что нам доступно несколько опций: 

Follow in Dump

В данном случае, выберите “Immediate Constant”. Это отобразит в окне дампа то, что находится по адресу, на который ссылается инструкция: 

Immediate Constant

Как вы видите, в окне дампа сейчас отобразилось содержимое памяти, начиная с адреса 403009, который является адресом, по которому расположена строка, на которую ссылалась команда. В правой части вы можете видеть строку “MyMenu”, в левой части – шестнадцатеричный код, который соответствует этой строке. Как можно заметить, после строки “MyMenu” идут другие строки. Эти строки используются в других частях программы.

Наконец, что-то интересное!

Что бы закончить этот туториал, давайте сделаем что-нибудь веселое. Давайте отредактируем бинарник так, что бы программа отображала наш собственный текст! Мы изменим строку “Dialog As Main” на другую и посмотрим, что из этого получится. 

Во-первых, нажмите на символ “D” строки “Dialog As Main” в ASCII-секции окна дампа: 

нажмите на символ “D” строки “Dialog As Main”

Вы заметите, что байт, который соответствует символу “D” также выделится. Давайте теперь выделим строку “Dialog As Main” целиком: 

Dialog As Main

Теперь кликните правой кнопкой мыши по выделенной строке и выберите “Binary” -> “Edit”. Это позволит изменить нам содержание памяти нашей программы: 

“Binary” -> “Edit”

Должно появится такое вот окно: 

Должно появится такое вот окно

Первое поле показывает нам нашу строку в ASCII-кодировке. Второе – в Юникоде (в этой программе данная кодировка не используется поэтому окно – пустое). Последнее поле отображает шестнадцатеричный код. Теперь – давайте изменим строку. Для корректной работы программы необходимо, что бы новая строка не была длиннее оригинальной! Потому что в противном случае мы изменим байты, которые относятся уже к другим данным. В моем случае я изменил строку на “Program R4ndom”. 

Program R4ndom

Теперь нажмите OK и запустите приложение (F9). Напечатайте в нем что-нибудь и потом выберите “Options” -> “Get Text”. 

Обратите внимание на заголовок открывшегося окна

Обратите внимание на заголовок открывшегося окна :)  

Целью данного «Введения в крэкинг с нуля, используя OllyDbg», является дать тем, кто только начал осваивать искусство крэкнинга, базовые знания и, вместе с тем, сделать это так, чтобы эти знания позволили в дальнейшем читать и понимать более продвинутые туториалы – такие, которые можно встретить в «Новом курсе от CracksLatinos», который, разумеется, остаётся открытым для новых добавлений и пополнений.

Идея создания курса родилась из-за того, что многие туториалы в «Новом курсе от CracksLations» оказывались слишком сложными для новичков, и те, не сумев достигнуть нужного уровня, оказывались разочарованными и во многих случаях отказывались продолжать. Поэтому целью данного «Введения…» является не повторение прекрасных туториалов из «Нового курса…», число которых уже перевалило за 500, но заложить основу, чтобы те, кто закончит данный курс, смогли читать более сложные пособия. Это, как и всё в нашем ремесле, требует значительных усилий, и главной задачей является сократить их количество, дав базовые знания и позволив в дальнейшем понимать более сложный материал.

Мы не будем здесь рассуждать о вечном противостоянии Soft-Ice против OllyDbg, думаю, что даже фанатики от Soft-Ice признают, что проще начать с OllyDbg, так как о нём много информации и его проще изучать. Нам нужно войти в мир крэкинга через дверь под названием «OllyDbg», а уже потом тот, кому нужно, сможет перейти на любой другой отладчик, который потребуется, так как меняются лишь их способы использования, но суть остаётся неизменной.

Сначала нужно вооружиться инструментом, который мы собираемся в основном использовать, для чего кликните тут

[ссылка]

и скачайте его.

Поскольку мы начинаем с нуля, то для начала нам нужно распаковать скачанный архив в такую папку на жёстком диске, до которой можно легко добраться. Хорошей идеей будет создать папку на диске C:/. Хотя будет работать и в любом другом месте, я буду исходить из того, что выбран диск C:/.

После того, как файл был распакован, заходим в созданную папку и видим:

В ней находится исполняемый файл OLLYDBG.exe, который нам и нужно запустить и ярлык, которого я для удобства сделал на своём рабочем столе.

Ок, всё готово к запуску. Кликаем на OllyDbg:

Перед нами появляется сообщение о том, что DLL, находящаяся в библиотеке, старше, чем такая же системная DLL, и если выберем «Да», то тогда старая DLL будет стёрта из папки, а использоваться будет системная. Хотя я не вижу особых различий между этими двумя, тем не менее, предпочитаю ту, которая идёт с дистрибутивом, и поэтому всегда нажимаю «Нет».

Это чистый OllyDbg, и первой программой, которую мы откроем только для того, чтобы ознакомиться с OllyDbg, станет знаменитый CrackMe CrueHead’а

[ссылка]

, который приложен к данному туториалу.

Чтобы открыть файл в OllyDbg, идём в File -> Open или нажимаем на иконку:

Откроется окно, с помощью которого можно найти нужный файл, в данном случае это crackme CrueHead’а.

Откроется вышеупомянутый crackme, и на данный момент неважно, что совершенно непонятно, что означает открывшийся нам вид – пока мы только пройдёмся по различным частям и функциям OllyDbg и некоторым настройкам, чтобы когда в последующих туториалах будет написано, скажем, «зайдите в DUMP», вы, по крайней мере, знали, где находится эта опция.

Здесь мы рассмотрим четыре части главного окна OllyDbg:

1. Дизассемблированный код

Также называется листингом. Тут Олли показывает нам дизассемблированный код программы, которую мы собираемся отлаживать; по умолчанию Олли сконфигурирована так, чтобы анализировать программу при её открытии. Это можно изменить в Options -> DEBUGGING OPTIONS.

То есть, если отмечена галочка «AUTO START ANALISIS OF MAIN MODULE», OllyDbg проанализирует программу и покажет о ней дополнительную информацию.

Это начало проанализированного листинга крэкми CrueHead’а, и если мы откроем его без анализа, то сможем увидеть разницу.

В окне анализа содержится множество информации, которая, несмотря на то, что пока нам не очень понятна, выглядит весьма интересной. В то же время приятно знать, что её можно в любой момент убрать, если анализ оказался не слишком точным или в него закралась какая-то ошибка.

Зачастую OllyDbg отображает некоторые части программы некорректно, так как ошибочно интерпретирует исполняемый код как данные, и тогда она отображает примерно следующее:

В этом случае можно вручную убрать анализ, кликнув на листинге правой кнопкой мыши и выбрав «ANALISIS -> REMOVE ANALYSIS FROM MODULE».

И тогда листинг отобразится корректно.

Другой опцией, которой вы можете воспользоваться для облегчения работы и которая мне лично не очень нравится (но вкусы бывают разные), является подсветка jump (переходов) и call (вызовов) – кликните на листинге правой кнопкой мыши и выберите «APPEARENCE -> HIGHLIGHTING -> JUMPS AND CALLS».

Здесь мы видим, что call’ы подсвечены лазурным цветом, а переходы – жёлтым.

Теперь листинг стал более читаемым, но пока у нас нет ни малейшей идеи, что это означает, но хорошо иметь инструмент подготовленным к дальнейшему использованию.

Второе важное окно – это окно регистров.

Вспомним, что окно регистров находится в самой правой части OllyDbg, и там отображается значительное количество информации.

Есть значительно больше информации, которую мы не видим, но можно устанавливать режим отображения в три состояния («VIEW FPU REGISTERS» – отображать FPU-регистры, «VIEW 3D NOW REGISTERS» – отображать «3D NOW»-регистры и «VIEW DEBUG REGISTERS» – отображать отладочные регистры). По умолчанию отображаются первые.

Теперь переходим к «стеку или куче». Здесь не слишком много конфигурационных опций – разве что возможность отобразить информацию, касающуюся регистров ESP и EBP.

По умолчанию стоить режим отображения информации, связанной с ESP (и он же является самым полезным), но его можно сменить на режим отображения информации, связанной с EBP, для чего необходимо кликнуть в этом окне правой кнопкой мыши и выбрать пункт «GO TO EBP», а дальнейшее использование пункта «GO TO ESP» вернёт нас в прежний режим.

В дальнейших главах я объясню подробнее функциональность стека, но пока мы рассматриваем только то, что можно изменить с помощью конфигурации.

У окно дампа есть много режимов отображения, которые можно менять, кликнув правую кнопку мыши в окне дампа и выбрав тот, который нужен. По умолчанию используется используется режим 8-ми байтовый Hex/ASCII.

Режим, используемый по умолчанию, также является и чаще всего используемым, но вместе с тем, у нас есть возможность изменять его на показ дизассемблированного кода (DISASSEMBLE), текста (TEXT) и других форматов (SHORT, LONG, FLOAT).

И, наконец, опция SPECIAL -> PE HEADER, которая, как мы это увидим в ближайших главах, может быть очень полезной.

Теперь мы знаем основные части главного окна OllyDbg, но есть ещё окна, которые недоступны напрямую, но могут быть вызваны как через меню, так и через кнопки на панели управления.

Рассмотрим каждую из них.

Кнопка L или VIEW->LOG показывает нам то, что OllyDbg пишет в окне лога. Его можно сконфигурировать на отображение различного рода информации, а по умолчанию в окне лога сохраняется вся информация о запуске, а также информация, связанная с «BREAKPOINTS CONDICIONAL LOGS» (условными логами точек останова). С последней мы встретимся гораздо позднее, а пока давайте посмотрим информацию о запущенном процессе (в нашем случае это крэкми CrueHead’а) и библиотеках, которые он загружает.

Одна из самых главных опций данного окна – это ведение лога в файле на тот случай, если мы хотим сохранять информацию в текстовом файле. Чтобы активировать эту опцию, нажмите на правую кнопку мыши и выберите «LOG TO FILE».

Кнопка E или VIEW->EXECUTABLES показывает нам список модулей, которые использует программа: exe, dll, ocx и прочие.

Здесь также правая кнопка мыши вызывает множество опций, которые пока мы смотреть не будем, но которые мы уже видели при исследовании главного окна OllyDbg.

Кнопка M или VIEW->MEMORY отображает память, занятую нашей программой. Здесь мы видим секции приложения, библиотеки, использующиеся процессом, стек и различные секции, занятые системой, и зачастую программы в процессе выполнения занимают новые секции памяти.

Кликнув правой кнопкой мыши можем сделать SEARCH в памяти, чтобы найти в ней строки различных родов (текстовые, шестнадцатиричные, юникодовые), также есть возможность подсветить точки останова в секциях, равно как и возможность изменить права доступа к последним (выберите SET ACCESS).

Кнопка T или VIEW->THREADS показывает нам список нитей (потоков) программы.

Хотя сейчас мы не знаем что это такое, а узнаем это лишь в последующих главах, ознакомиться с каждым из окон лишним не будет. Пользоваться ими мы научимся позднее.

Кнопка W или VIEW->WINDOWS отображает нам окна программы, но поскольку она ещё не выполняется, то и список окон остаётся пустым.

Кнопка H или VIEW->HANDLES отображает хэндлы, позже я объясню, для чего они служат.

Кнопка C или VIEW->CPU возвращает нас к главному окно OllyDbg.

Кнопка / или VIEW->PATCHES показывает список наложенных патчей, если программа была изменена. Поскольку пока никаких изменений не вносилось, сейчас окно остаётся пустым.

Кнопка K или VIEW->CALL STACK отображает «call stack», список вызовов, которые нам встретились до того места, где программа остановилась.

Кнопка B или VIEW->BREAKPOINTS вызывает список обычных точек останова, расположенных в программе. Здесь нет ни точек останова аппаратного обеспечения, ни точек останова памяти, только обычные.

Кнопка R или VIEW->REFERENCES показывает окно ссылок, полученных нами в результате поиска ссылок в Олли.

Кнопка «…» или VIEW->RUN TRACE отображает результат выполнения команды RUN TRACE. Здесь мы также можем выбрать опцию LOG TO FILE), чтобы сохранить результаты трассировки в текстовом файле.

Мы рассмотрели панель с самыми важными кнопками, чтобы вы были знакомы с возможностями, которые они предоставляют, когда мы начнём их более глубокое изучение в последующих главах.

Как сконфигуровать OllyDbg стала JIT (JUST IN TIME DEBUGGER)

Конечно, мы не будем всё время использовать JIT, а только в специальных случаях, так как если случится ошибка с какой-либо запущенной программой на нашей машине, то нам совсем не нужно, чтобы использовалась Олли (по умолчанию в качестве JIT используется dr.watson).

Чтобы сделать OllyDbg JIT-отладчиком, нужно перейти в OPTIONS->JUST IN TIME DEBUGGING

и нажать последовательно кнопки MAKE OLLYDBG JUST IN TIME DEBUGGER и DONE

Чтобы убрать эту функцию, нужно в том же месте нажать на RESTORE OLD JUST IN TIME DEBUGGER и DONE.

Подключение плагинов в OllyDbg

OllyDbg позволяет подключать плагины, которые могут оказаться полезными для решения той или иной задачи. Пока мы ограничимся подключением плагина COMMAND BAR, чтобы научиться как это делать.

Скачиваем данный плагин отсюда [

ссылка

]

После этого распаковываем плагин и смотрим содержимое папки, где это было сделано:

Прежде всего нужно создать папку для плагинов. Я создам её на C:/ и назову PLUGINS.

Разумеется, плагины могут находиться где угодно, но мне нравится размещать всё на C. Как бы то ни было, теперь мы должны сконфигурировать OllyDbg, чтобы она распознавала эту папку как местонахождение всех плагинов.

Для этого идём в OPTIONS->APPEARANCE.

И в открывшемся окне открываем вкладку DIRECTORIES.

Видим, что в качестве пути к плагинам указана директория, где находится сам OllyDbg.exe, и можно было бы помещать плагины туда, но мне нравится держать их отдельно, и тогда нажимаем на PLAGIN PATH->BROWSE, чтобы найти созданную нами папку.

Выбираем папку PLUGINS и сохраняем изменения.

То есть нужно перезапустить Олли, чтобы она признала новую папку с плагинам, но сначала следует скопировать в последнюю скачанный плагин.

Копируем всё содержимое архива в папку PLUGINS.

Теперь все файлы плагина «Command Bar» находятся в папке PLUGINS, в неё же следует помещать и остальные (зачастую можно копировать не все файлы в архиве, а только dll).

Теперь закрываем OllyDbg, если она всё ещё была закрыта, и запускаем по новой. Видим, что в меню PLUGINS появился COMMAND BAR и его опции.

В нижней части OllyDbg видим установленный COMMAND BAR.

Это текстовое поле для ввода команд, которые нам могут пригодиться во многих случаях, и позднее мы увидим их применение, а пока важно научиться подключать плагины.

Чтобы деинсталлировать PLUGIN достаточно просто стереть соответствующую dll из папки PLUGINS и перезапустить OllyDbg, и плагин исчезнет. Вместе с тем, благоразумно всегда держать COMMAND BAR включённым.

Снова открываем крэкми CrueHead’в в OllyDbg.

Наиболее полезные клавиши в OllyDbg следующие:

F7: Выполняет одну строку кода (если находимся на CALL, то переходим внутрь вызванного участка кода)

F8: Выполняет одну строку кода (если находимся на CALL, то просто выполняет вызов без перехода внутрь и переходит на следующую за CALL строку).

Это два вида ручной трассировки очень разные и в каких случаях использовать каждую из них мы рассмотрим позже.

F2: устанавливает обычную точку останова на отмеченной линии. Чтобы убрать эту точку останова, надо ещё раз нажать F2.

Хотим установить точку установа в позиции 40101A, поэтому отмечаем эту линию с помощью мыши.

С помощью одного клика мыши она помечается и становится серого цвета как на картинке. Затем нажимаем F2.

Видим, что соответствующая позиция в первой колонке становится красной, что говорит о том, что здесь есть точка останова. Нажав F2 ещё раз можно её убрать.

F9: Запускает программу, которая будет выполняться до тех пор, пока не встретит точку останова, не совершиться какое-либо исключение или же просто прекратит работу по каким-либо причинам. Когда программа запущена, в нижнем правом угле OllyDbg отображается слово RUNNING.

Запустив крэкми CrueHead’а, мы увидим следующее:

Чтобы временно прекратить выполнение программы, нужно нажать F12 или DEBUG->PAUSE.

Видим, что OllyDbg отображает слово PAUSED (пауза). Продолжить выполнение программы можно нажав F9 или DEBUG->RUN.

Чтобы закрыть отлаживаемую программу выберите DEBUG->CLOSE.

Это был краткий обзор OllyDbg, более глубокое изучение множества опций и возможностей которой мы продолжим изучать в последующих главах. Главное, чтобы вы скачали программу, сконфигурировали, ещё раз посмотрели всё, о чём было рассказано в этом туториале, так же подключили плагин, позапускали и поостанавливали крэкми CrueHead’а, попробовали поставить точки останова, чтобы в следующей главе все эти вещи не вызывали у вас колебаний и сомнений.

[C] Рикардо Нарваха, пер. Aquila

Глава 1 — Введение в OllyDbg

Целью данного «Введения в крэкинг с нуля, используя OllyDbg», является дать тем, кто только начал осваивать искусство крэкнинга, базовые знания и, вместе с тем, сделать это так, чтобы эти знания позволили в дальнейшем читать и понимать более продвинутые туториалы – такие, которые можно встретить в «Новом курсе от CracksLatinos», который, разумеется, остаётся открытым для новых добавлений и пополнений.

Идея создания курса родилась из-за того, что многие туториалы в «Новом курсе от CracksLations» оказывались слишком сложными для новичков, и те, не сумев достигнуть нужного уровня, оказывались разочарованными и во многих случаях отказывались продолжать. Поэтому целью данного «Введения…» является не повторение прекрасных туториалов из «Нового курса…», число которых уже перевалило за 500, но заложить основу, чтобы те, кто закончит данный курс, смогли читать более сложные пособия. Это, как и всё в нашем ремесле, требует значительных усилий, и главной задачей является сократить их количество, дав базовые знания и позволив в дальнейшем понимать более сложный материал.

Почему OLLYDBG?

Мы не будем здесь рассуждать о вечном противостоянии Soft-Ice против OllyDbg, думаю, что даже фанатики от Soft-Ice признают, что проще начать с OllyDbg, так как о нём много информации и его проще изучать. Нам нужно войти в мир крэкинга через дверь под названием «OllyDbg», а уже потом тот, кому нужно, сможет перейти на любой другой отладчик, который потребуется, так как меняются лишь их способы использования, но суть остаётся неизменной.

Начнём с начала

Сначала нужно вооружиться инструментом, который мы собираемся в основном использовать, для чего кликните тут [ссылка] и скачайте его.

Поскольку мы начинаем с нуля, то для начала нам нужно распаковать скачанный архив в такую папку на жёстком диске, до которой можно легко добраться. Хорошей идеей будет создать папку на диске C:/. Хотя будет работать и в любом другом месте, я буду исходить из того, что выбран диск C:/.

После того, как файл был распакован, заходим в созданную папку и видим:

В ней находится исполняемый файл OLLYDBG.exe, который нам и нужно запустить и ярлык, которого я для удобства сделал на своём рабочем столе.

Части главного окна

Ок, всё готово к запуску. Кликаем на OllyDbg:

Перед нами появляется сообщение о том, что DLL, находящаяся в библиотеке, старше, чем такая же системная DLL, и если выберем «Да», то тогда старая DLL будет стёрта из папки, а использоваться будет системная. Хотя я не вижу особых различий между этими двумя, тем не менее, предпочитаю ту, которая идёт с дистрибутивом, и поэтому всегда нажимаю «Нет».

Это чистый OllyDbg, и первой программой, которую мы откроем только для того, чтобы ознакомиться с OllyDbg, станет знаменитый CrackMe CrueHead’а [ссылка], который приложен к данному туториалу.

Чтобы открыть файл в OllyDbg, идём в File -> Open или нажимаем на иконку:

Откроется окно, с помощью которого можно найти нужный файл, в данном случае это crackme CrueHead’а.

Откроется вышеупомянутый crackme, и на данный момент неважно, что совершенно непонятно, что означает открывшийся нам вид – пока мы только пройдёмся по различным частям и функциям OllyDbg и некоторым настройкам, чтобы когда в последующих туториалах будет написано, скажем, «зайдите в DUMP», вы, по крайней мере, знали, где находится эта опция.

Здесь мы рассмотрим четыре части главного окна OllyDbg:

1. Дизассемблированный код

Также называется листингом. Тут Олли показывает нам дизассемблированный код программы, которую мы собираемся отлаживать; по умолчанию Олли сконфигурирована так, чтобы анализировать программу при её открытии. Это можно изменить в Options -> DEBUGGING OPTIONS.

То есть, если отмечена галочка «AUTO START ANALISIS OF MAIN MODULE», OllyDbg проанализирует программу и покажет о ней дополнительную информацию.

Это начало проанализированного листинга крэкми CrueHead’а, и если мы откроем его без анализа, то сможем увидеть разницу.

В окне анализа содержится множество информации, которая, несмотря на то, что пока нам не очень понятна, выглядит весьма интересной. В то же время приятно знать, что её можно в любой момент убрать, если анализ оказался не слишком точным или в него закралась какая-то ошибка.

Зачастую OllyDbg отображает некоторые части программы некорректно, так как ошибочно интерпретирует исполняемый код как данные, и тогда она отображает примерно следующее:

В этом случае можно вручную убрать анализ, кликнув на листинге правой кнопкой мыши и выбрав «ANALISIS -> REMOVE ANALYSIS FROM MODULE».

И тогда листинг отобразится корректно.

Другой опцией, которой вы можете воспользоваться для облегчения работы и которая мне лично не очень нравится (но вкусы бывают разные), является подсветка jump (переходов) и call (вызовов) – кликните на листинге правой кнопкой мыши и выберите «APPEARENCE -> HIGHLIGHTING -> JUMPS AND CALLS».

Получится следующее:

Здесь мы видим, что call’ы подсвечены лазурным цветом, а переходы – жёлтым.

Теперь листинг стал более читаемым, но пока у нас нет ни малейшей идеи, что это означает, но хорошо иметь инструмент подготовленным к дальнейшему использованию.

2. Регистры

Второе важное окно – это окно регистров.

Вспомним, что окно регистров находится в самой правой части OllyDbg, и там отображается значительное количество информации.

Есть значительно больше информации, которую мы не видим, но можно устанавливать режим отображения в три состояния («VIEW FPU REGISTERS» – отображать FPU-регистры, «VIEW 3D NOW REGISTERS» – отображать «3D NOW»-регистры и «VIEW DEBUG REGISTERS» – отображать отладочные регистры). По умолчанию отображаются первые.

3. Стек или «куча»

Теперь переходим к «стеку или куче». Здесь не слишком много конфигурационных опций – разве что возможность отобразить информацию, касающуюся регистров ESP и EBP.

По умолчанию стоить режим отображения информации, связанной с ESP (и он же является самым полезным), но его можно сменить на режим отображения информации, связанной с EBP, для чего необходимо кликнуть в этом окне правой кнопкой мыши и выбрать пункт «GO TO EBP», а дальнейшее использование пункта «GO TO ESP» вернёт нас в прежний режим.

В дальнейших главах я объясню подробнее функциональность стека, но пока мы рассматриваем только то, что можно изменить с помощью конфигурации.

4. Дамп

У окно дампа есть много режимов отображения, которые можно менять, кликнув правую кнопку мыши в окне дампа и выбрав тот, который нужен. По умолчанию используется используется режим 8-ми байтовый Hex/ASCII.

Режим, используемый по умолчанию, также является и чаще всего используемым, но вместе с тем, у нас есть возможность изменять его на показ дизассемблированного кода (DISASSEMBLE), текста (TEXT) и других форматов (SHORT, LONG, FLOAT).

И, наконец, опция SPECIAL -> PE HEADER, которая, как мы это увидим в ближайших главах, может быть очень полезной.

Остальные окна OllyDbg

Теперь мы знаем основные части главного окна OllyDbg, но есть ещё окна, которые недоступны напрямую, но могут быть вызваны как через меню, так и через кнопки на панели управления.

Рассмотрим каждую из них.

Окно Log

Кнопка L или VIEW->LOG показывает нам то, что OllyDbg пишет в окне лога. Его можно сконфигурировать на отображение различного рода информации, а по умолчанию в окне лога сохраняется вся информация о запуске, а также информация, связанная с «BREAKPOINTS CONDICIONAL LOGS» (условными логами точек останова). С последней мы встретимся гораздо позднее, а пока давайте посмотрим информацию о запущенном процессе (в нашем случае это крэкми CrueHead’а) и библиотеках, которые он загружает.

Одна из самых главных опций данного окна – это ведение лога в файле на тот случай, если мы хотим сохранять информацию в текстовом файле. Чтобы активировать эту опцию, нажмите на правую кнопку мыши и выберите «LOG TO FILE».

Окно Executables

Кнопка E или VIEW->EXECUTABLES показывает нам список модулей, которые использует программа: exe, dll, ocx и прочие.

Здесь также правая кнопка мыши вызывает множество опций, которые пока мы смотреть не будем, но которые мы уже видели при исследовании главного окна OllyDbg.

Окно memory

Кнопка M или VIEW->MEMORY отображает память, занятую нашей программой. Здесь мы видим секции приложения, библиотеки, использующиеся процессом, стек и различные секции, занятые системой, и зачастую программы в процессе выполнения занимают новые секции памяти.

Кликнув правой кнопкой мыши можем сделать SEARCH в памяти, чтобы найти в ней строки различных родов (текстовые, шестнадцатиричные, юникодовые), также есть возможность подсветить точки останова в секциях, равно как и возможность изменить права доступа к последним (выберите SET ACCESS).

Окно Threads

Кнопка T или VIEW->THREADS показывает нам список нитей (потоков) программы.

Хотя сейчас мы не знаем что это такое, а узнаем это лишь в последующих главах, ознакомиться с каждым из окон лишним не будет. Пользоваться ими мы научимся позднее.

Окно Windows

Кнопка W или VIEW->WINDOWS отображает нам окна программы, но поскольку она ещё не выполняется, то и список окон остаётся пустым.

Окно Handles

Кнопка H или VIEW->HANDLES отображает хэндлы, позже я объясню, для чего они служат.

Окно CPU

Кнопка C или VIEW->CPU возвращает нас к главному окно OllyDbg.

Окно Patches

Кнопка / или VIEW->PATCHES показывает список наложенных патчей, если программа была изменена. Поскольку пока никаких изменений не вносилось, сейчас окно остаётся пустым.

Окно Call Stack

Кнопка K или VIEW->CALL STACK отображает «call stack», список вызовов, которые нам встретились до того места, где программа остановилась.

Окно Breakpoints

Кнопка B или VIEW->BREAKPOINTS вызывает список обычных точек останова, расположенных в программе. Здесь нет ни точек останова аппаратного обеспечения, ни точек останова памяти, только обычные.

Окно References

Кнопка R или VIEW->REFERENCES показывает окно ссылок, полученных нами в результате поиска ссылок в Олли.

Окно Run Trace

Кнопка «…» или VIEW->RUN TRACE отображает результат выполнения команды RUN TRACE. Здесь мы также можем выбрать опцию LOG TO FILE), чтобы сохранить результаты трассировки в текстовом файле.

Мы рассмотрели панель с самыми важными кнопками, чтобы вы были знакомы с возможностями, которые они предоставляют, когда мы начнём их более глубокое изучение в последующих главах.

Как сконфигуровать OllyDbg стала JIT (JUST IN TIME DEBUGGER)

Конечно, мы не будем всё время использовать JIT, а только в специальных случаях, так как если случится ошибка с какой-либо запущенной программой на нашей машине, то нам совсем не нужно, чтобы использовалась Олли (по умолчанию в качестве JIT используется dr.watson).

Чтобы сделать OllyDbg JIT-отладчиком, нужно перейти в OPTIONS->JUST IN TIME DEBUGGING

и нажать последовательно кнопки MAKE OLLYDBG JUST IN TIME DEBUGGER и DONE

Чтобы убрать эту функцию, нужно в том же месте нажать на RESTORE OLD JUST IN TIME DEBUGGER и DONE.

Подключение плагинов в OllyDbg

OllyDbg позволяет подключать плагины, которые могут оказаться полезными для решения той или иной задачи. Пока мы ограничимся подключением плагина COMMAND BAR, чтобы научиться как это делать.

Скачиваем данный плагин отсюда [ссылка]

После этого распаковываем плагин и смотрим содержимое папки, где это было сделано:

Прежде всего нужно создать папку для плагинов. Я создам её на C:/ и назову PLUGINS.

Разумеется, плагины могут находиться где угодно, но мне нравится размещать всё на C. Как бы то ни было, теперь мы должны сконфигурировать OllyDbg, чтобы она распознавала эту папку как местонахождение всех плагинов.

Для этого идём в OPTIONS->APPEARANCE.

И в открывшемся окне открываем вкладку DIRECTORIES.

Видим, что в качестве пути к плагинам указана директория, где находится сам OllyDbg.exe, и можно было бы помещать плагины туда, но мне нравится держать их отдельно, и тогда нажимаем на PLAGIN PATH->BROWSE, чтобы найти созданную нами папку.

Выбираем папку PLUGINS и сохраняем изменения.

То есть нужно перезапустить Олли, чтобы она признала новую папку с плагинам, но сначала следует скопировать в последнюю скачанный плагин.

Копируем всё содержимое архива в папку PLUGINS.

Теперь все файлы плагина «Command Bar» находятся в папке PLUGINS, в неё же следует помещать и остальные (зачастую можно копировать не все файлы в архиве, а только dll).

Теперь закрываем OllyDbg, если она всё ещё была закрыта, и запускаем по новой. Видим, что в меню PLUGINS появился COMMAND BAR и его опции.

В нижней части OllyDbg видим установленный COMMAND BAR.

Это текстовое поле для ввода команд, которые нам могут пригодиться во многих случаях, и позднее мы увидим их применение, а пока важно научиться подключать плагины.

Чтобы деинсталлировать PLUGIN достаточно просто стереть соответствующую dll из папки PLUGINS и перезапустить OllyDbg, и плагин исчезнет. Вместе с тем, благоразумно всегда держать COMMAND BAR включённым.

Снова открываем крэкми CrueHead’в в OllyDbg.

Наиболее полезные клавиши в OllyDbg следующие:

F7: Выполняет одну строку кода (если находимся на CALL, то переходим внутрь вызванного участка кода)

F8: Выполняет одну строку кода (если находимся на CALL, то просто выполняет вызов без перехода внутрь и переходит на следующую за CALL строку).

Это два вида ручной трассировки очень разные и в каких случаях использовать каждую из них мы рассмотрим позже.

F2: устанавливает обычную точку останова на отмеченной линии. Чтобы убрать эту точку останова, надо ещё раз нажать F2.

Например:

Хотим установить точку установа в позиции 40101A, поэтому отмечаем эту линию с помощью мыши.

С помощью одного клика мыши она помечается и становится серого цвета как на картинке. Затем нажимаем F2.

Видим, что соответствующая позиция в первой колонке становится красной, что говорит о том, что здесь есть точка останова. Нажав F2 ещё раз можно её убрать.

F9: Запускает программу, которая будет выполняться до тех пор, пока не встретит точку останова, не совершиться какое-либо исключение или же просто прекратит работу по каким-либо причинам. Когда программа запущена, в нижнем правом угле OllyDbg отображается слово RUNNING.

Запустив крэкми CrueHead’а, мы увидим следующее:

Чтобы временно прекратить выполнение программы, нужно нажать F12 или DEBUG->PAUSE.

Видим, что OllyDbg отображает слово PAUSED (пауза). Продолжить выполнение программы можно нажав F9 или DEBUG->RUN.

Чтобы закрыть отлаживаемую программу выберите DEBUG->CLOSE.

Это был краткий обзор OllyDbg, более глубокое изучение множества опций и возможностей которой мы продолжим изучать в последующих главах. Главное, чтобы вы скачали программу, сконфигурировали, ещё раз посмотрели всё, о чём было рассказано в этом туториале, так же подключили плагин, позапускали и поостанавливали крэкми CrueHead’а, попробовали поставить точки останова, чтобы в следующей главе все эти вещи не вызывали у вас колебаний и сомнений.

[C] Рикардо Нарваха, пер. Aquila

Сегодня покажу как можно с помощью «Ольки», «вылечить» один известный архиватор. Для этого нам понадобится: OllyDBG, плагин «CommandBar».

Ставим архиватор, через

40 дней

некоторое время наблюдаем картину:

Первое что приходит в голову — изменить проверку на наличие лицензии или проверку на время использования программы. Пойдем по легкому пути — ищем WinAPI функцию которая получает настоящее время GetLocalTime. В контекстном меню выбираем

Search for -> Name (label) in current module.

Ищем функции связанные со временем, ах вот же она, чуть не пропустили.

Теперь необходимо поставить брейкпоинт на эту функцию. В окне плагина CommandBar вводим

bp GetLocalTime

и теперь при вызове этой функции наш отладчик остановится в нужном нам месте.

Запускаем отладку, клавиша F9. Наша точка останова успешно отработала и мы оказались в начале функции GetLocalTime, давайте дойдем до места выхода из этой функции (Ctr+F9), сделаем один шаг (F7). Вот мы видим, что после получения времени, вызывается функция по адресу 004B8C00, предлагаю зайти в неё и посмотреть что там может быть интересного, используем шаг с заходом (F7).

Видим благоприятные знаки.

Трассируем программу по F8, до проверки по адресу 004B8C26, наблюдаем TEST AL,AL.

Напоминаю, AL — является младшим регистром EAX, там у нас сейчас пусто. Команда TEST AL,AL проверяет, равен ли регистр AL нулю, если равен, то флаг ZF будет включен.Следующая команда JE SHORT 004B8C44, отправляет на с по адресу 004B8C44, в случае если ZF флаг включен. Что же, предлагаю убрать эту проверку с переходом. Нажимаем пробел и вводим nop, несколько раз нажимаем Assemble, пока не затрутся эти две команды.

Запускаем отладку (F9) и видим что опять остановились на нашем брейкпоинте, давайте уберем его (F2) и снова продолжим отладку (F9). Теперь видим что нам ничего не мешает работать и в поле о регистрации появилась надпись о там что программа зарегистрирована.

In this tutorial, I will attempt to introduce you to using OllyDBG. Olly has many functions and the only way to truly learn them all is to experiment and practice. That being said, this tutorial will give you a brief overview. Additional topics not covered in this tutorial will be discussed in later tutorials, so that by the end, you should have a pretty good grasp of Olly.

I am including some files in this tutorial. You can download the files and PDF version of this tutorial on the tutorials page. They include a simple binary that we will be using in olly, an Olly cheat sheet, my version of Olly with some cosmetic changes, and a new ini file that you can replace Olly’s default init file with that will help with new users (thanks go out to the immortal Lena151 for this). They can be downloaded directly here or from the tutorials page. If you would rather use the original Olly, you can download it here .

Loading the app

The first step is to load the intended binary into Olly. You can either drag and drop the file onto Olly’s disassmebly window, or click the load icon on the top far left and choose the file. In this case, load “FirstProgram.exe”, downloaded from this site. Olly will do analysis (if you can read it fast enough in the bottom bar of Olly’s display) and will stop at the programs Entry Point (EP):

Olly main screen

The first thing to notice is that the EP is at address 401000, as we can see in the first column. This is a pretty standard starting point for an executable (at least an executable that has not been packed or obfuscated anyway). If your screen looks different and Olly has not stopped at 401000, try going into Appearance and selecting debugging options, click on the “Events” tab, and make sure “WinMain (if location is known)” is checked. Then restart the app).

Let’s get a snapshot of the memory space taken up by “FirstProgram.exe”. Click on the “Me” icon (or “M” if using a different version of Olly):

Memory Window
If you look in the address column, you will see that at location 401000, the row contains the size 1000, the name “FirstPro” (short for FirstProgram), the section name “.text, and that it contains “SFX, code”. As we will learn later in this series, exe files have different sections in them that contain different types of data. In this section is the “code” for the program. It is 1000h bytes long and it starts at address 401000 in memory.

Below this you will see the other sections of our FirstProgram; there is an .rdata section that contains data and imports at address 402000, a section called “.data” that contains nothing at address 403000, and finally, a section called “.rsrc” that contains resources (such as dialog boxes, images, text etc. Keep in mind that these sections can be called anything- it is completely up to the programmer.

You may wonder why the .data section has nothing in it. Well, in actuality, it does. It has things like global variables and random data. Olly just chooses not to list this as he doesn’t know exactly what kind of data is stored in there.

At the top of the sections is a section called “PE Header”. This is a very important section, one we will get very much into in a future article. For now, just know that it is like an instruction manual for Windows with steps for loading this file into memory, how much space it needs to run, where certain things are etc. It is at the head of just about any exe (and DLL for that matter).

If you now look down the list, you will see other files other than our First Program app. We see comctl32, imm32, gdi32, kernel32 etc. These are DLL files that our app needs in order to run. A Dll file is a collection of functions that our program can call that have been provided by windows (or another programmer). These are things such as opening dialog boxes, comparing strings, creating windows and the like. Collectively, these are the Windows API. The reason programs  use these is because if we had to program every function, just displaying a message box could take thousands of lines of code. Instead, Windows has provided a function like CreateWindow that does this for us. This makes programming much, much easier for the programmer.

You may wonder how these DLL’s got into the address space of our program and how windows knew which ones were needed. Well, this information is stored in the PE Header listed above. When Windows loads our exe into memory, it checks this header and finds the names of the DLL’s, as well as what functions in each DLL our program needs, and then loads these into our program’s memory space so that our program can call them. Every program loaded into memory will also have the required DLL’s that the program need loaded into it’s memory space. This means that, conceivably, some DLL’s may be loaded several times in memory if several programs are currently loaded and all use that particular DLL. If you would like to see exactly which functions our program calls, you can right-click in Olly’s disassembly window and select “Search For” -> “All Intermodular Calls. This shows something like the following:

Intermodular calls

This may be surprising, but this list is VERY small, Usually, there are hundred’s or thousands of functions needed for a commercial product, but because our sample program is so simple, it doesn’t need very many. Although, when you think about what our program does, it seem like quite a lot of functions just to perform such a basic role! Welcome to Windows :) . This window shows the name of the DLL first, followed by the name of the function. For instance, User32.LoadIconA is in the DLL User32 and the function name is LoadIconA. This function usually loads the icon on the top left corner of the window.

Next, let’s do a search for all strings in the app. Right-click the disassembly window and choose “Search For” -> “All Referenced Text Strings:

Strings

This window shows all text strings it could find in our app. Since this app is very simple, there are only a couple. Most apps will have MANY more (sometimes in the 100′s of thousands) unless they have been packed or obfuscated. In this case, you may see none at all! The reason packers do this is because reverse engineers (at least new ones) rely heavily on text strings to find important functions in a binary, and removing the text strings makes it much harder. Imagine if you did a search for text strings and saw “Congratulations! You entered the correct serial”? Well, this would be a huge help to a reverser (and we will see this time and again). By the way, double-clicking on one of the strings will take you to the instruction that uses it in the disassembly window. This is a nice feature so you can jump right to the code that uses the string.

Running the program

If you look in the top left corner of Olly you should see a yellow window that says “Paused”. This is telling you that the app is paused (at the beginning in this case) and ready for you to do something. So let’s do something!. Try hitting F9 (or choose “Run” from the “Debug” menu option). After a second, our program will pop up a dialog box (it may open behind Olly, so minimize Olly’s window to make sure.)

Our Program

That same box that said Paused should now say Running. This means that the app is running, but running inside Olly. You may interact with our program, in fact do :) See how it works and what it does. If you accidentally close it, click back over to Olly and hit ctrl-F2 (or choose Debug->Restart) to re-load the program, and you can hit F9 to run it again.

Now try this: as the program is running, click over to Olly and click the pause icon (or click F12, or choose Debug->Pause). This will pause our program wherever in memory it happened to be running. If you now try to view the program, it will look funny (or won’t show up at all). This is because Windows is not updating the view as it is paused. Now hit F9 again and you should be able to play with the program again. If anything goes wrong, just click the double left facing arrow icon or choose Debug-restart (or ctrl-F2) and the app will re=load and pause at the beginning. You can now run it again if you wish.

Stepping the program

Running an app is fine and dandy, but doesn’t give you a heck of a lot of information about what’s going on. Let’s try single-stepping. Reload the application (reload icon, ctrl-F2, or debug->restart) and we will be paused at the start of the application. now press F8. You will notice that the current line selector has gone down one line. What Olly has done is run one line of instructions and then paused again. If you were really observant, you would have noticed the stack window scrolled down one and has a new entry at the top:

Stack Window 1

This is because the instruction that we performed, PUSH 0″ ‘pushed’ a zero onto the stack. This shows up on the stack as “pModule = NULL”. NULL is another name for zero. You also may have noticed that in the registers window, the ESP and EIP registers have turned red:

Registers Window

When a register turns red, it means that the last instruction run changed that register. In this case, the ESP register (which points to the address of the top of the stack) was incremented by one since we pushed a new value onto the stack. The EIP register, which points to the current instruction that is being run has also increased by two. This is because we are no longer on address 401000, but 401002- running that last instruction was two bytes long and we are now paused on the next instruction. This instruction is at 401002, which is the current value of EIP.

The instruction that Olly is now paused on is a CALL. A call instruction means that we want to temporarily pause in the current function we are in and run another function. This is analogous to calling a method inside a high level language, for instance:

int main()
{
    int x = 1;
    call doSomething();
    x = x + 1;
}

In this code, we first make x equal to 1, then we want to pause this line of logic and instead call doSomething(). When doSomething is done, we will resume with our original logic and increase x by 1.

Well, the same is true in assembly language. We first PUSHed a zero onto the stack and now we want to call a function, in this case the one in Kernel32.dll called GetModuleHandleA():

The PUSH instruction

Now press F8 once more. The current line indicator will move down one, the EIP register will stay red and increase by 5 (as the instruction that ran was 5 bytes long) and the stack was brought back to what it originally showed. What happened here is that since we pressed F8, which mean “Step-Over”, the code inside the call was performed and Olly paused on the next line after the call. Now, inside of this call the program could have done anything, but we ‘stepped over’ it.

Now, to see the other option, re-start the program (ctrl-F2), press F8 to step over the first instruction, but this time hit F7 on the call instruction. You will notice that the entire window looks different now:

New Code Area

This is because F7 is “Step-In”, meaning Olly made the call and paused at the first line of this new function. In this case, the call jumped to a new area of memory (EIP = 4012d6). Theoretically, if we kept stepping through this new functions lines of code, we would eventually get back to the statement after the call that got us here, back at the beginning. Of course, there are shortcuts to this, but for now, let’s just re-start the program and start over, as we don’t want to get too lost.

Now that we are paused at the beginning of the program, hit F8 (Step-Over) 4 times and we will land on this statement:

Main Window 2

You will notice that there are 4 PUSH statements in a row. This time, watch the stack window as you hit F8 4 times and watch the stack grow (it actually grows down – remember the plate example?). I think we’re starting to get the feel for PUSHing on the stack…

Now you may ask WHY we pushed these arbitrary numbers onto the stack. In this case it is because these 4 numbers are being passed as parameters to a function (the function we are about to call at address 401021). If we take our previous high-level program and modify it a bit, it will become clearer:

int main()
{
    int x = 1;
    int y = 0;
    call doSomething( x, y );
    x = x + 1;
}

Here, we declare two variables, x and y, and pass them into the doSomething Function. The doSomething function will (probably) do something with these variables and then return control back to the calling program. The stack is one of the main ways that variables can be passed to a function: each variable is PUSHed onto the stack, the function is called, and the in the function, these variables are accessed, usually using the inverse of the PUSH instruction which is POP.

The stack is not the only way to do this, it is just the most often used. These variables could also have been put into registers and accessed through these registers inside the called function, but in this case, the compiler of our program chose to put them on the stack. All of this will become clearer after you study assembly language (you are studying assembly language, aren’t you?). We will also go over this several times in the future.

Now, if we press F8 one more time, you will notice that it will say “Running” in the active bar in Olly and our program’s dialog box will show up. This is because we stepped-over the call that actually has most of the program in it. Inside this call is code that enters a loop waiting for us to do something, so we never get control back to the line after the call. Well, let’s fix that…Click over to our program and hit the ‘close’ button to end the app. Olly will immediately pause on the next line after the call:
Main window 3

You will also notice that our program has disappeared. This is because, somewhere in that call, the dialog window was closed. Also, if you look down one line you will see that we are just about to call kernel32.dll -> ExitProcess. This is the Windows API that stops an application, so basically Olly has paused our program after it has closed the window but before it has actually been terminated! If you now press F9, the program will terminate, the active bar in Olly will say “Terminated” and we are no longer debugging anything.

Breakpoints

Let’s try something else, re-load the app (ctrl-F2) and double-click on the line at address 401011 in the second column (you will be clicking on the opcodes “6A 0A”. Address 401011 will now turn red:

Setting a breakpoint

What you have done is set a breakpoint on address 401011. Breakpoints force Olly to pause execution when it reaches it. There are different types of breakpoints in order to stop execution on different events:

Software Breakpoints

A software breakpoint replaces the byte at your breakpoint address with a 0xCC opcode, which is an int 3. This is a special interrupt that tells the operating system that a debugger wishes to pause here and to give control over to the debugger before executing the instruction. You won’t see the instruction change to 0xCC, Olly does this behind the scenes, but when Olly hits it an exception occurs and Olly will trap the exception and allow the user to do what he/she wishes. If you select to allow the program to continue (either by running it or stepping), the 0xCC opcode is replaced back with it’s original.

In order to set a software breakpoint, you can either double-click on the opcode column, or you can highlight the row you want the breakpoint on, right-click on it, and choose Breakpoints->Toggle (or hit F2). To remove the breakpoint, you can double-click on the same line or right-click and select Breakpoint->Remove Software Breakpoint (or hit F2 again).

Now that we have a BP (breakpoint) set at address 401011 and our program is paused at the first instruction, hit F9 (run). Our program will run but will pause at the line with our BP on it.

I also want to point out something very helpful. Click on the “Br” toolbar icon or select View->Breakpoints. You will see an entry in the breakpoint window that shows our currently set BP:

Breakpoint window

This gives you a quick overview of all of your breakpoints set. You can double-click on one of them and the disassembly window will jump to that breakpoint (though the EIP will stay the same as you are not actually changing the flow of control of the program. double click the EIP register to go back to the current line set to execute next).

If you highlight a breakpoint and click the space bar, the breakpoint will toggle between enabled and disabled. You can also highlight a breakpoint row and hit “DEL” key which will remove the breakpoint.

Lastly, restart the program, go into the breakpoints window, highlight the breakpoint we set at address 401011, and hit the space bar. The “Active” column will change to “Disabled”. Now run the program (F9). You will notice that Olly did not stop at our BP because it was disabled.

Hardware Breakpoints

A hardware breakpoint uses the CPU’s debug registers. There are 8 of these registers built into the CPU, R0-R7. Even though there are 8 built into the chip, we can only use four of them. These can be used for breaking on reading, writing or executing a memory section. The difference between hardware and software breakpoints is hardware BP’s don’t change the process’s memory, so they can be more reliable, especially in programs that are packed or protected. You set a hardware breakpoint by right-clicking on the desired line, selecting Breakpoint, and then choosing Hardware, on Execution:

Setting Hardware breakpoints

The only way to see what memory BP’s you have set is to select “Debug” and “Hardware Breakpoints”. There is a plugin that will make this a lot easier, but we’ll discuss that later :)

Breakpoints

Memory Breakpoints

Sometimes you may find a string or a constant in the program’s memory, but you don’t know where in the program it is accessed. Using a memory breakpoint tells Olly that you want to pause whenever ANY instruction in the program reads or writes to that memory address (or groups of addresses.) There are three ways to select a memory breakpoint:

  • For an instruction, right-click on the desired line and select Breakpoint->Memory, On Access or Memory, On Write.
  • To set a BP on an address in the memory dump, highlight one or more bytes in the dump window, right-click on them and choose the same option as above.
  • You can also set a BP for an entire section of memory. Open the Memory window (“Me” icon or View->Memory), right click the section of memory you desire, and right-click and choose “Set Break On Access for either Access or Write.

Breakpoint on memory region

Using The Dump Pane

You can use the dump pane to inspect the contents of any memory location in the debugged process’s memory space. If an instruction in the disassembly window, a register, or any item in the stack contains a reference to a memory location, you can right click that reference and select “Follow in Dump” and the dump pane will show you the address section. You can also right-click anywhere in the dump pane and select “Go To” to enter an address to view. Let’s try it.

Make sure the FirstProgram is loaded and paused at the beginning. Now, press F8 eight time and we will be on the instruction at address 401021 that says CALL FirstPro.40102c. If you look at this line, you will notice that this call is going to jump us down to address 40102c, which happens to be 3 lines down from where we currently are. Hit F7 to step in to the jump and we will then be at that address at 40102c. Remember that this is a CALL instruction, so we will eventually come back to 401021 (or at least the instruction after this).

A CALL

Now, step the code (F8) until we get to address 401062. You can also just set a breakpoint on this line and hit F9 to run to it. Remember how to set a breakpoint? double-click on the opcode column on the line you want to set the BP. You can also just highlight the line and hit F2 to toggle the BP on and off). Now we are paused at address 401062:

Break at address

Now, let’s look at the line we are paused at. The instruction is MOV [LOCAL.3], FirstPro.00403009. As I’m sure you know (because you have been studying assembly language :p ) this instruction moves whatever is at address 00403009 onto the stack (which Olly references as LOCAL.3). You can see in the comments column that Olly has discovered that at this address is the ASCII string “MyMenu”. Well, let’s have a look. Right-click on the instruction and select “Follow in Dump”. You will notice that we have a couple options here:

Follow in Dump

In this case, select “Immediate Constant”. This loads whatever address is being affected in the instruction. If  you had chosen “Selection”, the dump window would have shown the address of the highlighted line, in this case 401062 (the line we were paused at). We would basically just be looking at a dump of what we were looking at in the disassembly window. Lastly, if we had chosen “Memory address”, the dump screen would show the memory for LOCAL.3. This would in effect show the memory for the local variables we were working with (on the stack). Here;s what the dump looks like after selecting Immediate Constant”:

Memory dump

As you can see, the dump now shows memory starting at address 403009, which is the address the instruction Olly was loading the ASCII string from. On the right, you can see the string, “MyMenu”. On the left, you can see the actual hex for each character. you may notice that after “MyMenu” are some additional strings. These strings will be used in other parts of the program.

Finally, Something Fun!

To end this part of the tutorial, let’s do something fun. Let’s edit the binary to display our own message! We will change  the “Dialog As Main” string to something of our own and then see what happens.

First, click on the “D” of “Dialog As Main” in the ASCII section of the dump window:

Clicking in dump pane

You will notice that the first hex digit is also highlighted on the left. This digit corresponds to the letter “D”. If you look it up on an ASCII chart you will see that the hex for the letter “D” is 0×44. Now, click and drag to select the entire string “Dialog As Main”:

Selecting memory

Now, right-click anywhere on the selection and choose “Binary” -> “Edit”. This allows us to change the memory contents of our program:

Binary editing

We should then have a screen that looks like this:

Binary edit screen

The first field shows us our string in ASCII. The second field is for Unicode (which this program doesn’t use, so the field is blank) and the last field is the raw data relating to this string. Now, let’s change it. Click on the first letter of the string (the “D”) and type anything you want over top of the “Dialog As Main” string. Just make sure you don’t add more letters than in the original string! You may overwrite other strings the program need, or worse, code that the program needs!!! In my case, I typed “Program R4ndom”:

Changing binary data

Now click OK and run the app (click inside Olly and hit F9). Switch over to our program, type something in and select “Options” -> “Get Text”. Now look at our dialog box!!!

The payoff

Notice anything different about the title of the dialog box :)

-till next time

R4ndom

Понравилась статья? Поделить с друзьями:
  • Диметилсульфоксид мазь инструкция по применению цена
  • Roland camm 1 gs 24 инструкция на русском
  • Мелаксен мелатонин 3 мг инструкция по применению взрослым
  • Газовая колонка электролюкс нано про инструкция по эксплуатации
  • Магний хелат солгар инструкция по применению