- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
#include "gc.h"
static bool PointerNotOwnedByParentStackFrame(struct StackFrame *frame,
struct StackFrame *parent,
void *ptr) {
return !(((intptr_t)ptr > (intptr_t)frame) &&
((intptr_t)ptr < (intptr_t)parent));
}
/**
* Adds destructor to garbage shadow stack.
*
* @param frame is passed automatically by wrapper macro
* @param fn takes one argument
* @param arg is passed to fn(arg)
* @return arg
*/
void __defer(struct StackFrame *frame, void *fn, void *arg) {
struct StackFrame *frame2;
if (!arg) return;
frame2 = __builtin_frame_address(0);
assert(frame2->next == frame);
assert(PointerNotOwnedByParentStackFrame(frame2, frame, arg));
if (append(&__garbage, /* note: append() not included */
(&(const struct Garbage){frame->next, (intptr_t)fn, (intptr_t)arg,
frame->addr})) != -1) {
frame->addr = (intptr_t)&__gc;
} else {
abort();
}
}
Это с какой версии такой изврат можно делать? Пиздец, почему просто локалку не заполнить над вызовом?
https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html
А ещё питушение с longjmp.
https://govnokod.ru/24763#comment429753
В «gcc» его можно поймать с помощью __builtin_frame_address(0).
Т.е. со всякими защитами от нарушения control flow этот код несовместим? Заебись фича. Хуже были только гццшные "лямбды", которые вообще исполняемый стек требовали.
> Хуже были только гццшные "лямбды", которые вообще исполняемый стек требовали.
Лолчто???
Можно же просто насрать в стек своим юзер-инпут говном, а потом порушить всё нахуй.
https://govnokod.ru/13183
https://govnokod.ru/13162
https://govnokod.ru/23505
Ещё где-то было.
https://govnokod.ru/19017
В 64-битном «MSVC» нет встроенного асма. Что предложил автор примера? Он предложил положить мышиного кота в строковую инициализированную переменную и снять атрибут «no execute» у страниц, в которые попало это значение.
В «Windows» поддержка «DEP» появилась в «Висте», но по дефолту была отключена для пользовательских программ, потому что с «DEP» старое говно может не работать.
Удобной настройка исключений «DEP» в «Windows» стала, когда появилось средство «EMET»:
https://en.wikipedia.org/wiki/Enhanced_Mitigation_Experience_Toolkit
P.S. А, он про ядро, а не про юзерспейс.
А реально прижали всех к стенке на десятке когда HVCI запилили, насколько я помню.
P.S. Нагуглил:
https://docs.microsoft.com/en-us/windows/security/threat-protection/device-guard/enable-virtualization-based-protection-of-code-integrity
Его ещё в старых билдах не было... Как всё сложно...
UPD: оказывается, минус второе — это «System Management Mode».
Гипервизор, например, считается минус первым кольцом, «SMM» — минус вторым, «Intel ME» — минус третьим. Однако, повторюсь, это больше эмпирическое разделение по принципу «кольцо N имеет произвольный доступ к кольцам N+i, кольцо N не может влиять на кольца N-i больше дозволенного этими кольцами». Что именно считать отрицательным «кольцом» — вопрос философский. Физический мир, например, можно записать в минус четвёртое: компьютер может влиять на окружающую среду только через строго определённые механизмы, в то время как окружающая среда может воздействовать на компьютер как угодно.
«Технические» кольца (по крайней мере, в «x86») определены строго: через CPL. «Философские кольца», в свою очередь, чисто эмпирические: все просто договорились считать гипервизор минус первым кольцом, например. С тем же успехом его можно записать в минус десятое (SMM — -11, etc.), от этого смысл не изменится.
SMM (минус второе кольцо) точно был на всех 80486, а также на каких-то 80386, только он, кажется, раньше не был документирован, кто-то случайно раскрыл опкод для переключения в SMM.
В «gcc» вложенные функции работают как замыкания, захватывая все локальные переменные и аргументы родительской функции.
Зачем-то добавили фичу: на вложенную функцию можно взять указатель. Чтобы по этому указателю вложенную функцию можно было вызвать, придумали «трамплины»: это такой короткий код, который передаёт вызываемому замыканию указатель на контекст. Так вот авторы не придумали ничего лучше, чем создавать этот трамплин в стеке. Поэтому со всех страницы стека приходится снимать атрибут «no execute», иначе трамплин не вызовется.
https://man.openbsd.org/mprotect.2
Кажется, в юзверьском коде такого ограничения нет.
PHP ставится в другой раздел (/usr/local/), не является частью базовой системы, и потому может хоть все страницы пометить как RWX, всем насрать.
Тео и Ко гарантируют безопасность и безбажность только базовой системы. Охуилон портов всякого говна они, разумеется, не могут проверить.
PS. я джва года жду такой шеллкод.
Вроде обычный C99.
в ТВОЕМ ПРИМЕРИ МОЖЕТ БЫТЬ НА СТЕКЕ, ЛИБО В СЕКЦИИ С КОНСТАНЦИЯМИ, ЛЕНЬ ИСКАТЬ В СТОНДАРТЕ. я, СОБСНО, ИСПОЛЬЗОВАЛ ЭТУ ФИЧУ С ГЛОБАЛЬНЫМИ КОНСТАНТАМИ, КОГДА СВЯЗНЫЕ СПИСКИ СТРОИЛ, ЧТОБЫ НЕ ДЕЛАТЬ ЛИШНИХ ОБЪЯВЛЕНИЙ.
> gc.h
Дальше не читал, но поорал.
Это как с conio
https://en.wikipedia.org/wiki/Justine_Tunney
Categories: ... Transgender and transsexual computer programmers
Разрабом безымянным
Которому реквестов
Никто не заведёт
Теперь я трансоняшка
Мне каждая дворняжка
При встрече сразу
Лапу подает!
А есть ещё процессоры с переключателем набора инструкций типа «ARM» или «NEC V20»?