• XSS.stack #1 – первый литературный журнал от юзеров форума

Мануал/Книга 32-битная архитектура ARM (часть 1)

yashechka

Генератор контента.Фанат Ильфака и Рикардо Нарвахи
Эксперт
Регистрация
24.11.2012
Сообщения
2 344
Реакции
3 563
Часть 1 - Смысл жизни

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

Этот курс представляет собой комплексную серию уроков, в которой мы изучаем все аспекты C++ и то, как они связаны с архитектурой ARM 64, поскольку мы отреверсим каждый шаг на языке ассемблера ARM 64, чтобы получить полное представление о среде.

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

В следующем уроке мы настроим нашу среду разработки

Источник: https://0xinfection.github.io/reversing/pages/arm-32-course-1.html
 
Часть 2 - Системы счисления

В основе микропроцессора лежит последовательность двоичных чисел, которые представляют собой напряжение либо +5Вольт (включен, или 1), либо 0Вольт (выключен или 0). Каждый 0 или 1 представляет бит информации в микропроцессоре. Комбинация 8 бит дает один байт.
Прежде чем мы погрузимся в двоичную систему, давайте рассмотрим знакомую десятичное число. Если мы возьмем число 2017, мы поймем, что это две тысячи семнадцать.

1642151497415.png


Давайте посмотрим на двоичную систему и основы того, как она работает.

1642151514515.png


Если бы мы преобразовали двоичное число в десятичное, мы бы очень просто сделали следующее. Возьмем двоичное число 0101 1101, и, как вы можете видеть, это 93 десятичное число.

1642151531666.png


Добавление значений в столбец значений дает нам 0 + 64 + 0 + 16 + 8 + 4 + 0 + 1 = 93 в десятичной системе.

Если бы мы преобразуем десятичное число в двоичное, мы бы проверили, возможно ли вычитание относительно бита самого высокого порядка, и если да, то в двоичный столбец будет помещена единица, а остаток будет перенесен в следующий ряд. Давайте рассмотрим пример десятичного значения 120, которое составляет 0111 1000 в двоичной системе.

1642151548115.png

1) Может 128 поместиться внутри 120: Нет, поэтому 0.
2) Может ли 64 поместиться внутри 120: Да, значит, 1, тогда 120 - 64 = 56.
3) Может 32 поместиться внутри 56: Да, поэтому 1, тогда 56-32 = 24.
4) Может ли 16 поместиться внутри 24: Да, значит, 1, тогда 24 - 16 = 8.
5) Может ли 8 поместиться внутри 8: Да, поэтому 1, тогда 8-8 = 0.
6) Может ли 4 поместиться внутри 0: Нет, поэтому 0.
7) Может ли 2 поместиться внутри 0: Нет, поэтому 0.
8) Может ли 1 поместиться внутри 0: Нет, поэтому 0.


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

1642151566195.png


Преобразуем двоичное число, например 0101 1111, в шестнадцатеричное. Для этого мы просто смотрим на таблицу и сравниваем каждый полубайт, который представляет собой комбинацию из 4 бит. Имейте в виду, что 8 бит равны байту, а 2 нибла равны байту.

0101 = 5

1111 = F


Следовательно, 0101 1111 в двоичной системе = 0x5f в шестнадцатеричной. Обозначение 0x обозначает шестнадцатеричный формат.

Чтобы перейти от шестнадцатеричного формата к двоичному, это очень просто сделать, поскольку вам нужно просто сделать так, например:

0x3a = 0011 1010

3 = 0011

А = 1010


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

Чтобы преобразовать шестнадцатеричное значение в десятичное, мы делаем следующее:

0x5f = 95
5 = 5 х 16 ^ 1 = 5 х 16 = 80
F = 15 х 16 ^ 0 = 15 х 1 = 15


Таким образом, мы видим, что 80 + 15 = 95, что является шестнадцатеричным значением 0x5f.

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

1642151655659.png

Складываем числа снизу вверх и получаем 352 в шестнадцатеричном формате.

"Какого черта я буду тратить свое время на изучение всей этой чуши, когда компьютер делает все это за меня!"

Если вы знакомы с какими-либо реверс-инженерами, пожалуйста, уделите время и задайте им вышеупомянутый вопрос.

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

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

Независимо от того, создаете ли вы, отлаживаете или крякаете, Python, Java, C, C++, R, JavaScript или любое другое приложение, которое выходит в свет, в конечном итоге оно все состоит из двоичных 0 и 1, которые представляют собой +5Вольт или 0В.

Мы, люди, работаем в десятичной системе счисления. Процессор работает в шестнадцатеричной. Регистры, с которыми мы имеем дело в Linux, имеют 32-битный размер. Когда мы начнем обсуждение регистров процессора, мы узнаем, что каждый из них имеет 32-битную ширину (технически BCM2837 имеет 64-битную ширину, однако наша версия Linux, с которой мы работаем, является 32-битной, поэтому мы адресуем только 32-битные регистры каждого регистра).

В следующем уроке мы погрузимся в двоичное сложение! Будьте на связи!
 
Часть 3 - Бинарное сложение

Бинарное сложение может проходить одним из четырех способов:

0 + 0 = 0
1 + 0 = 1
0 + 1 = 1
1 + 1 = 0 (1) [Один + один равно нулю, один идет в перенос]


Имейте в виду, что (1) означает бит переноса. Это очень просто означает переполнение.

Возьмем следующий пример 4-битного нибла:

0111
+ 0100
= 1011


Мы видим очевидный перенос в 3-м бите. Если бы 8-й бит имел перенос, это сгенерировало бы флаг переноса в ЦП.

Давайте рассмотрим 8-битное число:

01110000
+ 01010101
= 11000101


Если бы у нас было:

11110000
+ 11010101
= (1) 11000101


Здесь мы видим бит переноса, который запускает флаг переноса в ЦП равным 1 или истина. Мы обсудим флаг переноса в следующих уроках. Просто запомните этот пример для справки, так как он очень важен для понимания.

На следующем уроке мы погрузимся в бинарное вычитание! Будьте на связи!
 
Часть 4 - Двоичное вычитание

Двоичное вычитание - это не что иное, как добавление отрицательного значения числа, которое нужно вычесть. Например, 8 + - 4, начальная точка будет равна нулю, к которой мы перемещаем 8 точек в положительном направлении, а затем четыре точки в отрицательном направлении, что дает значение 4.

Мы представляем знаковый бит в двоичном формате, для которого бит 7 указывает знак числа, где 0 положительно, а 1 отрицательно.

1643011241755.png


Вышеупомянутое соответствует -2.

Мы используем концепцию дополнения до двух, при которой каждый бит инвертируется, а затем добавляется 1.

Давайте рассмотрим двоичный код 2.

00000010

Переверните биты.

11111101

1643011263060.png


Давайте рассмотрим операцию вычитания:

1643011289722.png


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

На следующем уроке мы рассмотрим длину слов! Будьте на связи!
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх