Подтвердить что ты не робот

Какой самый классный взлом вы видели или сделали?

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

Один из самых сложных аппаратных хаков, которые я видел, был сделан бывшим сотрудником в телекоммуникационной компании несколько лет назад. У него было небольшое портативное телевидение в его офисе, и он будет смотреть его весь день, работая. Чтобы уйти от него, он подключил переключатель к включению/выключению, который был активирован через его ногу под его столом.

Какое самое крутое аппаратное или программное обеспечение, которое вы лично видели или сделали? На какой взлом вы сейчас работаете?

4b9b3361

Ответ 1

Я вспоминаю этот взлом как написанный Бобом Смитом, который сделал старый менеджер памяти времен DOS под названием 386MAX (или "386 to Max" ). Это не было частью продукта, это была небольшая утилитная программа, которую он взбивал и где-то размещал. Однако в Интернете единственная ссылка на эту технику, которую я могу найти, - это DDJ Недокументированный уголок из ноябрь 1996 г. Робертом Коллинзом.

Проблема

До того, как Intel представила команду CPUID, было сложно проверить точный тип и уровни пересмотра процессора в вашей системе. Оказывается, что в большинстве версий 386 и более поздних версий на самом деле был идентификатор ЦП, но он был виден только в одно конкретное время: сразу после того, как процессор был reset в регистре EDX. (Предполагалось, что компьютерный BIOS будет единственным программным обеспечением, которое в этом законно заинтересовано).

Проблема: как нормальная программа может получить это значение регистра, если мы не являемся BIOS?

Фоновый материал

Этот хак опирается на шесть отличительных особенностей компьютеров, совместимых с IBM PC. Они были следующими:

  • Начиная с IBM AT и более поздних версий, существует способ независимо отключить адресную строку A20 на шине.
  • Большинство компьютеров не имеют ОЗУ, установленного в очень высоких адресах памяти, чуть ниже BIOS ROM.
  • Большинство компьютеров IBM PC bus возвращают 0xFF, когда вы читаете ячейку памяти, в которой нет установленной памяти.
  • 0xFF 0xFF 0xFF и т.д. является незаконным кодом операции на процессорах Intel.
  • Если вы установите обработчик исключений в память, он выдержит мягкую перезагрузку большинства процессоров этой эпохи (с 386 по 486).
  • При использовании мягких или жестких reset процессоры Intel переходят на адрес, который находится в верхней части адресной памяти, минус 16 байтов, поэтому там размещается BIOS ROM.

В программе сочетаются знания всех этих пустяков для достижения цели.

The Hack

Результатом стала программа командной строки DOS, которая сделала следующее:

  • Установлен нелегальный обработчик исключений opcode
  • Отключила адресную строку A20 на шине
  • Мягкая перезагрузка CPU (я думаю, это было вызвано вызовом BIOS)

Когда была выполнена мягкая перезагрузка, процессор попытался бы перейти в верхнюю часть памяти минус 16 байт, где находится код запуска ПЗУ. Однако, поскольку A20 был выключен, он фактически переместился бы на вершину памяти минус 16 байт минус один мегабайт. На большинстве ПК там нет ОЗУ. Таким образом, он выберет серию байтов 0xFF из этой несуществующей ОЗУ и попытается ее выполнить. Это создаст незаконное исключение кода операции.

Его обработчик исключений затем вырвет значение EDX (CPUID) и запустит его где-нибудь, где он сможет его найти. Затем он очистит беспорядок (верните A20 обратно, откиньтесь из защищенного режима в реальный режим для DOS) и верните управление в исходный код.

Когда это сработало, это был гений. Voila, здесь была простая программа DOS для командной строки, которая даст вам значение CPUID.

Конечно, неизбежно были ПК, которые были "не совсем совместимы", которые ужасно рушились, когда вы это запустили. Хорошо.

Ответ 3

Ну, это не самое крутое, но это определенно забавно (для программистов).

Мы построили ad-hoc query builder для проекта базы данных резюме. В нем были некоторые элементы ajaxy, и основная идея заключалась в том, что если вы изменили что-либо на странице, поиск автоматически снова запустится. (Это было вызвано событием onBlur всех виджетов пользовательского интерфейса)

Таким образом, у нас не было реального использования для кнопки "Поиск" или "Выполнить запрос". Это путало пользователей без конца. Поэтому мы добавили кнопку поиска, которая ничего не сделала. Он просто сидел там.

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

Это сделало нашу пользовательскую базу очень счастливой. Простые вещи.

Ответ 4

Это был не хак, который я сделал, а скорее кто-то, с кем я работал, давным-давно сказал мне об этом (он действительно сделал взлом).

Кажется, он работал на кого-то, кто был слепым и кому нужен способ читать текстовые файлы. Поэтому он понял, как перевести текстовые файлы на шрифт Брайля и распечатать их, используя различные символы, такие как. и:

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

Конечно, акт чтения устранял депрессии, поэтому он был механизмом чтения-раз, но я всегда думал, что это довольно классный хак.

Ответ 5

Во время работы с обратным проектированием iPhone я обнаружил уязвимость в базовой полосе (чип, который обрабатывает телефонию и блокировку оператора), что позволит вам произвольно писать нули. Хотя сначала это казалось бесполезным, быстро стало очевидно, что это может сделать гораздо больше, чем я изначально думал. Благодаря тому, как работает ARM, некоторые скачки могут быть сведены к нулю путем записи единственного нуля в цель, в результате чего путь выполнения всегда будет продолжать двигаться вперед. Это позволило разблокировать программное обеспечение, но было быстро заменено более надежным взломом, который позволил вам полностью перекрыть базовую полосу.

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

Ответ 6

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

Ответ 7

Это такая тривиальная вещь, но когда я впервые увидел этот код (моим разработчиком), я был потрясен, потому что это то, о чем я бы никогда не подумал (комментарии, добавленные мной):

cglobal x264_sub8x8_dct_sse2, 3,3  ;3,3 means 3 arguments and 3 registers used
.skip_prologue:
    call .8x4
    add  r0, 64                    ;increment pointers
    add  r1, 4*FENC_STRIDE
    add  r2, 4*FDEC_STRIDE
.8x4:
    SUB_DCT4 2x4x4W                ;this macro does the actual transform
    movhps [r0+32], m0             ;store second half of output data
    movhps [r0+40], m1             ;the rest is done in the macro
    movhps [r0+48], m2
    movhps [r0+56], m3
    ret

Он делает блок 8x8 из 4 преобразований, выполняя наборы 8x4 за раз. Но он не вставляет код дважды (что будет впустую размер кода), а также не имеет функции 8x4 и вызывает его дважды. У него тоже нет петли. Вместо этого он вызывает "функцию", а затем увеличивает указатели, а затем "падает" прямо на него и делает это снова.

Он получает лучшее из обоих миров: нет функции, вызывающей надстройку за пределами оригинала (поскольку указатели r0, r1 и r2 не увеличиваются в SUB_DCT4), а также не дублируются коды и нет накладных расходов цикла.

Ответ 8

Этим летом я написал игру, которую я назвал SatelliteRush. Это игра Breakout для мобильных телефонов с Java и GPS. Его можно воспроизводить в двух режимах: "скучный режим" и "спутниковый режим". В скучном режиме вы используете кнопки для перемещения весла, как обычно, но в спутниковом режиме он использует приемник GPS телефона. Вы бегаете туда и обратно, и весло двигается вместе с вами.

Я тестировал его только на Sony-Ericsson W760i, и он работает достаточно хорошо, учитывая, что обновления GPS-координат довольно медленные и неточные.

До сих пор я сделал "техническую тестовую версию" этой игры, поэтому она не очень красива или проста в использовании. Но если у вас есть GPS-телефон с Java, вы можете скачать его здесь: http://www.lysator.liu.se/~padrone/temporary/SatelliteRushTest/

EDIT:

Теперь доступно для Android в качестве бесплатного приложения на Android Market: https://market.android.com/details?id=se.nekotronic.satelliterush

Ответ 11

У меня есть ранний компьютер Commodore 64, и ему нужно написать для него код сборки.

Проблема заключалась в том, что для C64 не было ассемблерной программы (либо это, либо я не мог себе этого позволить).

Итак, я написал ассемблер, просмотрев коды опций 6502 в книге и создав программу из необработанных байтов.

В какой-то момент он смог взять ассемблерный код в качестве своего входа и скомпоновать в программу.

Мой друг написал дизассемблер для своего ПЭТ на Бейсике. Я использовал эту программу, чтобы разобрать мой ассемблер, а затем смог использовать мой ассемблер для сборки более новых версий.

О, обручи, которые нам пришлось перескакивать в старые времена:)

Ответ 12

Самый классный хак (и это не действительно взломать истинный смысл этого слова, но он проходит, как и некоторые из вышеперечисленных ответов), которые я когда-либо создавал, был на моем Apple//e.

В справочном руководстве была одна строка, в которой $C010 был флагом "любой ключ вниз".

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

То, что они не сказали вам, и все узнали, что это нелегко, было то, что не было надежного способа узнать, что нажата клавиша WHAT.

Если вы написали небольшую сборку... (помилуй мои ошибки, моя сборка 6502 очень ржавая)

  :1
  lda $C010
  cmp #$80
  bcc :1  ; branch if less than? I forget how to do that.
  lda $C000
  jsr $FDF0   ;output the accumulator value to the screen

Таким образом, он будет зацикливаться до тех пор, пока вы не нажмете клавишу и не выведете ключ, загрузив из переключателя чтения клавиатуры $C000.

Но если вы запустили эту программу, это будет не совсем правильно.

Это наверняка вывело бы что-то, пока вы держали ключ, и ничего не было, когда вы не были, но где-то там было небольшое отставание (я думаю, я не парень-аппаратчик), поэтому, если вы нажали ' f 'вы получите много f. Но если вы остановились, затем нажмите "g", вы получите кучу "f", прежде чем перейти к "g".

Вы можете увидеть доказательства этой проблемы в яблоке] [версия Gauntlet, вы двигались в одном направлении, и если бы вы попытались двигаться во втором направлении, вы немного двинетесь в исходном направлении, пока вы прошли лаг.

Это не имело никакого смысла, потому что чтение $C000 всегда было на 100% точным, если только вы не пинговали $C010.

Я нашел эту проблему увлекательной, и после нескольких недель игры я наконец придумал то, что я до сих пор считаю самой крутой программой, которую я когда-либо писал.

Сама программа не имела смысла, она сделала несколько бесполезных ORA, но по какой-то причине она сработала, и она дала правильные значения из $C000 после запроса $C010.

Так здорово, что я написал статью для журнала nibble, которую они приняли, но никогда не публиковались (либо потому, что они вышли из бизнеса, либо потому, что статья читается так, как написано 15-летним, что это было), где я написал заменяющую программу ввода с клавиатуры и подключил ее к нулевой странице, которую все зовут, чтобы получить ввод с клавиатуры, и я смог программно изменить задержку повторения клавиатуры и скорость повтора, что было иначе невозможно, поскольку оно было подключено к аппаратной части. Разумеется, Apple//e вышла в этот момент, но по сей день, самый классный хак.

Обновление 3/2/2010: Пройдя несколько старых документов, я нашел распечатку моей небольшой процедуры сборки. Я размещаю его здесь, чтобы узнать, может ли кто-нибудь понять, почему он работает, и поэтому он будет навсегда сохранен в цифровой форме где-то...

$0300  AD 10 C0  LDA $C010  ; load accumulator with any-key-down flag
$0303  29 80     AND #$80   ; keep only high bit flag
$0305  0D 00 C0  ORA $C000  ; OR accumulate with keyboard soft switch
$0308  10 F9     BPL $0303  ; erm, I forget exactly which branch this is
$030A  09 80     ORA #$80   ; turn the high bit on 
$030C  20 ED FD  JSR $FDED  ; print char in accumulator
$030F  4C 00 30  JMP $0300  ; start again.

Не имеет никакого смысла, почему это должно работать, но это так. Или сделал. 25 лет назад.

Ответ 13

Быстрый обратный квадратный корень - причудливая маленькая рутина, которая каким-то образом позволяет вычислить обратный квадратный корень чего-то, но вы никогда не догадаетесь, что посмотрите на нее.

http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/

Ответ 14

Друг мой заменил материнскую плату в его Dell новой, более быстрой, материнской платой OEM. Однако он не мог заставить кнопку питания и другие элементы передней панели работать - разъемы были разных размеров, с разным расположением контактов. Я взял кучу запасных перемычек и запасных проводов и подключил соответствующие контакты один за другим. Не требуется пайка:)

По коду, меня постоянно впечатляют. Я всегда думал, что нет элегантного способа определить, успешно ли был fork ed child exec ed, но там .

ребенок:

execvp(argv[0], argv);
errval = errno;
write(data->fd, &errval, sizeof(errval));

Родитель:

socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
flag = fcntl(fds[1], F_GETFD) | FD_CLOEXEC;
fcntl(fds[1], F_SETFD, flag);
pid = clone(child, NULL, SIGCHLD, NULL);
if(pid < 0){
        ...
}
close(fds[1]);
/* Read the errno value from the child, if the exec failed, or get 0 if
 * the exec succeeded because the pipe fd was set as close-on-exec.
 */
n = read(fds[0], &ret, sizeof(ret));
if (n < 0) {
        ...
} else if(n != 0){
        /* exec failed */
} else {
        /* exec succeeded */
}

Ответ 17

Мы были скомпрометированы в небольшой компании, в которой работали некоторые якобы российские хакеры. Мне и другим разработчикам хотелось посмотреть, как, и поэтому я снял самый элегантный PHP script, который я когда-либо видел с нашего сервера, и быстро удалил его с нашей живой машины.

Это был троянский конь, называемый c99shell, который сделал так много с таким маленьким, что одновременно было одновременно и ужасно, и красиво. У этого был встроенный графический интерфейс с изображениями с использованием base64 для вывода их из PHP, поэтому все было само собой. Список функций был болен! Эта вещь может запускать оболочки, проверять строки подключения, блокировать себя и ряд других полезных вещей для злоумышленника.

Это было прекрасно.

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

Ответ 19

Я бы сказал вам, но они могут захотеть получить мой диплом о высшем образовании, если я признаюсь в этом;)

Ответ 20

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

Все демо-приложение было написано на языке C и ассемблере. Он подключил таймер и клавиатурные прерывания для взаимодействия с приложением. Я написал все, включая библиотеку окон.

Ответ 21

Я однажды взломал простую командную строку dos-style для psion 3a во время университетской лекции. Он мог делать только основной список каталогов, просмотр, копирование и перемещение, но он выглядел как часть - полноэкранный небольшой шрифт.

О, и я запрограммировал понг для 68008 с горшками для ввода и осциллографом для вывода. Не так сложно использовать Dev-Board, но было что-то классное в том, чтобы играть в него на osc.

Ответ 22

Я написал простой пакетный файл Windows, чтобы позволить мне быстро воспроизводить дорожки, соответствующие некоторым шаблонам, из моей музыкальной библиотеки (на f: drive) на болезненно медленной машине (открытие iTunes занимает около 3 минут на этой машине!). Он поддерживает регулярные выражения с помощью команды findstr и использует mplayer для воспроизведения дорожек. Все, что мне нужно сделать, это нажать Windows + R и напечатать:

play u2

или

play "neighbo.+rhood"

или

play "blink[0-9][0-9][0-9]"

Пакетный файл выглядит так: play.bat.

cd /d f:
findstr /I /R %1 dirlist.txt > playlist.txt
mplayer -playlist playlist.txt

Оба mplayer и play.bat должны быть добавлены к вашему пути.

Ответ 23

Не сделал я, конечно, но недавно я наткнулся на это, и это выглядело круто:

Самостоятельная игра жизни в С#

"Conways Game of Life увлекает компьютерных ученых на протяжении десятилетий. Несмотря на то, что ее правила смехотворно просты, вселенная Conways порождает множество планеров, космических кораблей, осцилляторов, планер-пушек и других форм" жизни ". программы печати аналогичны любопытству и, что довольно удивительно, имеют важное место в теории вычислений.

Что происходит, когда вы объединяете два? Вы собираетесь это выяснить, но одно можно сказать наверняка: фактор geekiness должен быть довольно высоким.

Я написал небольшую программу на С#, содержащую сетку Game-of-Life. Программа продвигает сетку игр к следующему поколению и распечатывает свою копию с обновленной сеткой. Вы можете взять вывод, скомпилировать его с помощью компилятора С#, запустить его, и вы получите следующее поколение игры. Вы можете выполнить итерацию процесса или вручную изменить начальное состояние сетки. "

Следуйте приведенной выше ссылке для исходного кода.

Ответ 24

Несколько лет назад я разрабатывал веб-интерфейс и использовал некоторые совершенно новые JS-библиотеки для функциональности AJAX. В lib только eval'd JS, который был в заголовке html doc, но было слишком много данных, которые возвращались, чтобы вписаться в заголовок. Что делать?

Некоторые выскакивают, что JS в заголовке имеет доступ к телу html-документа, поэтому я написал общую функцию eval the body, которая была возвращена в заголовке. Очень полезно в то время, особенно b/c другой JS lib, мы оценивали только eval'd JS из тела, поэтому это было совместимо для обеих JS-библиотек и избегало любых ограничений размера из заголовка!

Да, просто, но я чувствовал себя довольно устрашающим в течение целого месяца после выяснения этого:)

Ответ 25

Я написал ассемблер для небольшой виртуальной машины (UDVM) с Excel и Visual Basic. Вы пишете код сборки в ячейках Excel и макет памяти на другом листе, а затем внизу вычисляете двоичные строки машинного кода. Представьте себе страх ручной сборки при каждом изменении кода сборки.

Ответ 26

После нескольких дней отладки сервера удаленного доступа, который испытывал недопустимое количество отброшенных вызовов, я проследил эту проблему до самодельного механизма аутентификации, который зависел от текстового представления запущенного getty PID. getty генерирует ошибку и отменяет, если в ее PID содержится четное число, за которым следует 9, заставляя вызов отбрасываться, а getty - с обновленным PID.

После того, как проблема была идентифицирована, я был снят с проекта и позже обнаружил, что "исправление" заключается в изменении преобразования числового текста в текст из

sprintf(strval, "%d", pid);

к

sprintf(strval, "%o", pid);

Вместо того, чтобы устранять неполадки в процедуре аутентификации, кто-то решил преобразовать PID в восьмеричный, что делает невозможным содержать 9!

Ответ 27

И программа самопечати ('quine') в С#, длиной 149 символов:

С# Quine

class P{static void Main(){var S="class P{{static void Main(){{var S={1}{0}{1};System.Console.Write(S,S,’{1}’);}}}}";System.Console.Write(S,S,‘"‘);}}

Ответ 28

Увидев моего бывшего товарища по команде, переписывая игрушку на один 3D-движок в течение трех недель с нуля на ассемблере. Старая была медленной, и у нас не было времени больше менять графические активы. Он начал переписывать за два месяца до крайнего срока.

Это был тот же парень (и некоторые другие чуваки - это был акт командной работы), который сделал потрясающую работу, набив 10 минут графики и звука в исполняемый файл размером 64 КБ.

http://pouet.net/prod.php?which=1221

Ответ 29

Когда вы смотрите, как использовать TCP в 4D, я применил этот вариант Duff Device в документации:

$SentOK:=False  //A flag to indicate if we made it through all of the calls
Case of 
   : (SMTP_New ($smtp_id)!=0)
   : (SMTP_Host ($smtp_id;<>pref_Server)!=0)
   : (SMTP_From ($smtp_id;vFrom)!=0)
   : (SMTP_To ($smtp_id;vTo)!=0)
   : (SMTP_Subject ($smtp_id;vSubject)!=0)
   : (SMTP_Body ($smtp_id;vMessage)!=0)
   : (SMTP_Send ($smtp_id)!=0)
Else 
   $SentOK:=True  //message was composed and mailed successfully
End case 
If ($smtp_id!=0)  //If a Message Envelope was created we should clear it now
   $OK:=SMTP_Clear ($smtp_id)
End if 

Я посмотрел на него и подумал, что это действительно умно (я все еще это делаю). К сожалению, это было не то, что мне было нужно, и у меня не было возможности использовать его.

Ответ 30

Не я:

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]){
  int i;

  printf("((((");
  for(i=1;i!=argc;i++){
    if(     strcmp(argv[i], "^")==0) printf(")^(");
    else if(strcmp(argv[i], "*")==0) printf("))*((");
    else if(strcmp(argv[i], "/")==0) printf("))/((");
    else if(strcmp(argv[i], "+")==0) printf(")))+(((");
    else if(strcmp(argv[i], "-")==0) printf(")))-(((");
    else                             printf("%s", argv[i]);
  }
  printf("))))\n");
  return 0;
}