Ассемблер ARM для хакеров, часть 2: использование GDB для понимания инструкции ADD

  • Автор темы Автор темы LeSh1y777
  • Дата начала Дата начала

LeSh1y777

Пользователь
Регистрация
25/9/25
Сообщения
5,682
Репутация
49
Лайки
153
Депозит
-8.95$
Добро пожаловать обратно, кибервоины!

В предыдущей статье мы рассмотрели некоторые команды ассемблера ARM. Сегодня мы углубимся в практическое применение инструкции ADD. Используя возможности отладчика GNU (GDB), мы рассмотрим, как анализировать и обрабатывать эту инструкцию, чтобы глубже понять архитектуру ARM.

Подготовьте среду​

Прежде чем приступить к изучению ассемблера, нам следует подготовить среду. О возможных способах подготовки можно прочитать в этой статье . Я буду использовать Raspberry Pi с 32-битной ОС Raspbian.

Чтобы проверить, работает ли ваша система в 32-разрядном пользовательском пространстве, выполните:

raspberrypi> getconf LONG_BIT

Далее проверьте архитектуру ваших двоичных файлов:

raspberrypi> файл /bin/bash

arm_asm_check_os_version.webp

В приведенном выше примере вы видите довольно распространённую проблему современных Raspberry Pi: Raspbian OS — 32-битная система, но использует 64-битное ядро. Это оптимальный вариант установки, поскольку он обеспечивает совместимость с 32-битной версией для всех ваших приложений и библиотек, а также лучшую поддержку оборудования благодаря 64-битному ядру.

Инструкция ДОБАВИТЬ​

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

Синтаксис следующий:

<strong>ADD{S}{&lt;c&gt;}{&lt;q&gt;} {&lt;Rd&gt;,} &lt;Rn&gt;, #&lt;const&gt;</strong>
Где
S – если присутствует, инструкция обновляет флаги. Мы поговорим о флагах позже;
<Rd> – регистр назначения;
<Rn> – первый операнд;
<const> – непосредственное значение, которое нужно добавить к значению, полученному из <Rn>;
<c> и <q> – необязательные поля ассемблера.

Перейдём к практическому этапу и напишем код. Я создам файл instructions.s и открою его в Vim.

Начало файла, как обычно, — глобальное объявление значения «_start». Я подробно объяснил этот шаг в следующей статье . Также для удобства изучения я добавлю комментарий с синтаксисом инструкции add.

arm_asm_biginning_of_the_code.webp

Прежде всего, нам нужен регистр (<Rn>), который будет прибавляться к нашему константному значению (#<const>). Мы создадим регистр общего назначения с помощью инструкции mov.

Как вы, возможно, помните из моей предыдущей статьи, регистры общего назначения — это r0-r12.

arm_asm_registers.png

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

mov r0, #7

Где
mov – инструкция скопировать значение в регистр;
r0 – регистр назначения, в котором мы будем хранить временное значение;

#7 – знак решетки означает, что следующее значение является константой. В этом примере я использовал число 7; вы можете выбрать любое другое.

После этого мы готовы приступить к выполнению инструкции по добавлению.

add r1, r0, #3

arm_asm_add_instruction.webp

Где
r1 — регистр назначения, в котором мы собираемся сохранить сумму 7 + 3
r0 — наш первый операнд со значением 7.

#3 – константа, которая будет добавлена к r0. Я использовал значение 3.

На этом этапе давайте соберем этот код и посмотрим в gdb (отладчике GNU), что происходит.

Для сборки я буду использовать GCC:

gcc -g -nostdlib -static -o instructions instructions.s

arm_asm_assemble.webp

Где
-g – Включить отладочную информацию
-nostdlib – Не компоновать со стандартной библиотекой (так как мы ее не используем)
-static – Создать статический исполняемый файл

Теперь мы можем открыть исполняемый файл с помощью GDB, но перед этим я установлю GEF (GDB Enhanced Features), который обеспечивает автоматический мониторинг регистров, вывод цветового кода и многое другое.

Чтобы установить GEF, выполните:

raspberrypi&gt; bash -c "$(curl -fsSL https://gef.blah.cat/sh)"

Теперь запустим GDB:

gdb ./instructions

arm_asm_start_gdb.webp

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

(gdb) set displaced-stepping off

После этого мы можем установить точку останова на метке _start, чтобы остановить выполнение там:

(gdb) break _start

arm_asm_breakpoint.webp

Запускаем нашу программу:

(gdb) run

arm_asm_run_command_gdb.webp

Здесь мы видим, что программа начала выполнение, но остановилась на _start из-за точки останова.

Давайте проверим значение всех регистров:

(gdb) info registers

arm_asm_empty_registers.webp

На этом этапе они пустые. Давайте рассмотрим одну инструкцию по сборке:

(gdb) stepi

И проверьте значение только регистров r0 и r1.

(gdb) info registers r0 r1

arm_asm_store_r0.webp

И здесь мы видим, что регистр r0 уже хранит значение 0x7 или 7 в десятичной системе счисления.

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

arm_asm_value_for_r1.webp

Значение r1 равно 0xa или 10 в десятичной системе счисления, как мы и запрограммировали.

Краткое содержание​

В этой статье мы рассмотрим инструкцию ADD на языке ассемблера ARM. Мы рассмотрим сборку кода с помощью GCC и использование GDB (отладчика GNU) для мониторинга выполнения и проверки значений регистров, демонстрируя, как результаты отражают запрограммированные сложения. Понимание такого низкоуровневого поведения крайне важно для разработки эксплойтов, где манипулирование значениями регистров и управление ходом выполнения программы, например, перенаправление выполнения или создание цепочек возвратно-ориентированного программирования (ROP), зависят от точного знания того, как такие инструкции, как ADD, влияют на состояние системы.
 
Назад
Сверху Снизу