Пользователь
Информация
- В рейтинге
- 1 936-й
- Откуда
- Петропавловск, Северо-Казахстанская обл., Казахстан
- Зарегистрирован
- Активность
Специализация
Десктоп разработчик, Инженер встраиваемых систем
Pure C
Assembler
X86 asm
Win32 API
Visual Basic
MySQL
Git
ООП
Разработка электроники
Обратная разработка
Какие политкорректные заменители для слов «чернокнижник» и «белогвардеец»?
В отрыве от правильных слов о разнице между UCS-2 и UTF-16, хочется сказать, что решение засунуть эмодзи в юникод я считаю абсолютно идиотской инициативой.
Тоже, но в меньшей степени относится к включению туда всяких мёртвых вариантов письменности, которые в последний раз использовались в 12 веке, а сейчас интересуют только археологов и палеолингвистов.
Само ограничение в 64К символов и возможность умещаться в 2 байта на символ и иметь прозрачное преобразование индекса символа в смещение в байтах и возможность сканировать строку, просто перебирая 16-битные слова — она очень соблазнительная и дорогого стоит.
Почему тупо? Переменный это циклическое сокращение и расслабление мышц — 100 раз в секунду (для 50 Гц сети), а постоянный — мышцы напряглись и остались в таком напряжённом состоянии до снятия приложенного напряжения. Не тупо нагрев.
Пожалуйста, запомните и постарайтесь больше никогда не писать «электропередач». Линии электропередач — это такая же нелепость, как трубы теплоснабжений, шахты вентиляций, заведения здравоохранений, органы правопорядков, стояки канализаций. Подобно тому, как слова «теплоснабжение», «канализация», «вентиляция», «здравоохранение» и «правопорядок» обозначают либо какой-то организованный непрерывный процесс, либо концептуальное понятие, точно также и «электропередача» означает непрерывнй глобальный процесс передачи электроэнергии от генерирующих объектов к объектам-потребителям.
Это только в телевизоре и на радио есть «программа телепередач», а в электроэнергетике нет никаких «электропередач» во множеством числе, а есть электропередача как глобальное явление. Электропередача — то же, что и энергоснабжение. Вы слышали что-нибудь про «линии энергоснабжений»? В сфере радио аналогичным термином было бы «радиовещение». Вы можете говорить о «программе телепередач», но вы не можете говорить о «графике радиовещаний».
Чрезвычайно распространённая оговорка «линии электропередач» является, по видимому, попыткой натянуть
сову на глобус«программу телепередач» на электроснабжение.Другое известный мне случай, когда словосочатению так же не повезло — это министерство путей сообщений, которое на самом деле министерство путей сообщения, где сообщение — это тоже не посылка и не SMS-ка, а концептуальное понятие транспортной взаимосвязанности.
А модель какая?
Я сижу на XP, и должен сказать, что вы преукрашиваете. 95—98% сайтов работают без проблем. Либо я принципиально какими-то не теми сайтами интересуюсь.
Не так давно истёк срок действия одного сертификата корневного центра сертификации: но это проблема сертификата, а не самой XP. Достаточно было установить в хранилище доверенных сертификаторов сертификат нового Root CA, на котором сейчас всё зиждется из того, что раньше базировалось на старом.
С Хромом есть проблема в том, что он полагается на системную SSL-релизацию, а она не умеет работать с некоторыми алгоритмами. Но в таких случаях я переключаюсь на FireFox — у него своя внутренняя независимая реализация SSL/HTTPS.
По поводу невозможности обновить браузеры: это действительно боль. Есть мнение, что во многих случаях ограничение на минимальную версию ОС чисто искуственное, «политически мотивированное», нежели техническое. Кстати говоря, слышал, что есть некая китайская сборка Chromium, которая отлично работает на XP.
Не могу достоверно сказать на счёт браузеров, но могу рассказать интересную историю насчёт Process Explorer от Марка Руссиновича. Начиная с какой-то версии Process Explorer перестал корректно работать на Windows XP.
Я нашёл на форумах поддержки SysInternals тему на этот счёт, где представители компании говорили, что они ну никак не могут обеспечить работоспособность новых версий под Windows XP.
Тогда я вычислил ту версию, начиная с которой оно интерфейс программы под Windows XP поломался, и стал реверс-инжинирить и отлаживать её, чтобы понять, что же такого принципиально нового они там начали использовать, что нельзя получать под Windows XP малой кровью? Может быть новомодный (гореть ему в аду) интерфейс aka Ribbin (резиновая лента)? Но нет, судя по скриншотам, никакой резиновой ленты там нет.
В итоге, разгадка оказалась банальной, неожиданной и разочаровывающей.
Начиная с какого-то момента в comctl32.dll была добавлена новая функциональность и в некоторых структуры были добавлены новые поля. Соответственно, в заголовочные файлы, где объявлены функции/макросы/структуры, имеющие отношение к comctl, были внесены изменения: добавлены новые поля, но всё это было заключены #if...#endif макросы, так, чтобы старый код, не знающий о новых фишках, мог нормально компилироваться.
Часто используемой практикой у Microsoft является то, что структуры, в которые планируется добавление новых полей, имеют первым полем поле cbSize, чтобы сообщить API-функциям, в которые будет передаваться указатель на структуру, о том, какой «версией» структры пользуется вызывающая сторона: сколько полей она правильно инициализировала и сколько полей вызываемая API-функция имеет право модифицировать, чтобы не испортить соседние не относящиеся к структуре данные.
При этом реализация comctl32.dll, какой бы новой она ни была, всегда умеет корректно работать со «старыми версиями» структур, у которых было меньше полей, потому что в ином случае все старые программы под новой версией Windows переставали бы работать.
Так вот, начиная с какого-то момента при компилировании Process Explorer они стали пользоваться новым комплектом заголовочны файлах, и установили константы/флагми условной компиляции так, чтобы сообщить компилятору «да, мы хотим использовать вот эту новую версию структуры с новыми полями».
По факту же никакие новые фишки, даруемые новой версией библиотеки comctl32.dll они не использовали. Никакие новые поля, добавленные в структуру в новой версии, они тоже не использовали.
Они вообще никак не были завязаны на новые возможности новой версии comctl32.dll. Но они задали макрос _WIN32_WINNT таким, что в структуре появились новые поля, а от этого изменилось выражение sizeof(SOMECOMCTLRELATEDSTRUCT).
И когда программа скомпилированная с такими ключами условной компиляции попадала под Windows XP, она передавала в comctl-шные функции структуру, у которой первое поле cbSize оказывалось ниожиданно большим для XP-шной версии библиотеки, и эти API-функции отказывались работать с такой «новой» формой структуры.
Можно было бы возразить: мало ли по какой другой причине им потребовалось задать значение _WIN32_WINNT таким большим? Они эти сделали для совершенно других целей, не связанных с comctl32.dll, а работа с контролами пострадата просто засчёт того, что доп. поля были в #if...#endif-зависимости от значения _WIN32_WINNT.
Но специально для избежания таких случаев в тех же заголовочных файлах были предусмотрены специальные
константымакросы для определения sizeof структуры в зависимости от того, какую именно версию библиотеки comctl32.dll ожидает увидеть вызывающая сторона.Я написал Руссиновичу письмо с результатми своего исследованиея и предложением о том, что всё проблема решается банальной заменой:
xxx.cbSize = sizeof(XXXXXX);
наxxx.cbSize = XXXX_V6_SIZE;
Руссинович ответил, что всё так, но они, тем не менее, не будут ничего менять, потому что они просто принципиально не хотят чтобы эта поддержка Windows XP у них была.
То есть то, что начиная с какой-то версии Process Explorer перестал корректно работать под XP — это не потому, что в него добавили какую-то функциональность, которой нет под XP. Это просто бюрократический препон.
Я думаю, что тот факт, что я пользуюсь ADSL через медную пару говорит в пользу того, что эта медная пара идёт не в ближайший шкаф с голосовым шлюзом, а на АТС, где стоят DSLAM-ы и прочая DSL-специфичная аппаратура.
Но даже если бы медная пара шла в голосовой шлюз, а дальше бы шла оптика, разве это отменяет возможность организовывать линк в условиях чрезвычайного положения через диалап-модему, коль скоро стационарные телефоны продолжали работать, тогда как интернет и сотовая связь были тотально отключены?
Не трудно. Трудно найти человека, который догадывается, что имея два модема можно соединить два разнесённых компьютера компьютера и для этого не нужен интернет-провайдер.
Это если у вас два хоста звонят друг другу. А теперь представьте жилой дом, внутри которого LAN (а во многих домах такое осталось с нулевых годов), и десяток квартир в одном доме дозваниваются в такие же квартиры ближайших домов, внутри которых все квартиры тоже связаны своими локальными сетями.
В первые часы отключения сотовой связи она была отключена так, что телефон тупо не видел базовых станций. Как будто базовые станции обесточили. Боюсь, что и звонки в скорую и другие экстренные службы в таком случае были бы недоступны. Только на второй-третий день телефоны начали видеть сеть оператора, а связь резалась уже на уровне маршрутизации звонков, то есть звонок шёл, но не достигал цели.
Так что люди, которые понадеялись на мобильную связь, сильно переоценили её бесперебойность. Впрочем, и городскую телефонию могли отключить при желании.
Когда недавно в Казахстане случилось многодневное тотальное отключение интернета, я сожалел, что многие поспешили выкинуть диалап-модемы и забыть, как это и что это. А ведь городской телефон не отключали, и дозваниваюсь друг-другу люди могли бы получить какую-то пусть и щаторможенную, но тем не менее работающую среду для обмена информацией. Хотя бы емейлами.
У меня и проводной стационарный телефон остался и используется, и диалап-модемы лежат, но что толку с того, если кроме тебя почти никто не знает, как с помощью двух этих вещей организовать линк.
Увы, это не работает. Шлёшь письмо с 6 пронумерованными вопросами, получаешь ответ из одного-двух предложений без нумерации, которые оказываются ответом на первый (как правило) или на последний вопрос.
Твиттеризм головного мозга, не иначе.
А потом мы видим статьи «Почему в современном софте всё всрато»...
С ключом /Gy- компилируйте, пожалуйста, чтобы говорить о порядке следования функций в пределах секции, а не о порядке вывода секций dumpbin-ом.
Вы obj-файл дампите (dumpbin-ом, например) и смотрите какой там порядок следования сущностей, а не конечный результат, который на свет производится линкером.
Внедрять CPP-код — это нечто.
Уважаю Рэймонда Чена, но в данном случае он напускает жуть там, где не нужно.
Есть такая гарантия: компилятор генерирует сущности машинного кода в строгом соответствии с тем, кем они фигурировали в исходном файле.
И действительно, но COMDAT folding выполняется линкером и только тогда, когда указана опция /OPT:ICF. Уже при /OPT:REF линкер может только выкидывать сущности, которые нигде не referenced, но не сливать (merge) их и не переставлять по своему усмотрению. Но у нас к RemoteThreadProc и EndOfRemoteThreadProc точно есть обращения, так что выкинуты они не будут. Казалось бы, я хочу посоветовать отключить COMDAT Folding, чтобы гарантировать работоспособность кода? Но тогда мы потеряем неплохую оптимизацию в пределах всего бинарника.
На самом деле, всё гораздо проще и лучше. Не надо глобально отключать COMDAT folding в процессе линковки. Чтобы COMDAT folding мог выкидывать или медждить ненужные или дублирующиеся куски объектных файлов, сам объектный файл должен быть сгененирован компилятором с использованием так называемого function-level linking (ключ /Gy компилятора), при котором каждая функция, каждая vftable, каждая переменная помещаеются в OBJ-файл упакованными в отдельную COMDAT-секцию.
Но если не указывать ключ /Gy и не использовать function-level linking, а мы можем сделать это для одного отдельно взятого исходного файла, то компилятор всю начинку, например, все процедуры положить в одну монолитную секцию .text. И линкер с такой монолитной секцией (где сразу куча процедур) ничего не сможет и не будет делать: они либо откинет всю секцию целиком, если ни на одну сущность из неё нигде больше нет ссылок, либо всю секцию целиком включит в состав выходного исполняемого файла.
То есть внедряемую процедуру и процедуру конца маркера мы выносим в отдельный .c/.cpp файл и только этот отдельный файл компилируем с /Gy-, а все остальные можем по прежнему компилировать с /Gy и использовать /OPT:ICF при линковке.
Может. А может и не может: нужно посмотреть, нет ли тонких настроек PGO, позволяющих не перекраивать отдельные фрагменты программы. Но есть кое что, что точно остановит PGO от «расколбашивания» нашей маленькой внедряемой процедуры по всему образу. PGO никогда не переставляет ничего между секциями. Вся хирургия и всё перекраивание происходит в пределах одной секции.
Поэтому волшебная #pragma alloc_text() с указанием секции «.inject» вынесла бы внедряемую и маркерную процедуру в отдельную секцию, и они бы гарантированно остались в пределах секции. Собственно, тогда и маркерная процедура не нужна: внеднять в чужой процесс целесообразно секцию целиком.
Тактика «внедряем секцию целиком» решила бы даже ранее упомянутые проблему перефрагментированности кода с помощью PGO, если бы мы её отдельно не решали.
Более того, она бы решила и проблему, которую Чен описал позже: проблему выравниваний для отдельных архитектур. Секция и вся начинка гарантированно имела бы правильное выравнивание, а выделяя под неё память в АП чужого процесса, мы бы выделяли правильной границы выравнивания (по другому VirtualAlloc и не может работать в принципе).
Может. Но инлайнинг можно отключить ключами при компилировании каждого отдельного исходного файла. И поместив внедряемый код в отдельный исходник, мы можем его скомпилировать так, чтобы инлайнинг был запрещён.
Очевидно, что LoadLibrary слишком «громкий» способ внедрения в другой процесс для антивирусного ПО. Подозрительный процесс, вирусный или заражённый вирусом, может воспрепятствовать внедрению в себя со стороны подобным способом одним из множества способов.
У меня бы члены подобного энума имели бы префикс «IR_». И от таких эксцессов защищает, и немного повышает читаемость и самодокументируемость кода.
ASLR появилась в Windows Vista, а это 2007 год. До введения ASLR делать подобное поведение дефолтным не имело никакого смысла, а значит дефолтным оно могло стать не более, чем 13 лет назад. Этому предшествовало как минимум 17 лет существования Microsoft-овского линкера с совершенно другим дефолтным поведением.
И, если уж быть точным в формулировках, поведение «если /FIXED:NO не указан явно, а мы делаем EXE — подразумевать /FIXED и не делать релокаций» как было дефолтным в линкере, так и осталось до сих пор.
Другое, что добавили ключ /DYNAMICBASE, одним из побочных эффектов применения которого (но не единственным) является «считать, что указан /FIXED:NO».
То есть дефолтное поведение изменено не непосредственно, а как побочный эффект от другого нововведения: с точки зрения стороннего наблюдателя дефолтное поведение всей системы действительно изменилось, но только в случае, если линкер запускается вообще с минимальным набором ключей командной строки.
Автор писал не на Си или C++, а на ассемблере, используя компилятор NASM, и внезапно, линкер не является частью NASM-а. Даже в Visual Basic, где компилятор реально встроен в IDE и не существует в виде отдельного исполняемого файла, линкер, тем не менее, не встроен в IDE, а является отдельным бинарником — отдельным инструментом.
Вы говорите по отношению к компоновщику фразу «в языках». Как будто бы линкер это как пятое колесо к какому-то из языков программирования. Линкер вообще не должен быть «в языке» или связан с языком. Это отдельный компонент в конвейере по производству исполняемых файлов.
Отстранённость линкера от компиляторов и языков программирования позволяет в рамках одного проекта написать часть исходного кода на Си, часть на Си++, часть на ассемблере, часть на паскале, часть на самодельном узко-специфичном языке программирования, а потом всё это слинковать в один исполняемый файл. При желании туда же может попасть фортран, кобол и прочая экзотика.
Исполняемые файлы без кода (resource-only DLL в Windows) тоже вполне себе обычное дело, и в рождении таких файлов линкер по прежнему нужен, но никакой компиятор и никакого ЯП участия уже не принимают. Для Windows приложений .res-файл утилитой CVTRES.EXE превращается в .obj-файл и подаётся на вход линкеру. Сам же .res файл может быть либо собран каким-то редактором ресурсов, либо компиятором resource script'ов RC.EXE из resource script-а — файла с текстовым описание дерева ресурсов. И без крайних частных случаев вроде resource-only DLL — в случае с обычными исполняемыми файлами, имеющими внутри себя ресурсы — ровна та же схема (resource script —> [RC.EXE] —> бинарный res-файл —> [CVTRES.EXE] —> объектный файл COFF-формата —> [линкер] —> исполняемый файл) остаётся актуальной.
Само по себе существование такой распределённой и гибкой (в стиле unix-way — делай одно маленькое дело, но делай его хорошо) концепции и стандартизированность объектных файлов (COFF у MS, OMF у Borland, ELF в мире юникс) это сродни существованию стандартов вроде ATX или PCI в железе).
Одни компании производят материнские платы, платы расширения, планки памяти, корпуса, накопители, соответствующие стандартам, но не собирают готовые ПК. Другие организации не производят электронику, но могут собрать компьютер из комплектующих от совершенно разных производителей.
С точки зрения любого технаря любая стандартизация и даруемая ей взаимозаменяемость есть благо. Но есть и другой подход в индустрии: делать полностью готовый компьютер-моноблок из своих нестандартных комплектующих полностью самим. Технари скалят зубы, зато маркетологи бьются в экстазе.
То, что вы из «новой волны» программистов, которые нонсенсом считают случаи, когда продукт может быть построен из исходников сразу на двух-трёх-четырёх ЯП, когда продукт собирается из makefile-а, билд скрипта, батника, а не из IDE со свистелками и блек-джеком, куда глубоко и крепко встроен компилятор, в котором хорошо запрятан линкер — примерно понятно, но ничего хорошего в этом не вижу.
Не теряет, потому что его изначально не было: «как оно будет» зависит ровно от ключей командной строки, а если их нет, от «модели» и версии линкера. Вспоминать про игры 2000-го, защиты типа Starforce, бежать проверять в разных IDE и закономерно получать противоречивые результаты — это всё было совершенно бессмысленным.
Вывод о путанице между компилятором и линкером делается не из этого, а уже из другого: из того факта, что во всех ваших (в смысле у вас двоих, а не лично Ваших) постах ни разу не фигурировало слово «линкер», а везде фигурирова «компилятор». Он тоже генерирует некие релоки, но совершенно не те.
Наличие или отсутствие в исполняемом файле информации, необходимой для перемещаемости образа, зависит от ключей командной строки, скормленных именно линкеру, а в случае, если соответствующие ключи не указаны — зависит от того, что за линкер используется и какая его версия. Одним этим выделенным жирным предложением в споре можно было бы поставить жирную точку. Без указания того, про какой линкер и про какую версию идёт речь, продолжать спорить не имело смысла. Но вы оба продолжили, причём спорили даже не о линкерах, а о компиляторах, которые тут вообще не причём.
Потом вы пишите:
и дополняете, что вам 53 и вы собаку съели на знании тонкостей формирования исполняемых файлов. Ну так тогда бы вы знали, что Microsoft-овский линкер большую часть истории своего существования по умолчанию предполагал именно /FIXED для EXE-файлов. Хотя, почему — может вы все эти годы с совершенно другим линкером имели дело. Но тогда с каким? То есть то ли вы такой опытный, но не знаете про дефолтность /FIXED для EXE и /FIXED:NO для DLL в MS-овском линкере, то ли вы просто работали с каким-то другим линкером, знаете его, возможно, довольно хорошо, но как будто бы в вашей картине мира других линкеров нет.
Дальше идёт:
По умолчанию где? Вы можете знать или не знать NASM, но NASM — не компоновщик. И выставлять флаг relocs stripped или же не выставлять его, а генерировать таблицу base-релокаций — это вообще не компетенция NASM-а. Как и MASM, NASM на входе принимает ассемблерный исходник, а на выходе выплёвывает объектный файл. Не исполняемый файл, а объектный. В котором нет места таблице релокаций (в том смысле, в каком она есть в PE) и нет места флагу IMAGE_FILE_RELOCS_STRIPPED.
Вот эти все ваши мелкие оговорки: то флаг не в таблцие секций (хотя он в PE-заголовке), то компилятор вместо линкера (в споре о том, должен ли линкер делать EXE-файлы перемещаемыми), то вы от NASM-а ждёте один из двух вариантов активности (и не знаете, какой там по умолчанию), которые свойствены линкерам, тогда как в NASM-е нет одного из двух вариантов, так как он не вбирает в себя функции линкера — всё это в совокупности создаёт впечатление, что вы плаваете в теме, не знаете, где проходит граница раздела ответственности между компиляторами и линкером.
Опять таки, решать проблему с ASLR вы предлагаете установкой флага IMAGE_FILE_RELOCS_STRIPPED, хотя логично было бы ассемберный код подправить так, чтобы вшитые в нём адресные константы попали в таблицу релокаций, либо же код самомодификации написать так, чтобы он определял реальную базу, вычислял дельту релокации на основании разницы между фактической базой и предпочитаемой базой и приплюсовывал эту дельту релокации всюду, где он в генерируемый машинный код вплетает адресные константы, заложенные в код на стадии написания ассемблерного исходника.
Не имеют, но если о них не написать, придёт кто-нибудь умный и к моей придирке «компилятор релокации не генрирует, их генерирует линкер» сам придирётся фразой «нет правда, компилятор релоки тоже же генерирует» (но это уже совсем
другая историядругие релоки).В целом, в этом диспуте, я больше на вашей стороне: я думаю, если на моём компьютере просканировать все EXE-файлы, то единственным, который будет иметь релокации, окажется OllyDbg, который стал перемещаемым не в угоду ASLR, а по совсем другой причине.