Учебное собрание [закрыто]

102

Решил выучить ассемблер. Основная причина для этого - способность понимать дизассемблированный код и, возможно, возможность писать более эффективные части кода (например, через c ++), делать что-то вроде пещер кода и т. Д. Я видел, что существует миллион различных вариантов сборки Итак, с чего начать? Какую сборку учить? Я хочу научиться, сначала выполнив несколько простых программ (например, калькулятор), но сама цель будет состоять в том, чтобы привыкнуть к нему, чтобы я мог понять код, показанный, например, IDA Pro.

Я использую окна (если это имеет значение).

edit: Итак, кажется, все указывают на MASM. Хотя я понимаю, что у него есть возможности высокого уровня, и все это хорошо для программиста кода сборки, это не то, что я ищу. Кажется, есть инструкции if, invoke и т. Д., Не показанные в популярных дизассемблерах (например, IDA). Так что, если возможно, я хотел бы услышать мнение всех, кто использует ASM для тех целей, о которых я прошу (чтение деассемблированного кода exe в IDA), а не только «общих» программистов на ассемблере.

редактировать: ОК. Уже учусь сборке. Я изучаю MASM, а не использую вещи высокого уровня, которые для меня не важны. Сейчас я пробую свой код в директивах __asm ​​в C ++, поэтому я могу попробовать что-то гораздо быстрее, чем если бы мне пришлось делать все с нуля с помощью MASM.

пожрал элизиум
источник
Аналогичный вопрос на stackoverflow.com/questions/1355524/…
TrueWill 01
Да, я тоже читал это. Но я бы сказал, что мой вопрос более «сфокусированный».
пожрал элизиум 01
Если вы используете Windows, целью (то есть процессором и, следовательно, набором инструкций) является x86 или x86-64. Если вы не получите другую машину или плату MCU или не используете эмулятор. Итак, возникает вопрос, какой ассемблер мне использовать? Или вы действительно спрашиваете, на какую архитектуру ориентироваться? Лично мне нравится красивый ортогональный набор инструкций на микросхемах серии m68k, увы, ах.
dmckee --- котенок экс-модератора
2
«Кажется, есть инструкции if, invoke и т. Д.» - это макросы («M» в «MASM»), и вам не нужно их использовать, даже если ассемблер их поддерживает.
ChrisW,
3
Было непросто дать этому вопросу 65-е место, 64 - такое красивое число. . .
735Tesla

Ответы:

40

Начните с MASM32, а оттуда посмотрите на FASM . Но вы получите удовольствие от MASM.

Полдень шелк
источник
Я слышал от MASM. Если я не ошибаюсь, в нем есть много "высокоуровневых" функций, которых я не вижу, когда смотрю на разобранный код. Я хотел бы иметь возможность программировать что-то в точности как код вывода большинства дизассемблеров, если это имеет смысл.
пожрал элизиум 01
1
По сути, это было бы похоже на написание кодов операций, что на самом деле не имеет смысла. Изучение MASM32 поможет вам понять, как выглядит код в отладчике. Вы также можете посетить
Noon Silk,
7
Вы не понимаете сборки. Вам нужно это понять. Код операции - это число. Отладчики будут пытаться разрешить коды операций своим инструкциям (иногда это сложно). Вам необходимо понять основные инструкции. Изучение MASM поможет вам в этом. Больше говорить не о чем.
Noon Silk
5
Вам не обязательно использовать все функции MASM только потому, что они есть; вы можете сделать вещи настолько трудными для чтения, насколько захотите, если вы думаете, что таким образом вы узнаете больше.
JasonTrue
3
MASM с его причудами, ошибками и так называемыми высокоуровневыми функциями сделал больше, чтобы запутать программистов на ассемблере - как новичков, так и экспертов - больше, чем все, о чем я могу думать.
Эй Джей Кеннеди
46

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

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

1) узнать набор инструкций для конкретного процессора

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

3) вы изучаете набор инструкций лучше, чем большинство инженеров, которые используют этот набор инструкций для заработка

В вашем случае есть пара проблем, я обычно рекомендую для начала использовать набор инструкций ARM, сегодня поставлено больше продуктов на базе ARM, чем любых других (включая компьютеры x86). Но вероятность того, что вы используете ARM сейчас и не знаете достаточно ассемблера для написания кода запуска или других подпрограмм, зная, что ARM может помочь или не помочь в том, что вы пытаетесь сделать. Вторая и более важная причина использования ARM в первую очередь заключается в том, что длины инструкций имеют фиксированный размер и выровнены. Дизассемблирование инструкций переменной длины, таких как x86, может быть кошмаром для вашего первого проекта, и цель здесь - изучить набор инструкций, а не создавать исследовательский проект. Третий ARM - это хорошо сделанный набор инструкций, регистры созданы равными и не имеют индивидуальных особенностей.

Так что вам нужно будет выяснить, с какого процессора вы хотите начать. Я предлагаю сначала msp430 или ARM, затем ARM или вторую, а затем хаос x86. Независимо от того, какая платформа, любая платформа, которую стоит использовать, имеет таблицы данных или справочные руководства для программистов, свободные от поставщика, которые включают набор инструкций, а также кодирование кодов операций (биты и байты машинного языка). Чтобы узнать, что делает компилятор и как писать код, с которым компилятору не приходится бороться, хорошо знать несколько наборов инструкций и посмотреть, как один и тот же высокоуровневый код реализуется в каждом наборе инструкций с каждым компилятором при каждой оптимизации. настройка. Вы не хотите заниматься оптимизацией своего кода только для того, чтобы обнаружить, что вы сделали его лучше для одного компилятора / платформы, но намного хуже для каждого другого.

О, для дизассемблирования наборов инструкций переменной длины, вместо того, чтобы просто начинать с начала и дизассемблировать каждое четырехбайтовое слово линейно через память, как в случае с ARM, или каждые два байта, например, msp430 (msp430 имеет инструкции переменной длины, но вы все равно можете обойтись происходит линейно через память, если вы начинаете с точек входа из таблицы векторов прерываний). Для переменной длины вы хотите найти точку входа на основе таблицы векторов или информации о том, как загружается процессор, и следовать коду в порядке выполнения. Вы должны полностью декодировать каждую инструкцию, чтобы знать, сколько байтов используется, тогда, если инструкция не является безусловным переходом, предположите, что следующий после этой инструкции байт является другой инструкцией. Вы также должны сохранить все возможные адреса ветвей и предположить, что это адреса начальных байтов для получения дополнительных инструкций. Однажды, когда мне это удалось, я сделал несколько проходов через двоичный файл. Начиная с точки входа, я пометил этот байт как начало инструкции, затем линейно декодировал через память, пока не попал в безусловный переход. Все цели ветвления были помечены как начальные адреса инструкции. Я сделал несколько проходов через двоичный файл, пока не нашел новых целей ветвления. Если в любое время вы найдете, скажем, 3-байтовую инструкцию, но по какой-то причине вы пометили второй байт как начало инструкции, у вас есть проблема. Если код был сгенерирован компилятором высокого уровня, этого не должно происходить, если компилятор не делает что-то плохое, Если в коде написан от руки ассемблер (например, в старой аркадной игре), вполне возможно, что будут условные переходы, которые никогда не могут произойти, например, r0 = 0, за которым следует переход, если не ноль. Возможно, вам придется вручную отредактировать их из двоичного файла, чтобы продолжить. Для ваших непосредственных целей, которые, как я полагаю, будут на x86, я не думаю, что у вас возникнет проблема.

Я рекомендую инструменты gcc, mingw32 - это простой способ использовать инструменты gcc в Windows, если ваша цель x86. Если не mingw32 plus, то msys - отличная платформа для создания кросс-компилятора из источников binutils и gcc (как правило, довольно просто). mingw32 имеет некоторые преимущества перед cygwin, например, значительно более быстрые программы и вы избегаете ада cygwin dll. gcc и binutils позволят вам писать на C или ассемблере и дизассемблировать ваш код, и существует больше веб-страниц, чем вы можете прочитать, показывая вам, как сделать один или все три. Если вы собираетесь делать это с набором инструкций переменной длины, я настоятельно рекомендую вам использовать набор инструментов, который включает дизассемблер. Например, сторонний дизассемблер для x86 будет сложной задачей, поскольку вы никогда не знаете, правильно ли он разобрался. Некоторые из них также зависят от операционной системы, цель состоит в том, чтобы скомпилировать модули в двоичный формат, который содержит инструкции маркировки информации из данных, чтобы дизассемблер мог выполнять более точную работу. Другой вариант для этой основной цели - иметь инструмент, который может компилироваться непосредственно в ассемблер для вашей проверки, а затем надеяться, что при компиляции в двоичный формат он создаст те же инструкции.

Краткий (ладно, чуть короче) ответ на ваш вопрос. Напишите дизассемблер, чтобы изучить набор инструкций. Я бы начал с чего-то РИСКОГО и простого в освоении, например, ARM. Как только вы узнаете, что один набор инструкций, другие становится намного проще подобрать, часто через несколько часов, с помощью третьего набора инструкций вы можете начать писать код почти сразу, используя таблицу данных / справочное руководство по синтаксису. Все процессоры, которые стоит использовать, имеют техническое описание или справочное руководство, в котором инструкции описаны вплоть до битов и байтов кодов операций. Изучите RISC-процессор, такой как ARM, и CISC, такой как x86, в достаточной степени, чтобы почувствовать различия, такие как необходимость проходить через регистры для всего или иметь возможность выполнять операции непосредственно в памяти с меньшим количеством регистров или без них. Три инструкции операнда вместо двух и т. Д. Когда вы настраиваете свой код высокого уровня, скомпилировать для более чем одного процессора и сравнить результат. Самая важная вещь, которую вы узнаете, заключается в том, что независимо от того, насколько хорошо написан высокоуровневый код, качество компилятора и сделанный выбор оптимизации имеют огромное значение для реальных инструкций. Я рекомендую llvm и gcc (с binutils), ни один из них не производитотличный код, но они многоплатформенные и многоцелевые, и оба имеют оптимизаторы. И оба они бесплатны, и вы можете легко создавать кросс-компиляторы из исходных кодов для различных целевых процессоров.

Старожил
источник
Спасибо за ответ. Но я даже не умею писать дизассемблер.
пожрал элизиум 01
8
«Напиши свой дизассемблер» - согласен, так я научился лучше всего. (Что случилось с «Но я даже не умею писать дизассемблер»?) LOL.
slashmais
Я пойду с тобой! Только что купил MSP430 и книгу по нему ... :)
Пепе
1
У меня есть несколько примеров msp430 github.com/dwelch67 плюс несколько симуляторов наборов инструкций для экспериментов, включая обучение asm и т. Д.
old_timer 01
Мне очень, очень нравится эта идея.
Милли Смит
34

Сборка, которую вы напишете вручную, и сборка, созданная компилятором, часто сильно различаются, если смотреть с высокого уровня. Конечно, внутренности программы будут очень похожи (в a = b + cконце концов, существует не так много разных способов кодирования ), но это не проблема, когда вы пытаетесь что-то перепроектировать. Компилятор добавит тонну шаблонного кода даже в простые исполняемые файлы: в прошлый раз, когда я сравнивал, "Hello World", скомпилированный GCC, был около 4 КБ, тогда как если бы он был написан вручную в сборке, это около 100 байт. На Windows хуже: в прошлый раз сравнивал (правда, это был прошлый век) самый маленький "Hello World", который я мог сгенерировать с помощью моего компилятора Windows, составлял 52 КБ! Обычно этот шаблон выполняется только один раз, если вообще выполняется, поэтому он не сильно влияет на скорость программы - как я сказал выше, ядро ​​программы, часть, на которую тратится большая часть времени выполнения, обычно очень похоже, независимо от того, скомпилировано или написано от руки.

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

Что вы хотите сделать, так это взять руководства по архитектуре IA-32 и AMD64 (оба рассматриваются вместе) от Intel и AMD и просмотреть первые разделы с инструкциями и кодами операций. Может быть, прочтите пару руководств по ассемблеру, просто чтобы понять основы ассемблера. Тогда возьмите небольшойпример программы, которая вас интересует, и разберите ее: пройдитесь по ее потоку управления и попытайтесь понять, что она делает. Посмотрите, сможете ли вы исправить это, чтобы сделать что-нибудь еще. Затем попробуйте еще раз с другой программой и повторяйте, пока не почувствуете себя достаточно комфортно, чтобы попытаться достичь более полезной цели. Возможно, вас заинтересуют такие вещи, как «кряки», созданные сообществом реверс-инжиниринга, которые представляют собой сложную задачу для людей, интересующихся реверс-инжинирингом, которые могут попробовать свои силы и, надеюсь, научиться чему-то в процессе. Их сложность варьируется от базовой (начните здесь!) До невозможной.

Прежде всего, вам просто нужно практиковаться . Как и во многих других дисциплинах, с обратной инженерией, практика делает совершенство ... или, по крайней мере, лучше .

Kquinn
источник
Я знаю, что когда вы компилируете что-либо с помощью языка высокого уровня, вы получите много «мусорного» кода, который не понадобился бы, если бы он был написан непосредственно на ассемблере. Я также понимаю, что есть разница между опытным программистом-ассемблером и опытным дизассемблером. Но то же самое можно сказать почти обо всем остальном.
пожрал элизиум 01
3
Меня беспокоит то, что, хотя теоретически я мог бы читать статьи и понимать, что они означают, пока я не начну писать что-то сам, я не верю, что действительно пойму это. Вы говорите, что я могу начать с изменения небольших частей кода, но для этого я сначала должен знать, какой тип ассемблера, например, использует IDA pro.
пожрал элизиум 01
Кроме того, что MSVC ++ использует для встроенного кода сборки? МАСМ?
поглотил элизиум 01
15

Я пойду против большинства ответов и порекомендую MMIX- вариант архитектуры MIPS RISC Кнута . Он не будет так полезен с практической точки зрения, как языки ассемблера x86 или ARM (не то чтобы в наши дни они так важны для большинства реальных задач ... ;-), но он откроет вам магию последней версии Knuth. версия величайшего шедевра по глубокому низкоуровневому пониманию алгоритмов и структур данных - TAOCP , "Искусство компьютерного программирования". Ссылки из двух процитированных мной URL - отличный способ начать исследовать эту возможность!

Алекс Мартелли
источник
12

(Не знаю, как вы, но я был в восторге от сборки)

На вашем компьютере уже установлен простой инструмент для экспериментов со сборкой.

Перейдите в меню Пуск-> Выполнить и введитеdebug

отладка (команда)

debug - это команда в DOS, MS-DOS, OS / 2 и Microsoft Windows (только версии x86, но не x64), которая запускает программу debug.exe (или DEBUG.COM в старых версиях DOS). Отладка может действовать как программа на ассемблере, дизассемблере или шестнадцатеричном дампе, позволяя пользователям интерактивно исследовать содержимое памяти (на языке ассемблера, в шестнадцатеричном или ASCII формате), вносить изменения и выборочно выполнять COM, EXE и другие типы файлов. Он также имеет несколько подкоманд, которые используются для доступа к определенным секторам диска, портам ввода-вывода и адресам памяти. Отладка MS-DOS выполняется на уровне 16-разрядного процесса и поэтому ограничивается 16-разрядными компьютерными программами . FreeDOS Debug имеет версию "DEBUGX", также поддерживающую 32-битные программы DPMI.

Учебники:


Если вы хотите понять код, который вы видите в IDA Pro (или OllyDbg ), вам необходимо узнать, как структурирован скомпилированный код. Я рекомендую книгу Reversing: Secrets of Reverse Engineering

Я поэкспериментировал пару недель, debugкогда начал изучать сборку (15 лет назад).
Обратите внимание, что debugработает на базовом уровне машины, нет команд сборки высокого уровня.

А теперь простой пример:

дайте aначать писать ассемблерный код - введите следующую программу - и наконец дайте gзапустить ее.

альтернативный текст


( INT 21отображение на экране символа ASCII, хранящегося в DLрегистре, если AHрегистр установлен в 2- INT 20завершает программу)

Ник Дандулакис
источник
Мне пришлось нажать ctrl-c, прежде чем я смог ввести "g".
ericp 07
2
@ericp, вам не нужно нажимать ctrl-c. Например, вы набираете a& [ввод], чтобы начать писать ассемблерный код. Если вы дважды нажмете [Enter], вы выйдете из режима сборки. g& [ввод], чтобы запустить его (смещение 100 по умолчанию).
Ник Дандулакис,
действительно ли это вызывает переполнение стека или просто выводит его на экран?
Янус Троелсен
1
@user, он просто пишет название этого сайта :-)
Ник Дандулакис
@JanusTroelsen, эти числа (53, 74, 61 и т. Д.) Являются кодами ASCII для 'S' 't' 'a' ... Каждый вызов Int21 печатает по одному символу за раз! Вот почему сборка НЕ ​​выполняется быстрее :)
doug65536
8

Я нашел Hacking: The Art of Exploitation интересным и полезным способом в этой теме ... не могу сказать, что когда-либо использовал эти знания напрямую, но на самом деле я читал это не поэтому. Это дает вам гораздо более полное представление об инструкциях, в которые компилируется ваш код, что иногда бывает полезно для понимания более тонких ошибок.

Не откладывайте заголовок. Большая часть первой части книги - это «Хакерство» в понимании этого слова Эриком Раймондом: творческие, удивительные, почти хитрые способы решения сложных проблем. Меня (и, возможно, вас) гораздо меньше интересовали аспекты безопасности.

mblackwell8
источник
8

Я бы не стал зацикливаться на написании программ на ассемблере, по крайней мере, сначала. Если вы используете x86 (что, как я предполагаю, так и есть, поскольку вы используете Windows), существует множество странных особых случаев, изучать которые бессмысленно. Например, многие инструкции предполагают, что вы работаете с регистром, которому вы явно не называете имя, а другие инструкции работают с одними регистрами, но не с другими.

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

Я бы сказал, что основы:

  • регистры: сколько их, как их зовут и каковы их размеры?
  • Порядок операндов: add eax, ebxозначает «Добавить ebx в eax и сохранить результат в eax».
  • FPU: изучите основы стека с плавающей запятой и способы преобразования в / из fp.
  • режимы адресации: [основание + смещение * множитель], но множитель может быть только 1, 2 или 4 (а может быть, 8?)
  • соглашения о вызовах: как параметры передаются функции?

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

Возможно, вам также будет полезно вооружиться руководствами Agner Fog , особенно инструкциями, в которых они перечислены. Он примерно скажет вам, насколько дорогая каждая инструкция, хотя на современных процессорах это сложнее напрямую количественно оценить. Но это поможет объяснить, почему, например, компилятор делает все возможное, чтобы избежать выдачи idivинструкции.

Еще один мой совет - всегда использовать синтаксис Intel вместо AT&T, когда у вас есть выбор. Раньше я был довольно нейтральным в этом вопросе, пока не понял, что некоторые инструкции у них совершенно разные (например, movslqв синтаксисе AT&T используется синтаксис movsxdIntel). Поскольку все руководства написаны с использованием синтаксиса Intel, просто придерживайтесь его.

Удачи!

Джош Хаберман
источник
4

Я начал изучать MIPS, очень компактную 32-битную архитектуру. Это сокращенный набор инструкций, но его легко понять новичкам. Вы по-прежнему сможете понять, как работает сборка, не перегружая себя сложностью. Вы даже можете загрузить миленький IDE, который позволит вам компилировать код MIPS: Clicky Как только вы получите повесить ее, я думаю , что было бы гораздо легче перейти к более сложной архитектуре. По крайней мере, я так думал :) На этом этапе у вас будут основные знания о распределении и управлении памятью, логическом потоке, отладке, тестировании и т. Д.


источник
4

Предложение использовать отладку - забавное, с его помощью можно проделать много интересных трюков. Однако для современной операционной системы изучение 16-битной сборки может быть немного менее полезным. Вместо этого рассмотрите возможность использования ntsd.exe. Он встроен в Windows XP (к сожалению, его перенесли в Server 2003 и новее), что делает его удобным инструментом для изучения, поскольку он настолько широко доступен.

Тем не менее, исходная версия в XP страдает рядом ошибок. Если вы действительно хотите его использовать (или cdb или windbg, которые представляют собой существенно разные интерфейсы с одинаковым синтаксисом команд и внутренней отладкой), вам следует установить пакет бесплатных инструментов отладки Windows .

Файл debugger.chm, включенный в этот пакет, особенно полезен при попытке выяснить необычный синтаксис.

Самое замечательное в ntsd то, что вы можете установить его на любой машине XP, которая находится рядом, и использовать для сборки или разборки. Это делает инструмент для обучения сборке / great / X86. Например (используя cdb, поскольку он встроен в приглашение dos, в остальном он идентичен):

(ошибки символов пропущены, так как они не имеют отношения к делу - также, надеюсь, это форматирование сработает, это мой первый пост)

C:\Documents and Settings\User>cdb calc

Microsoft (R) Windows Debugger Version 6.10.0003.233 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: calc
Symbol search path is: *** Invalid ***
Executable search path is:
ModLoad: 01000000 0101f000   calc.exe
ModLoad: 7c900000 7c9b2000   ntdll.dll
ModLoad: 7c800000 7c8f6000   C:\WINDOWS\system32\kernel32.dll
ModLoad: 7c9c0000 7d1d7000   C:\WINDOWS\system32\SHELL32.dll
ModLoad: 77dd0000 77e6b000   C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f02000   C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77fe0000 77ff1000   C:\WINDOWS\system32\Secur32.dll
ModLoad: 77f10000 77f59000   C:\WINDOWS\system32\GDI32.dll
ModLoad: 7e410000 7e4a1000   C:\WINDOWS\system32\USER32.dll
ModLoad: 77c10000 77c68000   C:\WINDOWS\system32\msvcrt.dll
ModLoad: 77f60000 77fd6000   C:\WINDOWS\system32\SHLWAPI.dll
(f2c.208): Break instruction exception - code 80000003 (first chance)
eax=001a1eb4 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4
eip=7c90120e esp=0007fb20 ebp=0007fc94 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
ntdll!DbgBreakPoint:
7c90120e cc              int     3
0:000> r eax
eax=001a1eb4
0:000> r eax=0
0:000> a eip
7c90120e add eax,0x100
7c901213
0:000> u eip
ntdll!DbgBreakPoint:
7c90120e 0500010000      add     eax,100h
7c901213 c3              ret
7c901214 8bff            mov     edi,edi
7c901216 8b442404        mov     eax,dword ptr [esp+4]
7c90121a cc              int     3
7c90121b c20400          ret     4
ntdll!NtCurrentTeb:
7c90121e 64a118000000    mov     eax,dword ptr fs:[00000018h]
7c901224 c3              ret
0:000> t
eax=00000100 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4
eip=7c901213 esp=0007fb20 ebp=0007fc94 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
ntdll!DbgUserBreakPoint+0x1:
7c901213 c3              ret
0:000>`

Кроме того, пока вы играете с IDA, обязательно ознакомьтесь с IDA Pro Book Криса Игла (ссылка отключена, поскольку StackOverflow не позволяет мне размещать более двух ссылок для моего первого сообщения). Это, безусловно, лучший справочник.

Иордания
источник
1
+1 за книгу Криса Игла. Надо добавить немного любви к Sk3wl из r00t;)
mrduclaw
4

Недавно я прошел курс компьютерных систем. Одной из тем была сборка как инструмент для связи с оборудованием.

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

Учитывая это, я склонен рекомендовать свой учебник для занятий:

Компьютерные системы: точка зрения программиста .

Компьютерные системы: взгляд программиста
(источник: cmu.edu )

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

Франк V
источник
3

Я думаю, вы хотите изучить мнемонику опкодов в формате ASCII (и их параметры), которые выводятся дизассемблером и которые понимаются ассемблером (могут использоваться в качестве входных данных).

Подойдет любой ассемблер (например, MASM).

И / или вам может быть лучше прочитать книгу об этом (были книги, рекомендованные по SO, я не помню, какие).

ChrisW
источник
3

Вы занимаетесь другой разработкой для Windows? На какой IDE? Если это VS, то нет необходимости в дополнительной IDE только для чтения дизассемблированного кода: отладьте свое приложение (или подключитесь к внешнему приложению), затем откройте окно дизассемблирования (в настройках по умолчанию это Alt + 8). Шагайте и наблюдайте за памятью / регистрами, как при использовании обычного кода. Вы также можете оставить окно регистров открытым (по умолчанию Alt + 5).

Intel предоставляет бесплатные руководства , которые содержат как обзор базовой архитектуры (регистры, процессорные блоки и т. Д.), Так и полный справочник инструкций. По мере развития и усложнения архитектуры руководства по «базовой архитектуре» становятся все менее и менее удобочитаемыми. Если вы сможете достать старую версию, у вас, вероятно, будет лучшее место для начала (даже руководства P3 - они лучше объясняют ту же базовую среду выполнения).

Если вы хотите вложить деньги в книгу, вот хороший вводный текст. Поищите amazon по запросу «x86», и вы получите много других. Вы можете получить несколько других направлений из другого вопроса здесь .

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

Офек Шилон
источник
3

Это не обязательно поможет вам писать эффективный код!

Операционные коды i86 - это более или менее «устаревший» формат, который сохраняется из-за огромного объема кода и исполняемых двоичных файлов для Windows и Linux.

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

Таким образом, компиляторы по умолчанию генерируют код x86, а современные чипы считывают предшествующие коды операций и переводят то, что они видят, в параллельные инструкции RSC с переупорядоченным выполнением, спекулятивным выполнением, конвейерной обработкой и т. Д., Плюс они полностью используют 32 или 64 регистра процессора. на самом деле имеет (в отличие от жалкой восьмерки, которую вы видите в инструкциях для x86).

Теперь все оптимизирующие компиляторы знают, что это действительно происходит, поэтому они кодируют последовательности кодов OP, которые, как они знают, микросхема может эффективно оптимизировать, даже если некоторые из этих последовательностей покажутся неэффективными для программиста .asm примерно 1990 года.

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

Самый простой и легкий способ получить более эффективную среду выполнения - это купить компилятор Intel C / C ++. У них есть ниша на рынке эффективных компиляторов, и у них есть то преимущество, что они могут спрашивать разработчиков микросхем о том, что происходит внутри.

Джеймс Андерсон
источник
Ваша история в некоторой степени предполагает, что процессоры CISC внутренне превратились в процессоры RISC. Возможно, я неправильно понял, но это просто неправда. А жалкая восьмерка? Современные процессоры (скажем, с 1999 г.) включают гораздо больше: 10 gpr: EAX-EFLAGS, 80-битный FP0-FP7, 64-битный MMX0-MMX7, 128-битный XMM0-XMM7, сегмент: CS-GS, специальные характеристики: CR0-CR4 , DR0-DR7, TR3-TR7, GDTR, IDTR, LDTR, MSR, а на x86-64 также R8-R15. Не все из них доступны из ring-3, но большинство из них используются и используются последними (после 2006 г.) компиляторами GCC / VC ++. В общем чуть больше, чем у "жалкой 8";).
Abel
3

Чтобы сделать то, что вы хотите сделать, я просто взял Справочник по набору инструкций Intel (может быть, не тот, который я использовал, но выглядит достаточно) и несколько простых программ, которые я написал в Visual Studio, и начал бросать их в IDAPro / Windbg. . Когда я перерос свои собственные программы, программное обеспечение компании crackmes мне помогло.

Я предполагаю, что у вас есть базовые представления о том, как программы выполняются в Windows. Но на самом деле для чтения ассемблера есть только несколько инструкций для изучения и несколько разновидностей этих инструкций (например, есть инструкция перехода, jump имеет несколько разновидностей, таких как jump-if-equal, jump-if-ecx-is-zero , и т.д). После того, как вы изучите основные инструкции, довольно просто понять суть выполнения программы. Представление графика IDA помогает, и если вы отслеживаете программу с помощью Windbg, довольно просто выяснить, что делают инструкции, если вы не уверены.

Немного поиграв в этом, я купил Hacker Disassembly Uncovered . Как правило, я избегаю книг со словом «Хакер» в названии, но мне очень понравилось, как в этой книге подробно рассказывается о том, как скомпилированный код выглядит в дизассемблированном виде. Он также занимается оптимизацией компилятора и некоторыми интересными вещами, касающимися эффективности.

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

mrduclaw
источник
2

Один из стандартных языков педагогического ассемблера - MIPS. Вы можете приобрести симуляторы MIPS (spim) и различные учебные материалы для них.

Лично я не фанат. Мне больше нравится IA32.

Пол Натан
источник
MIPS - это хорошо. 68000 тоже, и если вы выучите 68000, вы сможете писать двоичные файлы, которые будут работать в MAME. :-)
Носредна 09
2

Мой личный фаворит - NASM, в основном потому, что он мультиплатформенный, и он компилирует MMX, SSE, 64-бит ...

Я начал компилировать простой исходный файл C с помощью gcc и «перекодировать» инструкцию ассемблера из формата gcc в формат NASM. Затем вы можете изменить небольшие фрагменты кода и проверить улучшение производительности, которое оно приносит.

Документация NASM действительно полная, мне никогда не приходилось искать информацию из книг или других источников.

ГБ
источник
1

Здесь много хороших ответов. Низкоуровневое программирование, сборка и т. Д. Популярны в сообществе специалистов по безопасности, поэтому стоит поискать там подсказки и подсказки, когда вы начнете. У них даже есть несколько хороших руководств, подобных этому, по сборке x86 .

Брайан Литтл
источник
1

Сборку мы изучили с помощью комплекта разработчика микроконтроллера (Motorola HC12) и толстого даташита.

the_e
источник
0

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

Изучение неоптимизированного кода c / c ++ поможет создать ссылку на тот тип кода, который компилятор генерирует для ваших источников. В некоторых компиляторах есть какое-то зарезервированное слово ASM, которое позволяет вставлять машинные инструкции в код.

Я бы посоветовал немного поиграть с такими инструментами и намочить ноги, а затем перейти к делу? вниз? к прямому ассемблерному коду на любой платформе, на которой вы работаете.

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

EvilTeach
источник
0

Не по теме, я знаю, но поскольку вы программист Windows, я не могу не думать, что это может быть более подходящим и / или лучшим использованием вашего времени для изучения MSIL. Нет, это не сборка, но, вероятно, это более актуально в нашу эпоху .NET.

slf
источник
0

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

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

Вы можете посмотреть видеокурс xorpd x86 Assembly . (Я это написал). Сам курс платный, но упражнения с открытым исходным кодом, на github. Если у вас есть опыт программирования, я думаю, вы должны уметь работать только с упражнениями и все понимать.

Обратите внимание, что код предназначен для платформы Windows и написан с использованием ассемблера Fasm . Курс и упражнения не содержат никаких высокоуровневых конструкций, однако вы можете использовать Fasm для создания очень сложных макросов, если хотите.

xorpd
источник