Как стать автором
Обновить

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

Реверс-инжиниринг не является взломом, хоть и часто используется при взломе.

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

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

Там используется слово "hacked", которое в английском имеет более широкий смысл, не только негативный. В данном случае по смыслу близко "встроил в компилятор C++ 28-летней давности"...

"вкорячил в компилятор C++ 28-летней давности"

Присобачил, короче.

Или "закостылил", потому что "solution can only handle thrown objects of same base class" и прочие радости костылей.

И даже, судя по всему, не ничего не делал с компилятором, а всего лишь написал свои реализации служебных процедур ("хуков"), вызовы которых компилятор генерирует на try/catch/throw.

Я такое делал для MS VC++, который в отладочном режиме умеет вставлять вызовы служебных процедур, проверяющих целостность служебных же данных. Стандартные реализации тянут за собой изрядный объем кода из libc, который не умеет работать в ядре, поэтому бедняги из MS во всех своих ядерных модулях этой возможностью не пользуются, а я уже двадцать лет пользуюсь во весь рост. :)

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

Корявый перевод слова hack.

Боже мой, когда уж стюардессу-то закопают. Имею в виду Watcom.

Очень хорошая стюардесса, что ж вы так

Откапывать и откапывать? ;-)

Подтверждаю, не так давно им вполне коммерческую халтурку сделал :) Все эти современные полупрозрачные графонии и прочие рюшечки, тупо подцепил апи директных дров образца тыща поросятого года и всё кинулось мигать, сверкать и щёлкать так, как заказчик хотел :) А 64 бита там не требовалось, некуда и незачем.

Жив курилка!

Ладно, но потом - закопать!

"Она ещё станцует на моих похоронах!" (c)

Если в архитектуре используется обработка исключение как обработка ошибок, что-то пошло не так.

Wacom ,кстати был оберткой вокруг Си, и в каких-то версиях там бы Сишные структурированные исключения... он копал не в ту сторону ?

Если в архитектуре используется обработка исключение как обработка ошибок, что-то пошло не так.

Можете поподробнее раскрыть свою мысль? А то мне кажется, что по вашему мнению, на исключениях обработку ошибок делать неправильно.

Ну вот в Go возвращают errno на каждом шагу и гордятся этим.

"Возвращают errno" это оксюморон. errno в C это глобальная переменная, которая неявно модифицируется функцией, а не возвращаемое значение. И даже если воспринимать "errno" в широком смысле как "код ошибки", то вы неправы, потому что в Go в качестве ошибки можно возвращать (и на практике возвращаются) не только числа, а любые произвольные объекты с детальной информацией.

errno вполне может быть оберткой вокруг функции, афайк, т.к. требует локальности по отношению к потоку. Правильнее конечно сказать устанавливает. https://man7.org/linux/man-pages/man3/errno.3.html

если код не использует стронние библиотеки, то не надо допускать исключения в своем коде,

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

надо, по мере сил, пытаться не допускать ошибок, которые вызывают исключения, а не наварачивать "модную" обработку ошибок на исключениях, неужели вы этого не знаете?

Ну и как мне открыть файл без вероятности исключений?(замена исключения на errno не рассматриваем)

На всех проектах, где есть either, работать с апи вообще желания нет. Посмотри на kotlin coroutines, dart async. Тут всё сделано для того, чтобы было удобно с исключениями работать. В то же время, если тебе надо сделать несколько последовательных операций с Either, то делай код лесенкой. Хотя мог бы в 1 try catch обернуть

Вот про kotlin coroutines я бы такого не писал, обработка исключений в них сделана просто ужасно и плодит кучу проблем.

А как открытие файла связано с исключениями? В Си++ там все на битах состояния ( good, bad, fail, eof)

Очень сильное утверждение. Но я пожалуй продолжу разрабатывать нормально

интересно, в чем же сила ?

У каждого свое "нормально". Бывает то, что казалось нормальным еще день назад оказывается сегодня уже ни куда не годится, а бывает и наоборот.

Неправильно. Есть паттерн result. В Rust это класс Result, в Scala и Haskell - Either, например. Логика обработки ошибок в идеале должна крутиться вокруг них, так как возможные ошибки вписываются в контракт функции, как и обязательность их обработки. Исключения ломают контракт функций - это по сути еще одно возвращаемое значение, не вписанное в сигнатуру. В Java пытались это решить, сделав декларируемые исключения, но это оказалось неудобным (особенно в свете функционального программирования).

Причем тут Rust, Scala и прочие языки программирования? Давайте притянем за уши еще Брайнфак, в котором обработки ошибок вообще нет.

Обсуждается компилятор C++, в котором исключения архитектурно предназначены в том числе и для обработки ошибок.

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

Я тоже не понял комментарий @MiyuHogosha, поэтому и попросил уточнить его возражения. Исключения сами по себе - это просто инструмент для реализации алгоритма, и не более.
Естественно, функции Сишной библиотеки не должны выбрасывать исключений, даже если они используются внутри компонент в самой библиотеке. Но это не означает, что "Если в архитектуре используется обработка исключение как обработка ошибок, что-то пошло не так."

Я парафразировал Мейерса. Анархист и нв13 даже привелии некоторые из его аргументов. А примеров что у него, что на практике - сотни. Использование исключений оголяет множество подводных камней с RAII, в стандарт даже вносились изменния только ради исправления безвыходных ситуаций, см make_unique или порядок инициализации аргументов функции.

Использование исключений оголяет множество подводных камней с RAII, ...

При реализации RAII в С++ есть подводные камни, которые вскрылись при использовании исключений и ... что? Как по мне, так наоборот, благодаря исключениям были исправлены UB, что сделало поведение программы более детерминированным.

Именно. А еще хуже, что в процессе какой-то файл не был закрыт, ибо этот код скипнули.

Нигде не сказано что они прдназначены для обработки ошибок. они предназначены для обработки exception, что есть слово-враг переводчика, имеющнее еще одно , узко-специализированное значение - удолетворенный протест. Это событие, требующее немедленной реакции без предпринятия каких либо других действий. Обработка состояний ошибок может быть рутинной логикой, в случае исключений программа не может работать дальше и должна занятьсяконтролем повреждений.

в случае исключений программа не может работать дальше и должна заняться контролем повреждений

Да где вы этого начитались?

Исключение, это не ошибка в программе. Исключение, это одна из базовых архитектурных конструкций для реализации алгоритма. Поведение при исключении строго детерминировано и программа продолжает свое выполнение (зависит от реализованного алгоритма), в отличии от Segmentation Fault, при возникновении которого программа просто падает.

С помощью исключений, можно обрабатывать логические ошибки, но никто не запрещает их обрабатывать их с помощью кодов возврата.

Авторы языков Rust, Scala и Haskell сильно постарались для того, чтобы использовать их Result и Either не было больно. Но язык С++ поддерживает только исключения.

std::expected в стандарт попал, а std::optional с 17 стандарта, что намекает, что костыли вокруг местного Result городились много лет.

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

Учавствовал я в одном проекте, где не применяли исключения потому что они медленные (безосновательно абсолютно), а вместо этого возвращали 0 если в цепочке вызовов на 22 уровне стека что-то пошло не так. Но там был си с классами и типичные lib_malloc/lib_free без попыток это как-то обернуть в RAII, с соответствующим результатом сегфолтов в случайные моменты времени.

std::optional-то, может, и с 17 стандарта - но вот хотя бы метод and_then у него появился в том же стандарте, что и std::expected

Однако, в С++ лямбды писать не так удобно как в других языках, и один только and_then не может сделать использование std::expected удобным.

Чтобы конкурировать по удобству с исключениями, монаде Result нужна либо нормальная do нотация (как в Scala и Haskell), либо собственный оператор (как в Rust). В крайнем случае можно припрячь сопрограммы, но тогда непонятно как применять эту штуку в, собственно, сопрограммах.

То есть, реализовать даже в виде библиотеки невозможно?

Сахар в библиотеке добавить невозможно. А не хватает именно сахара.

До 23-го стандарта что тот, что другой, без UB не реализовать. Хотя говорят, что даже вектор нельзя реализовать из-за одной тонкости с созданием объектов без инициализации.

что... в Си++ исклбчения привернули с краю в 90ые, позаимствовав идею из расширения для Си (было несколmько разных, в том числе и мелкомягкое)

Видимо вы не читали Мейерса.

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

Исключения - это исключительные ситуации. ...

Это масло масляное. Исключение, это вполне себе конкретное и детерминированное поведение и они создаются при нормальном выполнении программы, а не возникают "по волшебству" из-за неправильного обращения к памяти или при её нехватке.

И если у вас действительно произойдет ошибка при работе с памятью, то это будет Segmentation Fault, а не исключение.

Не надо писать логику на исключениях, а обработка ошибок - нормально.

В случае работы с вводом\выводом, например сокетами или файлами обработка кодов ошибок и есть часть логики, см. POSIX коды ошибок не являющиеся ошибками. Если вы под обработкой ошибок подразумеваете аварийные ситуации - да, это и есть назначение исключений. В действительности исключение - это неверный устойчивый перевод. Оно использовалось в смысле английского легализа - подтвержденный акт изъявления протеста в суде, когда сказанное должно быть проигнорированно (см. witnesses whose authority is beyond exception).

Watcom же жив в виде Open Watcom с открытым исходным кодом и до сих пор поддерживает DOS.

Ну как жив? Учитывая, что он по своей природе не поддерживает 64-разрядный код, то это уже не очень-то жизнь.

И 64-разрядный DOS не поддерживает?

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

Поправочка: досу пофиг чем там программа после запуска занимается, пусть хоть в 64 бита переключается. Но запускает он 16битные

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

А аналогdos4gw они реализовали?

Рубрика: "Угадай автора новости по заголовку".

У самурая нет цели, только путь.

О, Ватком! С середины 90-х его не видел :)

взломал

Какой невероятно отвратительный перевод слова "hack". Не умеете переводить - не беритесь.

Эта простыня на первом скриншоте до боли напоминает обработку ошибок в Go, но там исключения не планируются :)

Проблема Go не в отсутствии исключений, а в отсутствии sum types и сахара для пробрасывания, по типу ? в Rust или do notation в Haskell. Пробрасывание по значению не обязательно должно быть вербозным. В том же расте высокоуровневый код выглядит так же, как аналогичный на языке с эксепшнами, только приправленный парочкой ?. Особенно если используется anyhow. И при этом отсутствуют все недостатки эксепшнов. Код легко композируется и для каждой функции по сигнатуре понятно, может ли она вернуть ошибку.

Sum types в Go правда тоже не планируются, но это уже упрямость и ошибка авторов. Такая же, как отсутствие дженериков (до недавних пор) и повторение the billion dollar mistake.

Я не очень понял, при чём тут "взломал" и "реверс". Код Watcom же открыли 20 лет назад?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Другие новости