Ассемблер для начинающих / Хабр
В любом деле главное — начать. Или вот еще хорошая поговорка: «Начало — половина дела». Но иногда даже не знаешь как подступиться к интересующему вопросу. В связи с тем, что воспоминания мои еще свежи, спешу поделиться своими соображениями с интересующимися.
Скажу сразу, что лично я ассемблирую не под PC, а под микроконтроллеры. Но это не имеет большого значения, ибо (в отличие от микроконтроллеров AVR) система команд данных микроконтроллеров с PC крайне схожа. Да и, собственно говоря, ассемблер он и в Африке ассемблер.
Конечно, я не ставлю своей целью описать в этой статье всё необходимое от начала и до конца. Благо, по ассемблеру написано уже невообразимое число литературы. И да, мой опыт может отличаться от опыта других программистов, но я считаю не лишним изложить основную концепцию этого вопроса в моем понимании.
Для начала успокою любознательных новобранцев: ассемблер — это совсем не сложно, вопреки стереотипному мнению.
bset P2.0
И, как говорится, никаких проблем. Нужно включить сразу штуки четыре, подключенных последовательно? Да запросто:
mov P2, #000fh
Да, тут я подразумеваю, что начинающий боец уже знаком хотя бы со системами счисления. Ну хотя бы с десятичной. 😉
Итак, для достижения успеха в деле ассемблирования, следует разбираться в архитектуре (в моем случае) микроконтроллера. Это раз.
Кстати, одно из больных мест в познании архитектуры — это организация памяти. Тут на Хабре я видела соответствующую статью: habrahabr.ru/blogs/programming/128991. Еще могу упомянуть ключевые болевые точки: прерывания. Штука не сложная, но по началу (почему-то) тяжелая для восприятия.
Если перед вами стоит сложная задача и вы даже не знаете как по началу к ней подступиться, лучше всего написать алгоритм. Это воистину спасает. А по началу, даже если программа совершенно не сложная, лучше всё же начать с алгоритма, ибо этот процесс помогает разложить всё в голове по местам. Возвращаясь к примеру с вычислением двойного интеграла по экспериментальным данным, обдумывала алгоритм я весь день, но зато потом программку по нему написала всего за 20 минут. Плюс алгоритм будет полезен при дальнейшей модернизации и/или эксплуатации программы, а то ассемблерный код, временами, если и будет понятен построчно, то чтобы разобраться в чем же общая идея, придется немало потрудиться.
Итак, второй ключ к успеху — подробно написанный и хорошо продуманный алгоритм. Настоятельно рекомендую не садиться сразу за аппарат и писать программу. Ничего дельного вы с ходу не напишете. Это два.
Собственно, хотелось бы как Фандорин написать: «Это т-т-три»… Но, боюсь, на этом пока можно остановиться. Хотя хотелось бы добавить еще несколько рекомендаций и пряников.
Подводя итог моему несколько сумбурному монологу, ключевые моменты в программировании на ассемблере — это знание архитектуры и связное построение мыслей. Конечно, не обязательно сразу с головой кидаться в штудировании литературы с описанием внутренностей того же PC, но общее представление (повторюсь, хотя бы для начала) будет очень нужно.
А теперь обещанные пряники! Вот я тут распинаюсь о каком-то непонятном ассемблере, а что же в нем, собственно говоря, хорошего? Да много всего! Во-первых, конечно, не нужно запоминать много команд, используемых библиотек и прочей сопутствующей дребедени. Всего парочка команд и, считайте, вы во всеоружии. Во-вторых, в связи с крайней близостью к машинным кодам, вы можете делать практически всё, что душе угодно (в отличие от тех же языков высокого уровня)! В-третьих, ассемблерный код, по причине максимальной лаконичности в формулировках, выполняется крайне быстро.
В общем, сплошные плюсы. На этой оптимистической ноте разрешите откланяться.
Дневники чайника
Дневники чайника
— Так кто вы всё-таки будете?
— Асм есть Царь!
(Из кинофильма «Иван Васильевич меняет профессию»)
Благодарность
Я действительно благодарен всем моим читателям, особенно активным, вы мне очень помогли. Если бы не вы, этих уроков не было бы.
Также уроков могло не быть без Плохиша (Bad_guy, извини, что так назвал :). Он посадил зерно crackl@b’a на просторы инета и ухаживал за ним все эти годы, пока проект превращался в дерево знаний. Спасибо zer0 за управление разделом статей.
Спасибо всем участникам нашего форума и «wasm.ru/forum» за помощь и науку, особенно: Leo, S_T_A_S_,Staier, The Svin.
Ну и, конечно, отдельное спасибо Седому (SeDoYHg или SeDoY) за огромную помощь в написании Чтивы 0 и за критику первых статей. Я даже могу сказать, что почти все главы здесь под редакцией Седого.
Да, чуть не забыл, без моей мамы текст был бы полон «обшибак и слеганца бесграматен» :).
А без содействия папы вообще бы не стал заниматься Ассемблером (в бизнес бы ударился, стал бы авторитетом, шлёпнули бы где-нибудь у входа в казино — и контрольный выстрел… А так максимум, что светит, — это потёртые данные на винте и радикулит :).
Короче говоря, всем, кто помог, — спасибо.
Пустословие
Как был предусмотрителен Джордж Лукас, когда снял 4-й эпизод «Звёздных Войн». Я понятия не имел, что возникнет потребность написать предчасть. А вот пришлось. После того, как я написал «Чтиву III», прошло 4 месяца.
Дело в том, что первая часть начинается примерно c такой фразы: «Прочтите Рассылку Калашникова и возвращайтесь читать Дневники чайника». Сам дочитал эту рассылку только до десятого урока, дальше идёт морально устаревшая информация.
Надеюсь, что большинство из тех, кто созрел для Асма, поймёт мой рассказ (от 9 до 110 лет :). Если не поймёте, не отчаивайтесь, есть другие дороги. Давно существуют подобные курсы элементарного ликбеза, например:
- Уже упомянутая рассылка Олега Калашникова «Ассемблер? Это просто!» (устарела, зато сразу практика). Кстати, эта же рассылка на всякий случай лежит и здесь, на Краклабе.
- «Низкоуровневое программирование для дZенствующих». Сейчас считаю, что это хорошая дорога для начинающих, но когда сам ничего не знал, эти статьи мне не понравились. Решайте сами, подойдут ли они вам сразу. На том же сайте вы найдёте море материала по теме. Искренне благодарен всем, кто трудится над этим ресурсом.
- Советую в первую очередь обратить внимание на статьи Кибер Маньяка (CyberManiac) из серии «Теоретические основы крэкинга» в разделе статей здесь на Краклабе или на Wasm’e в этом разделе.
В любом случае советую прочесть все известные уроки. В каждом источнике автор по-своему раскладывает тему. Есть много мнений о том, какие аспекты самые важные, и каждая точка зрения для новичка — золото. Остальные интересные ссылки я уже поместил в следующих статьях, так что если вы пожелаете сначала завалиться литературой, а потом разгребать её, можете смело смотреть Чтиву 1,2,3.
Для кого пишу
Предполагается, что читатель не программист вообще, но опытный пользователь и у него есть желание стать настоящим хакером.
Совсм недавно не было никакого Битфрая, я вообще был далёк от программирования. Конечно, проводил много времени за компом и
Ещё хочу сказать, что не встречал ни одного человека, который разделил бы мою позицию:
самый лучший старт для программиста — это Ассемблер.
Хотя вру, такую точку зрения поддерживают некоторые уважаемые люди. Но явной мысли «начинать надо с Асма» нигде так и не увидил.
Других языков программирования не знаю, и от вас этого требовать не буду. Будет даже лучше, если вы ещё не испорчены такими вещами, как:
Print "Здесь был Вася"
В Ассемблере нет оператора «PRINT» и нет даже его подобия. Этот язык может показаться вам странным (как мне другие), если вы привыкли к логике высокоуровневых языков.
В данной статье за главный объект изучения будет принят язык Ассемблер для Intel-совместимых процессоров.
В принципе совершенно неважно, с чего начинать, когда объект полностью неизвестен, всё равно придётся ещё не раз возвращаться к первой выбранной теме.
Возможно, кто-то из вас сразу же предпочтёт прочитать большой учебник. Например:
В.И. Юров
«ASSEMBLER. 2-е издание. Учебник для вузов»
и учебник Зубкова в качестве интересных примеров для программирования (на форуме есть ссылки).
Не нужно искать в моей статье глубокие тайны программирования, и уж совсем не стоит считать Чтиву 0 истиной в последней инстанции.
Но если вы любите обрастать знаниями по ходу экспериментов (как Bitfry), добро пожаловать в мир ассемблера через мою «калитку».
Метод обучения
«Чтива 0» имеет мало общего со своими предками (Чтивы I,II,III), хотя бы потому, что это не мой дневник. Скорее, «Чтива 0» будет Ваш дневник, Ваши ошибки и Ваши уроки ;).
Говорят, «умный учится, глупый учит», если к этой поговорке прибавить мой скромный багаж знаний — я совсем дурак :). Только что начал и уже хочу научить вас думать логикой ассемблера. Ребячество — скажут многие. Но если бы я не верил в успешность предприятия (при некотором усилии с вашей стороны), даже и не стал бы тратить время.
Вы, наверное, согласитесь, что все знания в этой жизни приходят витками. Старые догадки и поступки кажутся ошибочными после каждого такого витка (в чтивах I,II,III полно ошибок).
Человеку для первого, невооружённого, осмотра местности, лучше думать, что земля плоская (поверьте, так будет лучше). Затем он осваивает всё больше и больше, а в какой-то момент до него вдруг доходит: чтобы сложить карты и сопоставить с положением звёзд на небе, нужно представить невероятное — земля, оказывается, шар. Но и это не есть истина, на самом деле земля очень сложной формы, и чтобы описать её более-менее точно, нужно использовать все ресурсы науки и техники. Конца этому процессу не предвидится. То же самое можно сказать и о компьютере. Несмотря на то, что он всего лишь юное творение человека, мы умудрились запутать в нём столько всяких абстракций (которые ему, кстати, мешают), что Ассемблер можно уже воспринимать как насмешку над корнем этого слова.
Сделаю всё возможное, чтоб избежать сложных понятий, также обещаю не допускать тупостей вроде «земля круглая», так как это больше всего сбивает с толку, уж лучше думать, что она плоская, чем круглая :), по крайней мере, я буду стараться так не писать.
Но вернёмся к виткам познаний. В Чтиве 0 мы с вами постараемся смоделировать два таких витка (пока мне так кажется, может быть, их будет больше).
Нулевой виток будет содержать много практики и некоторое количество утверждений.
Первый будет состоять из ответов на главные вопросы, которые, надеюсь, у вас возникнут. Но это не значит, что там не будет практических примеров, наоборот, все самые интересные фокусы прячутся во втором витке.
Таким образом, обе части нулевой чтивы будут иметь одинаковые темы глав.
Вступление в суть День первый Системы счисления и устройство памяти День второй Регистры процессора День третий Практикация всего мозга День четвёртый О словах и двойных словах (форматы данных) День пятый Циклы, ветвления и регистр Флагов День шестой Знакомство с Win32-программированием День седьмой Стек День восьмой Структурирование программы День девятый
Пару слов об оформлении
Статья получилась длинная и пёстрая, поэтому вам лучше сразу знать что как будет выглядеть. Кроме основного текста, вы здесь встретите:Выделения, как обычно — суть из массы
— Сноски в конце главы
Код программ
Код исходников программ
Действия примера |
Cравка о командах процессора |
Ну и в этих серых блоках будет развлекуха, её читать совсем необязательно, поэтому с неё и начнём :).
Эй, малыш! Да, ты… Можешь раздобыть некоторый скарб для моего корабля?…
Инструменты, которые нам пригодятся
…Ну, что ж, спасибо за помощь. Ты вроде здесь просто так околачиваешься, а у меня на борту как раз юнги не хватает…
Перед отправлением в дальний поход необходимо как следует проверить укомплектованность нашего космического корабля.
Поскольку миссия разведывательная, а корабль лёгкого класса, приспособления мы будем подбирать тщательно, чтобы сократить лишнй вес и расходы. Всё наше снаряжение очень скромное по размеру, но могучее по возможностям.
Для начала посмотрите приложенные файлы: need.rar, prax0.rar, prax1.rar, общий размер ~500Kb. Там лежат примеры для проверки их работоспособности и кое-что ещё.
Hiew
Сайт программы, размер ~0,5Mb. Программа платная.
Версия должна быть для форточек не ниже 6.8 (я использую 7.01).
Если у вас нет этой программы, то в сети вы без проблем найдете её.
Heiw — это консольный шестнадцатиричный редактор с возможностью ассемблировать/дизассемблировать. Незаменимая для исследователей и ассемблерщиков вещь.
FAR manager
Сайт программы, размер ~3Mb. Программа бесплатная для русскоязычных пользователей.
Подойдёт и новая x64-версия 2.0 и 32-битная. Короче – любая. Порекомендовал бы использовать именно FAR, так как он тоже консольный. Сам я пользуюсь двумя файловыми менеджерами: Total Commander и Far. По опыту могу сказать, что Far можно настроить по сочетанию клавиш один в один с TC, было бы желание. Внешний вид настраивается до мелочей, просто на это надо потратить некоторое время. Far будет приятным и удобным если вы этого захотите, поверьте. Меня, например, дико раздражают мелкие шрифты и кислотные краски стандартной консоли (что Hiew, что Far, что любая другая цветная консольная программа), однако, всегда можно создать ярлычок в котором будут настройки шрифтов и палитра приятная для глаза. Ярлык для Far’a с моими любимыми цветами я прикрепил в файл need.rar. Кроме того можно настроить цветовую схему. Hiew и Far имеют богатые возможности в этом плане. Пробуйте. Однако если вам совсем не нравятся консоли, можете использовать что-то типа TC или обычный проводник.
CodeView (CV)
Сайт программы: microsoft.com. В принципе программа доступна для бесплатного скачивания где-то в дебрях Майкрософта, однако она является лишь придатком к довольно большому ненужному пакету, который входит в дополнение (не помню к чему). Отыскать её там будет непросто. Я выложил эту довольно старую программу у себя (в том же архиве need. rar).
Ещё CV входит в старый MASM (v5x,v6x) который входит в VisualC++ (версии не знаю).
CodeView — программа-отладчик (по-ихнему debugger — исправлятель ошибок). Отладчики помогают программистам понять, что делает их программа. 🙂 Когда этот светлый миг наступает, становится понятно, где ошибка.
Немалую часть времени написания программы программист проводит в отладчике, поэтому выбор дебагера — очень больной вопрос. Я остановился на CodeView, потому что не смог подобрать другого отладчика для первых шести примеров. Однако слишком погружаться в CV не стоит, так как он устарел и в реальной практике вряд ли вам пригодится.
OllyDbg
Сайт программы, размер ~1Mb. Программой можно пользоваться бесплатно с разрешения автора.
На 07.12.2011 последняя версия Oлли — 2.01 alpha 4, но можно использовать и старую стабильную 1.10.
А вот этот отладчик на сегодняшний день самый актуальный на платформах вплоть до Win7 x64 на уровне 32-битных приложений. OllyDbg — самый многофункциональный отладчик прикладных программ Win32. Но как только появится хороший подходящий для нас отладчик x64, сразу возьмусь переписывать уроки под него.
MASM32 SDK
Сайт программы, размер ~4Mb. Программа бесплатная.
Проект Стива Хатчисона (Steve Hutchesson). MASM32 – это современный пакет языка Ассемблер, собранный на основе компилятора MicroSoft.
Существует ещё пакет MASM (Macro Assembler) — это древний DOS’овый пакет от самой MS. Нам он не нужен, так же как и NASM, TASM, TASM32 и т.д.
На сегодняшний день единственной разумной альтернативой MASM32 является FASM. Сам я использую и FASM, и MASM32, но тему FASM’a затрагивать пока не будем.
Что такое «пакет языка Ассемблер»?
В стандартный пакет языка программирования входят:
- компилятор и линковщик (чтоб превращать исходные файлы в программу),
- документация (чтоб описать возможности пакета, собственные директивы, макросредства и т. д.),
- редактор исходных частей программы (как правило, вещь бесполезная, все пользуются любимыми текстовыми редакторами),
- различные дополнения и заготовки (чтоб облегчить рутинный труд),
- ну и, конечно, примеры.
Всё это нам понадобится не сразу, а постепенно, по мере необходимости. Поэтому не бросайтесь сейчас же изучать и осваивать все вышеперечисленные приборы. Однако Hiew и CodeView нужны будут сразу же после вылета с базовой станции.
На Windows версии x64 (7/Vista/XP или Server) в первые дни вам понадобится какой-нибудь эмулятор DOS-режима для запуска com-программ. Можно использовать громоздкий Virtual PC от MS или VMWare, но я предлагаю (спасибо Григорию за подсказку) маленький удобный эмулятор:
DOSbox
Сайт программы, размер ~1,5Mb. Программа бесплатная.
Без этой программы можно обойтись на 32-битной WinXP. На Висте и Семёрке x86 лично не проверял, но говорят, можно обойтись режимом совместимости (пробуйте и отпишитесь в гостевой по результатам).
Не смущайтесь, что версия называется «Win32 installer», она поможет и на системе x86, и на x64 эмулировать режим старой-доброй DOS для наших первых примеров. DOSbox устанавливается за пару секунд, и его очень легко настроить. Нужно всего лишь смонтировать папку с com-примерами и туда же кинуть все файлы отладчика CV. Монтаж выполняется одной командой. Например:
mount с d:\prax
где «d:\prax » – это папка на реальном диске D, в которой должны быть свалены воедино ваши com-примеры и файлы отладчика CV. А «c» – это уже виртуальный диск внутри dosbox’a.
Далее переходим на новый виртуальный диск командой
с:
Что потом – читайте уже в следующей главе. Можно, кстати, батничек сделать… Разумеется, надо знать основы языка команд DOS и DOSbox (на сайте программы есть русская документация). Сразу рекомендую главу специально для пользователей, впервые очутившихся в DOS-мире.
Инструменты, которые нам НЕ пригодятся.
Молоток, кувалда, бензопила и другие приспособления, которые, возможно, вы захотите применить в первые дни полёта. Адаптация к условиям невесомости проходит у многих крайне тяжело. Возможны потеря ориентации, головокружения и прочие побочные эффекты. Уберите подальше от компьютера тяжёлые и твёрдые предметы — компьютер не виноват, это всего лишь машина.
Кажется, можно отправляться.
Ещё раз повторю, виток0 нужен только для того, чтоб у вас возникли вопросы, я вовсе не предполагаю, что вы поймёте всё и сразу.
Можно сравнить эту часть с детским мультиком — все бегают-прыгают, яркие картинки, сплошные перегибы и упрощения.
Bitfry
Ускоренный курс по языку ассемблера | Мадлен Фарина | Обратный инжиниринг для чайников
Основы сборки x86 для обратного инжиниринга
Если вы занимаетесь каким-либо реинжинирингом — и под этим я подразумеваю дизассемблирование скомпилированного исполняемого файла с помощью таких инструментов, как Ghidra, для анализа машинного кода — тогда вы должны знать язык ассемблера. Если у вас есть интерес к этой области, вы, вероятно, уже слышали об ассемблере и знаете, что у него менее любимая (возможно, даже презираемая) репутация, но это не обязательно означает, что его трудно изучить.
Это не стандартный язык программирования, такой как Python или Java. Это оба высокоуровневых языка , а x86 и ARM Assembly — низкоуровневого . Это означает, что их может быть намного сложнее понять, и они включают работу с регистрами в памяти для выполнения задач. Языки высокого уровня легче понять программисту, в то время как компьютеру легче интерпретировать язык низкого уровня, также известный как машинный язык. Расхождений конечно больше (о них можно прочитать здесь), но это самое основное различие между ними.
Когда я впервые изучил ассемблирование для одного из моих обязательных курсов CS, я нашел его… мягко говоря, сложным. Было чертовски неприятно кодировать простые проекты, такие как калькулятор с четырьмя функциями или алгоритм GCD, в ARM v8. Мало того, что синтаксис был туманным и ошеломляющим, мне приходилось выполнять все кодирование и тестирование либо с помощью эмулятора, либо работая в терминале, подключенном к компьютерной плате Firefly ROC-RK3328-CC, подключенной к моему ноутбуку. Мне не привыкать работать в командной строке, но когда дело доходит до кодирования проектов, мне проще работать в IDE только из-за большого количества кода, с которым мне приходится работать.
(оглядываясь назад, я бы использовал функцию ssh в Visual Studio Code для подключения к моему Firefly, но тем не менее)
Из всего сказанного можно сделать вывод, что изучение, вероятно, будет раздражающим, и это нормально. Пока вы продолжаете практиковаться и изучать учебные материалы, такие как этот пост, вы освоитесь с ним достаточно, чтобы начать реверс-инжиниринг.
Чтобы лучше понять, как все работает, давайте взглянем на схему ниже.
Источник: http://faculty.cs.niu.edu/~mcmahon/CS241/Images/compile.pngЕсли вы когда-либо занимались разработкой на C++, вы знаете, что файл . cpp содержит код программиста, и вы должны скомпилировать его, чтобы получить выходной файл (.o). Эти файлы имеют объектный код, который представляет собой программы на машинном языке, содержащие код операции (код операции), который является инструкциями для компьютера. Интересно, что вредоносное ПО часто представляют в виде объектного кода, поэтому для понимания опкода необходим реверс-инжиниринг. Одной из целей RE является преобразование объектного кода в язык ассемблера в процессе дизассемблирования.
Итак, теперь, когда у вас есть общее представление о потоке программы, давайте взглянем на ассемблер.
Если вы заметили, я упомянул как сборку x86, так и сборку ARM v8. На самом деле разница есть, поскольку на самом деле существует несколько разных архитектур (и последующих «разновидностей») сборки. x86 является одним из наиболее распространенных языков ассемблера, его архитектура имеет как 32-разрядные, так и 64-разрядные версии, а его синтаксис основан либо на AT&T, либо на базе Intel. Другими словами, большинство компьютеров Intel используют сборку x86. Различия в синтаксисе включают порядок операндов, регистровые и непосредственные префиксы, суффиксы, указывающие размер операнда, и так далее.
Версии ARM похожи (это не то же самое, что сравнивать яблоки и апельсины), но отличаются тем, что ARM — это RISC-архитектура, а x86 — CISC (подробнее см. здесь). Инструкции ARM имеют встроенные условные флаги, что позволяет избежать всех тех прыжков вокруг одной или двух инструкций, которые вы часто видите в сборке Intel, а ARM не может напрямую делать с памятью ничего, кроме загрузки из нее и сохранения в нее. Сборка Intel может выполнять больше операций непосредственно с памятью.
В оставшейся части этого объяснения мы будем ссылаться на сборку x86.
Источник: http://users.cis.fiu.edu/~prabakar/cda4101/Common/notes/lecture04.htmlПроцессоры могут быть либо с прямым порядком байтов, либо с прямым порядком байтов. байт в слове памяти. Системы с прямым порядком байтов сохраняют старший значащий байт (MSB) по наименьшему адресу памяти, а младший значащий байт (LSB) — по наибольшему. И наоборот, системы с прямым порядком байтов хранят LSB по наименьшему адресу памяти и наоборот. На самом деле большинство процессоров имеют обратный порядок байтов, потому что это означает использование меньшего количества цепей, в то время как большинство сетевых протоколов имеют обратный порядок байтов, потому что он лучше подходит для передачи информации по одному биту за раз.
Необходимо понимание прямого и прямого порядка байтов, потому что это помогает понять, как данные хранятся в стеке в памяти. Знайте, что на компьютерах Intel байты хранятся с прямым порядком байтов.
Кроме того, забавный факт: полубайтовое (4-битное) значение называется полубайтом!
Архитектура x86 имеет 8 регистров общего назначения (GPR), 6 регистров сегментов, 1 регистр флагов и указатель инструкций для 32-разрядной архитектуры x86.
Источник: https://www.cs.virginia.edu/~evans/cs216/guides/x86.htmlEAX — Сохраняет возвращаемые значения функции
EBX — Базовый указатель на раздел данных
ECX — Счетчик строковых и циклических операций ESI — Указатель источника для строковых операций
EDI — Указатель назначения для строковых операций
ESP — Указатель стека
EBP — Базовый указатель кадра стека
EIP — Указатель на следующую команду для выполнения («указатель инструкции»), не может быть изменен напрямую с помощью mov , но может быть изменен косвенно путем обращения к операциям
Регистры общего назначения используются для основных арифметических и операции. Регистры указателей используются для указания на память для управления программой.
Флаги и регистры сегментов
CS — Указатель на сегмент кода, в котором выполняется ваша программа
DS — Указатель на сегмент данных, к которому обращается ваша программа
ES,FS,GS — Дополнительные регистры сегментов, доступные для дальней адресации указателя, например видеопамяти
SS — Указатель на сегмент стека, который использует ваша программа.
OF — Флаг переполнения, используется, если место назначения не может сохранить весь результат операция 0
Простые инструкции
mov — перемещает дату из одного места в другое без изменений в виде:
mov пункт назначения, источник
lea — загружает эффективный адрес, вычисляет косвенный адрес и сохраняет адрес ( не содержимое памяти) в приемнике
lea приемник, значение
jmp — указывает процессору перейти в новое место, передает поток выполнения путем изменения регистра указателя команд
jmp назначение
добавить — арифметическое сложение, прибавляет указанное значение к значению, хранящемуся в месте назначения, и заменяет место назначения результатом аналогично добавлению
суб назначение, значение
вкл. — увеличивает назначение на 1
вкл. назначение
dec — уменьшает назначение на 1
dec назначение
Существуют также логические операции, такие как или , и и xor , которые имеют те же режимы адресации, что и
9 sub 1.0
9 и
0 add0Адресация
В то время как для некоторых инструкций на ассемблере не требуется операнд, для других требуется один или несколько, а когда для инструкции требуется два операнда, источником является второй операнд. Источник содержит либо данные, которые должны быть доставлены, либо адрес (в регистре или памяти) данных. Адресация происходит с помощью сегментных регистров и имеет три разных режима: адресация регистров, немедленная адресация (когда данные, которые должны быть доставлены, находятся в источнике инструкции), адресация регистров и памяти (когда источник содержит адрес данных).
И, говоря об адресации, важно знать об адресе возврата , который является параметром, который сообщает функции, где возобновить выполнение после завершения функции. Это необходимо, потому что функции можно вызывать для выполнения обработки из многих разных частей программы, и функция должна иметь возможность вернуться туда, откуда она была вызвана.
Каждый вызов активной функции имеет фрейм, в котором хранятся значения всех локальных переменных, а фреймы всех активных функций хранятся в стеке. Стек — очень важная структура данных в памяти. Как правило, он используется для хранения временных данных, необходимых во время выполнения программы, таких как локальные переменные и параметры, адреса возврата функций и т. д. Это статическая память, то есть ее нельзя изменить во время выполнения. Динамическая память, подобная той, что выделена с помощью malloc() или new() функций хранятся в куче. Я расскажу о стеке и куче в своем следующем посте, но сейчас мы сосредоточимся только на стеке.
Как и стопка блинов, стек в памяти имеет порядок «последним пришел — первым обслужен» (LIFO), что означает, что объекты на вершине стека извлекаются первыми. И хотя это странно, в x86 стек растет вниз от старших адресов к младшим. Что касается сборки, вы можете найти некоторые из наиболее распространенных инструкций стека ниже.
Инструкции стека
push value
Это уменьшает ESP на количество байтов, занимаемых значением, и копирует значение по адресу, не относящемуся к ESP.
pop назначение
Это копирует байты в памяти из адреса ESP в место назначения, затем увеличивает ESP на размер места назначения.
Теперь о некоторых необычных инструкциях стека, которые часто используются вредоносными программами (важно, если вы собираетесь отменить любые подозрительные программы):
pusha — Помещает в стек 16-битные значения регистров AX, CX, DX, BX, SP, BP, SI, DI
pushad — помещает 32-битные значения регистров EAX, ECX, EDX EBX, ESP, EBP, ESI, EDI в стек
popa — обратная операция pusha
popad — обратная операция pushad
Надеюсь, вы знаете и имеете общее представление о сборке в хорошей отправной точке, чтобы на самом деле изучить тонкости языка. Как и все, это становится легче с практикой. Я включил несколько ссылок ниже, которые помогут вам в вашем путешествии.
Ссылки:
https://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture
Денис Юричев, Реверс-инжиниринг для начинающих , https://beginners.re/RE4B-EN.pdf
5
5 Майкл Сикорски, Эндрю Хониг, Практический анализ вредоносных программ: Практическое руководство по анализу вредоносного программного обеспечения , (2012)
Основы языка ассемблера | Cybrary
Язык ассемблера — это язык программирования низкого уровня, предназначенный для прямого взаимодействия с аппаратным обеспечением машины. Языки компьютерного программирования могут быть языками высокого или низкого уровня. Основное отличие состоит в том, что язык программирования высокого уровня более удобен для программиста, а это означает, что его гораздо легче понять, чем язык низкого уровня. Однако он также менее эффективен с точки зрения использования памяти, поскольку работает на более высоком уровне абстракции. Он не предназначен для прямого взаимодействия с аппаратным обеспечением компьютера и требует компилятора или интерпретатора для перевода.
Для сравнения, язык ассемблера более удобен для машин; его труднее понять людям, но он предлагает больше контроля, позволяя более эффективно использовать память. Для перевода нужен ассемблер, а не компилятор или интерпретатор. Сегодня языки программирования высокого уровня пользуются гораздо большей популярностью. Тем не менее, кибербезопасность — это несколько областей, где изучение языка низкого уровня, такого как язык ассемблера, по-прежнему чрезвычайно ценно. В первую очередь это касается анализа вредоносных программ. Именно здесь специалисты по кибербезопасности берут образцы вредоносных программ и разбивают их на язык ассемблера, чтобы определить, что делает вредоносное ПО, и, надеюсь, как вы можете его остановить.
Почему язык ассемблера важен для анализа вредоносных программ?
Всякий раз, когда создается вредоносное ПО, автор обычно использует процесс, называемый запутыванием, чтобы другие люди не могли прочитать код вредоносного ПО и понять, как оно работает. При обнаружении образца вредоносного ПО аналитики используют ollydbg или IDA pro, чтобы разбить программу на компоненты языка ассемблера. С этого момента вы поймете, что делает программа и, в конце концов, как вы можете остановить ее распространение или обнаружить ее на машине. Это делается путем определения индикаторы компрометации (IOC), которые являются важными способами обнаружения вируса, уникального для этой программы. Примерами IOC являются имена файлов, IP-адреса, к которым обращается программа, каталоги файлов, которые она сохраняет сама, и т. д.
Начните с онлайн-курса «Ассемблирование» сегодня >>
Как работает язык ассемблера?
Ранее было заявлено, что языки низкого уровня не предоставляют абстракции или почти не предоставляют ее. Это означает абстракцию от процессора. Когда вы пишете что-то на языке ассемблера, вы отдаете команды непосредственно процессору компьютера. Современные языки ассемблера обычно кодируют программы на ассемблере, которые преобразуются в машинный код, который является единственным типом языка программирования, который машина понимает без обработки. Вот пример того, как выглядит машинный код в двоичной форме:
Источник @ secjuice
Давайте посмотрим на некоторые компоненты языка ассемблера и на то, как они преобразуются в машинный код.
Что такое мнемоника?
Мнемоника — это имя, присвоенное машинной функции или аббревиатуре операции на языке ассемблера . Каждая мнемоника представляет машинную инструкцию на ассемблере. В приведенном выше примере add является примером одной из этих машинных инструкций. Некоторые другие примеры включают mul, lea, CMP, и и .
Что такое регистры?
Регистры в ассемблере можно сравнить с глобальными переменными, используемыми в языках программирования более высокого уровня, таких как Python или C . Существует три основных типа регистров:
- Общего назначения: Eax, Ebx, Esp, Ebp
- Сегмент: CS, CD
- Управление: EIP
Эти регистры могут хранить определенный объем данных и определенный тип данных. Например:
EAX — регистр-накопитель — используется для хранения операндов и данных результатов. Он может хранить 32 бита данных.
EBX- Базовый регистр — Указывает на данные. Может хранить 32 бита данных.
ECX — регистр счетчика — операции цикла. Может хранить 32 бита данных.
Что происходит с данными, которые не помещаются в регистры?
В языке ассемблера любые данные, которые не помещаются в регистры, хранятся в памяти компьютера. Это происходит потому, что регистры позволяют наиболее быстро извлекать данные. Следовательно, вы хотите хранить как можно больше данных в регистрах и хранить только то, что осталось в памяти, где скорость извлечения будет медленнее. Ниже приведена диаграмма, изображающая иерархию памяти компьютера:
Источник @ secjuice
Как видите, самое быстрое место для хранения находится вверху, но оно также и самое маленькое, когда дело доходит до емкости. Размер резко увеличивается, продвигаясь вниз по иерархии, но и становится медленнее.
Обычно данные хранятся в памяти в двух типах данных: с прямым порядком байтов или с прямым порядком байтов. Хранилище данных с прямым порядком байтов обычно используется, когда основное внимание уделяется скорости обработки, а не количеству потребляемой мощности, что отлично подходит для ноутбуков и компьютеров и обычно используется для процессов Intel. Пока big-endian обычно используется в процессорах ARM, используемых для мобильных устройств, и отдает приоритет энергоэффективности.
Как выучить язык ассемблера
К сожалению, у языка ассемблера не так много ресурсов для изучения, как у языков программирования высокого уровня. Это просто потому, что большая часть программирования выполняется на языках более высокого уровня, поэтому нет большой потребности в изучении ассемблера за пределами узкоспециализированных специальностей. Если вы заинтересованы в изучении программирования на ассемблере, есть несколько хороших вариантов, в том числе Udemy, tutorialspoint и Курс программирования на языке ассемблера Cybrary . Как и в случае с большинством языков программирования, лучший способ учиться — это целенаправленная практика, чтение и изучение. Если вы заинтересованы в изучении ассемблера для кибербезопасности, особенно в анализе вредоносных программ, вам следует ознакомиться с инструментами ollydbg и IDA pro . Это два ведущих инструмента для анализа вредоносных программ и преобразования файлов .exe в ассемблерный код. Вы можете загрузить эти инструменты по отдельности или загрузить дистрибутив Windows под названием 9.0251 Факел ВМ . Этот дистрибутив, ориентированный на безопасность, был создан FireEye и предназначен для обратного проектирования, аналитиков вредоносных программ, специалистов по реагированию на инциденты, судебных следователей и пентестеров. Что касается языка ассемблера, для начала я рекомендую X86, а затем ARM. Это два самых популярных языка ассемблера, X86 используется для процессоров Intel, а ARM в основном используется в мобильных устройствах, таких как сотовые телефоны.