GDB і регістри x86_64 — довідник

 


Регістри x86_64

Загального призначення

Регістр Призначення
rax Повернення значення з функції
rdi 1-й аргумент функції
rsi 2-й аргумент функції
rdx 3-й аргумент функції
rcx 4-й аргумент функції

Ключові регістри стеку

Регістр Призначення
rip Instruction Pointer — адреса наступної інструкції що виконається
rsp Stack Pointer — вершина стеку (поточна позиція)
rbp Base Pointer — основа поточного фрейму

Що читати в першу чергу при крашу


ASCII → Hex шпаргалка

Літера Hex
A 0x41
B 0x42
C 0x43
D 0x44
E 0x45
F 0x46

Якщо бачиш 0x4141414141414141 — це AAAAAAAA в пам’яті.


GDB — основні команди

Запуск

Управління виконанням

Breakpoints

Крокування

Регістри

Пам’ять — команда x (examine)

Формат команди x:

Функції і символи

Backtrace (стек викликів)


Розкладка стеку x86_64

При overflow заповнюємо знизу вгору:


Little-endian — як записувати адреси

x86 зберігає байти у зворотньому порядку!

Тобто молодший байт іде першим.

Python для генерації payload:


Захисти і як їх бачити

Stack Canary

Якщо є — overflow викликає *** stack smashing detected *** до ret.

ASLR

PIE (Position Independent Executable)


Компіляція — прапорці захисту

Прапорець Що вимикає
-fno-stack-protector Stack canary
-z execstack NX (стек стає виконуваним)
-no-pie PIE (адреси стають фіксованими)
-g Debug символи (для GDB)

Небезпечні функції C

Функція Проблема Замінити на
gets(buf) не перевіряє розмір взагалі fgets(buf, sizeof(buf), stdin)
strcpy(dst, src) копіює до \0 без перевірки strncpy(dst, src, sizeof(dst)-1)
strcat(dst, src) не перевіряє розмір strncat(dst, src, sizeof(dst)-strlen(dst)-1)
sprintf(buf, fmt, ...) може переповнити buf snprintf(buf, sizeof(buf), fmt, ...)
scanf("%s", buf) не перевіряє розмір scanf("%7s", buf) (з обмеженням)

Швидкий workflow при крашу

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *