2016-03-23 1 views
1

Можем ли мы пойти короче (персонаж-накрест) или более элегантно, чем:Кратчайший C++ код, чтобы вызвать нарушение прав доступа

*(int*)0=0; 

Цель состоит в том, чтобы поднять нарушение прав доступа. Предпочтительными являются независимые от платформы решения.

+2

Если вы скрываете один символ typedef в другом месте (возможно, параметр шаблона), вы можете сохранить 2 символа со своего пути. – o11c

ответ

2

Предполагая, что вы не в том числе включает в свой характер подсчитывать

Для Linux:

raise(11); //SIGSEGV 

Для Windows:

raise(SIGSEGV); // I don't know the SIGSEGV value for sure so more characters required 
+1

Для Windows это не так коротка и сладка: RaiseException (STATUS_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL); https://msdn.microsoft.com/en-us/library/windows/desktop/ms680552(v=vs.85).aspx –

+1

Ну, он находится здесь: https://msdn.microsoft.com/en-us /library/dwwzkt4c.aspx – MasterID

+0

Вы должны любить команду-сборную :) –

0

С Unix (в основном Linux) перспектива:

Если мы определим «нарушение доступа» как «любой сигнал», который заполняет si_addr поле siginfo_t, то согласно sigaction(2) что есть: SIGILL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP.

  • SIGILL может быть получен путем выполнения какой-либо недопустимая команды, в том числе, постоянно недействительных инструкции, такие как ud2 на x86 (в кодировке 0x0F 0x0B), но прыгает в случайный момент часто порождает это в любом случае.

  • SIGFPE может быть получен путем деления любого целого числа от 0 или деления наиболее отрицательного числа на -1

  • SIGSEGV может быть получено путем чтением или записи любому некартированным или PROT_NONE «D-страницы или запись в страницу только для чтения.

  • SIGBUS Я никогда не выяснял, откуда он.

  • SIGTRAP могут быть сгенерированы точки останова инструкции вашего ARCH, который на x86 является int3, который является один байт 0xcc. С одной точки зрения это самый короткий код. Если вы настаиваете на том, что вы можете сделать код C, вам придется обернуть его в блок asm в соответствии с капризами вашего компилятора.

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

+0

рейз (SIGSEGV); кажется ближе всего, но код не короче. –

1

Не существует переносного способа нарушения сегментации или другой подобной ошибки.

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

if (x == 5) 
{ 
    std::cout << "Gonna crash"; 
    *(int*)0 = 42; 
} 

Компилятор может перевести этот блок кода на no-op.

raise(SIGSEGV) может быть или не быть причиной фактического нарушения, но это единственный переносной способ заставить программу вести себя , как если бы произошло нарушение.

+0

Какой компилятор будет делать это? Любой из GCC, MSVC, XCode или Clang? –

+0

Я не знаю текущего компилятора, который делает именно это, но некоторые делают очень похожие вещи. Посмотрите [здесь] (http://ideone.com/gilyHa). Программа должна была разбиться на третьей итерации, не так ли? И почему конец цикла не заканчивается? –

+0

clang предупредит вас, что «косвенность нулевой указатель нулевой последовательности будет удалена, а не ловушка», но AFAICT фактически не удалит косвенное. См. [This] (https://llvm.org/bugs/show_bug.cgi?id=23831) –

1

Вот ближе всего я мог бы прийти, используя другой подход, с ОР и MasterID:

asm("ret");

Идея заключается в том, чтобы управлять стеком, как неумело, насколько это возможно. Я считаю, что gcc скомпилирует это.

Смежные вопросы