Выполнение кода эксплойт Cortex M4

Для тестирования MPU и игры с эксплойтами я хочу выполнить код из локального буфера, работающего на моей плате разработчиков STM32F4.

int main(void)
{
  uint16_t func[] = { 0x0301f103, 0x0301f103, 0x0301f103 };
  MPU->CTRL = 0;
  unsigned int address = (void*)&func+1;
  asm volatile(
    "mov r4,%0\n"
    "ldr pc, [r4]\n"
    :    
    : "r"(address)    
  ); 
  while(1);
}

В основном у меня первая очередь из МПУ. В func хранятся мои инструкции. В части ASM я загружаю адрес (0x2001ffe8 +1 для большого пальца) в регистр счетчика программ. При пошаговом выполнении кода с помощью GDB в R4 правильное значение сохраняется и затем передается в регистр ПК. Но тогда я окажусь в HardFault Handler.

Редактировать: стек выглядит так:

0x2001ffe8: 0x0301f103  0x0301f103  0x0301f103  0x2001ffe9

Инструкции верны в памяти. В "Полном руководстве по Cortex" сказано, что регион 0x20000000–0x3FFFFFFF - это SRAM, и "этот регион является исполняемым, поэтому вы можете скопировать здесь программный код и выполнить его".

1 ответ

Решение

Вы назначаете 32-битные значения 16-битному массиву.

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

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

Посмотрите на инструкцию BX для этого, а не ldr pc

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

Компилятор также должен жаловаться, что вы присваиваете void* переменной без знака, так что здесь требуется тип-трансляция.

По привычке я рекомендую адрес |=1, а не +=1, в этом случае любой из них будет работать.

Другие вопросы по тегам