четвер, 26 липня 2018 р.

"Undocumented DOS", 1st edition

Ще одна "ретрорецензія". Про "романтичні" комп'ютерні 90-ті я вже не раз писав. Поміж популярних тогочасних хобі було написання вірусів. DOS -- ідеальне середовище для них, ніякого захисту, вся система як на долоні -- розважайся, скільки зможеш. Але сяка-така протидія, все ж, була -- ранні антивіруси, пошук підозрілих процесів і дивних блоків пам'яті тощо. За відсутності розмежування доступу, змагання вірус-антивірус було цікавою грою. А вміння працювати із внутрішніми, недокументованими, структурами DOS було корисним для ефективної участі в ній. Приклад: багато антивірусів не відслідковували роботу із файлами через і FCB.  Та й цікаво -- раптом недокументоване включає якісь містичні можливості. Ходить справедливий жарт: "Чогось недокументованими можливостями найбільше цікавляться ті, що документовані поки толком не освоїли". З іншого боку -- нам було від сили півтора десятиліття. :-) 
Важлива ремарка -- DOS і суміжні сфери в той час на Заході вже стрімко втрачали актуальність. Навіть OS/2  своє доживала, як виявилося пізніше. Але ми працювали із старою технікою (наприклад, Пошук-1/Пошук-2 -- слабенький клон PC XT середини 80-х) та із старою літературою. Зараз дивлюся на книжки -- добуті чудом, по яких тоді вчився, і жахаюся їх рівневі. І дуже різко реагую на заяви студентів "Ми не змогли розібратися - літератури немає", за наявності доступу до яких хочеш книг, пошукових систем взагалі і StackOverflow зокрема та ще й можливості запитатися у місцях, де буває тисячі людей, які вміють та хочуть пояснити новачкам.


Моїм провідником у "вірусній" сфері був відомий (у вузьких колах) журнал Infected Voice, як виявилося, в основному, київського базування. Багато корисного звідти почерпнув: відчув безкарність від втручання в бінарний код -- своєрідна десакралізація після довгих страждань із Turbo Pascal, занурився в глибини асемблера, зокрема, познайомився із Polymorphic Engines, взнав про Forth, вперше зіткнувся із форматом об'єктних файлів (виконавчих файлів -- безперечно, теж, які віруси без того), і т.д. і т.п. Там часто згадувалася книга "Udocumented DOS". Дуже хотілося її почитати.
"Все твои желания исполняются – рано или поздно, так, или иначе…" -- про Вершителів, Макс Фрай.
Як не дивно, вона, одна із небагатьох знакових книг того часу, не трапляється в дикій природі в електронному вигляді -- ні сканів, ні популярного в ті часи перенабраного чи краденого у видавництві електронного тексту. Так ще й на Амазоні вона була, але, разом із доставкою -- за зовсім захмарні гроші. Аж нарешті, цього року, вдалося купити. "Рано чи пізно" -- воно таке.

Рецензія

Отож, наш герой: "Undocumented DOS: Programmer's Guide to Reserved MS-DOS Functions and Data Structures" by Andrew Schulman, Raymond J. Michels, Jim Kyle, Tim Paterson, David Maxey, Ralph Brown.  Перше видання -- жовтнень 1990-го року. Більшість імен авторів добре відомі людям, які програмували під DOS в той час. 

Книга виявилася на диво милою -- легко читається, написана зрозуміло, прикладів -- належна кількість, важливий код -- безпосередньо в книзі (зараз це вважається недоліком, але уявіть, що додаткових матеріалів чи комп'ютера, щоб на них дивитися, у вас немає). Читаючи, отримав масу задоволення. Однак, комусь не рекомендував би. Актуальність її зараз, крім історичної, зовсім ніяка -- та ж "Extending DOS" by Ray Duncan et. al" видається ціннішою навіть зараз, як приклад інженерної боротьби із важкими обмеженнями та креативності в процесі. Але сам, як художню книжку, прочитав із задоволенням.
Взагалі, іронія -- власний досвід та недавні розмови із людьми, які програмували в наших краях під DOS, в 90-х, показують, що до захищеного режиму наші програмісти, в своїй масі, не дійшли. Не сумніваюся, що такі були, але поки не зустрічав жодної людини, яка б писала промислові програми із використанням Protected mode. Максимум -- оверлеї використовувалися. Траплялися також саморобки для вивчення захищеного режиму, класу описаних тут: "Уроки захищеного режиму x86. Весь цикл разом", і все.

Тому не раз чув трагічні історії про подолання 640Кб бар'єру, оверлеї, економію кожного байту та "вимушене" використання асемблеру та інші жахіття, характерні на Заході швидше для початку 80-х. Це все -- не зважаючи на наявність Extended/Expanded memory (Пошук-2 мав 1Мб, та й 286 на 1-2Мб вже не були екзотикою навіть у нас), Dos Extender-ів, VCPI чи DPMI і т.д. і т.п. Правда, і літературу по тому всьому знайти не вдавалося на наших теренах. Не знаю, що причина, а що -- наслідок... Так і застрягли в 80-х, потім переповзли під Win32 -- і знову застрягли. Досі із жахом MS Visual Studio 6.0 згадую -- компілятор С++ там був жахливий, глючний і кривий, но більше десятиліття він був мейнстрімом у нас.
Останньою краплею, що спонукала мене написати цю (будемо чесні, позбавлену жодного практичного сенсу) рецензію: до книжки додаються оригінальні, не розпаковані  -- в запаяному пакеті, дискети!

Нижче ще є фото, де видно -- вони запаковані.
Хотів оформити у стилі статті  Charles Petzold до річниці Windows 1.0: "Windows 1.0 and the Applications of Tomorrow" -- зобразити, ніби рекламую свіжу-свіжу книгу. Але воно потребувало б більше ресурсів, ніж можу виділити. Тому -- нічого видатного чи кумедного. 

На момент виходу книжки було випущено DOS 4.0, автори стверджують,  десь -- загадково маскуючись, а десь і прямо, що мають доступ також до DOS 5.0, який мав найближчим часом вийти. У книжці багато прикладів, вони акуратні (як на свій час, із деякими обмовками, описаними нижче) та повні.  Явно писали люди, які вільно володіли темою, хотіли поділитися своїми знаннями і мали певні письменницькі таланти. 
Отримати цінну технічну інформацію можна і з неякісної книги. Власне, часто і доводилося так. Однак, читати гарно написану книгу значно приємніше. Паралельно із Undocumented DOS читав оглядову "OS/2: Принципы построения и установка", М. Гранже та Ф. Менсьё, 1991 року видання, перекладену із французької, оригінальне видання 1989. Різниця -- разюча. (Міні)задачка по ній. Що перекладачі останньої книги вкладають у терміни: "Минизадача", "Переброска сегментов", "Кольцо с жетоном"?

Цікава ремарка -- в "Undocumented DOS" вже ледь-ледь помітно певний скептицизм щодо OS/2. Хоча, може це мені здалося.
Сподіваюся, читачі пробачать мені зловживання абревіатурами виду PSP -- ностальгія змушує. :-)

Перша глава присвячена виправданню на тему, що використовувати недокументоване  (наприклад, недокументовані особливості процесора) -- погана ідея, але щодо DOS, часто -- вимушена необхідність, і завдяки великій поширеності такої практики -- не така небезпечна, бо -- "зворотна сумісність". Як ми знаємо, все так і вийшло. Ламали щось дуже рідко -- до прикладу, вже аж під Windows XP ручна маніпуляція SFT (що це таке -- див. книгу ;-) перестала працювати. Виправдання, як на мене, добре аргументовані. Багато важливого функціоналу було недоступно із використанням документованих засобів, тому всі великі компанії, включаючи саму Microsoft (і в продуктах і в статтях) використовували ці недокументовані можливості.

На самому початку стверджується, що, станом на 1990-й, існує порядку 20 тисяч програм під DOS та 30-50 мільйонів заінстальованих копій DOS. 

Друга глава, "Programming for Documented and Undocumented DOS: A Comparison" описує, які міри слід приймати і чому, щоб такі, не зовсім коректні (з точки зору  Microsoft) програми вели себе нормально. Зокрема, недокументовані структури даних, такі як LoL (та, це не той LOL, що ми знаємо зараз, це -- List of Lists) чи SFT від версії до версії змінюються. Тому слід акуратно перевіряти версію та діяти згідно неї. 

Всюди велика увага приділяється консистентності і взаємним перевіркам: "а чи точно ми правильно працюємо із недокументованою структурою -- чи справді дані, що лежать у різних її частинах, узгоджені" і все таке. Якось неочікувано у позірно хаотичному світі DOS.
У цій главі є підрозділ (стор. 42) "No Magic Number". Іронія тому, що магічні числа в прикладах постійно. Навіть коди 10 і 13 (хто впізнає? ;-) безпосередньо так і вписані. Згадуючи "містечковість", про яку багато бурчав: у нас, в 90-х, на початку 2000-х дуже важко було говорити, що існують інші платформи, окрім Win32 і "пророку його"  MS Visual Studio. Від таких розмов просто відмахувалися, як від розповідей про якусь древню, забиту, нікому не потрібну екзотику.

Світ DOS у деяких аспектах тим славився. Читаєш цю книгу і автоматично транслюєш: "компілятор вирівнює структуру на два байти" -- ага, "вирівнювання -- на розсуд компілятора/платформи, зазвичай -- машинне слово"; "такі-то регістри не можна змінювати в асемблерних вставках, такі можна" -- "ага, calling convention" і т.д.

Заради справедливості, в інших аспектах книга акуратна. Кросплатформовості, природно, як такої немає, але різні версії DOS та її емуляція під OS/2 розглядається. Акуратно вона підходить і до кроскомпіляторності, відмінності між популярними компіляторами та мовами програмування детально розглядаються із купою прикладів.
Показано, як тим всім користуватися із різних мов -- асемблера, С, (трішки згадано про С++), Pascal, Basic та з використанням різних компіляторів. 

Глава 3 присвячена керуванням ресурсами, зокрема -- пам'яттю. Про неї розповідається: як відбувається менеджмент, описано MCB (Memory control blocks) та як ними маніпулювати, розглянуто поняття процесу з точки зору DOS, прив'язка блоків пам'яті до процесів та особливості PSP (Program Segment Prefix), деякі аспекти завантаження та функціювання драйверів тощо.

Правда, якщо щодо маніпуляції пам'яттю і MCB, текст вичерпний, то драйвери писати він не навчить, навіть цілі такої собі не ставить. Зате процедура завантаження драйвера у пам'ять описана достатньо детально, щоб написати програму, здатну завантажувати драйвери не при завантаженні системи (із CONFIG.SYS), а з командного рядка -- без перезавантаження DOS.

MCB мені якраз по вірусах, включаючи boot/MBR-віруси? вже були знайомі. Якщо ти не хотів, щоб твій вірус насторожив уважного користувача, який міг не полінуватися викликати MEM, здивуватися, що це за блоки пам'яті все ще належать давно завершеній, не резидентній, програмі і щось запідозрив, то мусив із ними хитрувати. Але почитати послідовний виклад, з точки зору прикладного використання, було цікаво. 

Описано процес пошуку файлу, який відкривається: спершу пошук імені відбувається поміж драйверів, лише потім шукається на диску. Це на тему, чого досі файл AUX не створиш, а створиш якось -- не видалиш так просто.

Цікаво також читати про вирішення типових проблеми, таких як фрагментація пам'яті, трішки рудиментарної реалізації ідеї UNIX "все є файл", чи робота із процесами, у, будемо чесні, тихому болотці DOS -- з точки зору внутрішнього життя "великих" операційних систем (ОС).

Четверта глава -- про файлову систему та Network redirector, який не те щоб саме мережевий, а просто спосіб під'єднувати чужі, не FAT, файлові системи. Прикидаючись, ніби вони -- такий собі FAT. Тобто, мережевий диск, безперечно, працюватиме через Network redirector. Але й оптичний диск -- теж. Пам'ятаю здивування від того, що MSCDEX -- мережевий драйвер. :-)

Перша частина глави присвячена тому, як DOS працює із файлами. Згаданий вище List of Lists детально розглянуто саме тут: його формат в залежності від версії, спосіб доступу та те, як його ініціалізує система при завантажені. Також, описано інші критичні структури даних: DPB (Driver Parametes Block), SFT (System file tables -- віруси, які вміли працювати із нею безпосередньо, отримували помітну перевагу) і системні FCB (спосіб схрестити новий спосіб працювати із файлами із DOS2+ і старі FCB), буфери DOS, CDS (Current Directory Structure -- завдяки емуляції яких заради зворотної сумісності, Windows досі в консолі робить вигляд, що для кожного диску є своя поточна директорія), JFT (Job File Table -- якщо елементи SFT можна вважати трішки збоченим аналогом відомих із Unix/Linux файлових дескрипторів ядра, то JFT містить аналоги дескрипторів процесу). Описано, як додавати та прибирати диски на льоту. (Хоча, ніхто не гарантує, чи виживе система після цього, але в DOS взагалі мало що гарантовано).

Друга її частина розповідає про, власне, редиректор. Мережева тема була, певне, найбільш загадковою для мене, коли то було актуально, в 95-97 роках.  В принципі, описаного в цій главі, вистачило, щоб задовольнити цікавість.А практично, сподіваюся, ніколи не знадобиться.

Як приклад, реалізовано емулятор диску Phantom, який підтримує директорії, але на диску не більше одного файлу, а в кожній директорії -- не більше однієї піддиректорії. Максимальний розмір файлу -- 2Кб. Все це -- заради простоти. А щоб мало не здалося -- написано на Паскалі.

П'ята глава -- про резидентні програми (TSR -- Terminate and Stay Resident) та намагання прикрутити до принципово однозадачного DOS багатозадачність.

Віруси без резидентності -- несерйозно. Завдяки їй можна і нові програми заражати, зразу при запуску, а то й ще під час компіляції, (випадок екзотичний, зате цікавий), маскуватися від антивірусів та допитливих користувачів, реалізуючи стелс-технології різноманітні. Перехопив переривання, хтось хоче розмір зараженої програми взнати -- повертаєш старий, до зараження, підозрілий хтось відкриває, чи не антивірус -- підставляєш старий код, на переривання таймера, INT 8, повісився і дивишся -- чи ніхто не забрав у нас керування, або на клавіатурне, 9-те -- і дражниш юзера. Чи, скажімо, 11-класники не хочуть, щоб ми, 10-класники, бавилися комп'ютерні ігри. Написали зловредну резидентну софтинку, яка заважає запускати ігри. Ми, "жителі" 10-го класу, з тим категорично не згодні -- розробляємо протидію. І т.д. і т.п. Та й Том Сван (мій другий вчитель асемблера, після Пітера Абеля) терпимо описав ключові елементи обробки переривань в реальному режимі x86 на IBM PC-сумісних машинах. 

Але хоча базові речі -- збереження-відновлення регістрів і прапорців, реєнтрантність, ці книги висвітлювали, жодна із них не розповідала про критичні для написання повноцінних резидентних програм речі. Тому лише значно пізніше стало зрозуміло, чого мої спроби написати резидентний файловий менеджер із тріском провалилися.  А ось дана глава книги містить достатньо інформації. 

Один із перших розділів глави має промовисту назву: "TSR: It Sounds Like a Bug, But It's a Featrue" -- явно ніхто все це не проектував, розробники Мікрософт додавали "затички" в міру власної потреби.

Написання обробників переривань описано на різних мовах -- не тільки на асемблері, але й з використанням С та Паскаля. Багато розповідається про переключення стеків DOS, областей DTA, SDA (Swappable Data Area), PSP тощо. Розповідається про те, як мінімізувати витрати пам'яті та як акуратно віддати всі вже не потрібні ресурси програми, перш ніж ставати резидентним -- пам'ять, включаючи блок змінних середовища, відкриті файли (особливо, відкриті не нею а оболонкою, для перенаправлення виводу) тощо. Описано процес вимикання резидента.

Розповідається про INDOS -- своєрідний семафор на входів DOS, без якого забезпечити реєнтрантність і коректну роботу резидента, що має вискакувати (pop-up) на екран чи здійснювати ввід-вивід (особливо із використанням функцій DOS) -- неможливо. Розповідається і про інші критичні особливості синхронізації резидентів та інших обробників переривань, що спрацьовують асинхронно відносно основного коду: знаходження в обробнику критичної помилки означає критичну область, хоча INDOS і не встановлено, але під час роботи із COMMAND.COM -- INDOS завжди встановлено, бо останній очікує на ввід із клавіатури в INT21h Fn. 0Ah, тому слід перехоплювати INT 28h -- "затичку" від MS якраз на такий випадок. Також -- про функції INT 2Ah, Fn. 80h -- зайти в критичну секцію DOS та Fn. 81h -- вийти із критичної секції DOS, які слід перехопити, щоб знати про перебування у критичних секціях.  Перераховано, із обґрунтуванням, які переривання слід перехоплювати під час активності резидента, описано інтерфейс INT 2F для взаємодії із ним. Розказано про різницю між версіями DOS та баги у деяких із них, важливі при написанні резидентів.

Показано, як можна в чистому DOS організувати мінімальну багатозадачність.

Не знав, що існувало багато спеціальних бібліотек для створення резидентних програм. Що тільки люди не винаходять... 

Знову згадаю -- кумедно спостерігати, як DOS вирішує проблеми, що й перед великими системами стоять.

Глава 6 розповідає про командний інтерпретатор COMMAND.COM та способи взаємодії із ним. Багато розказано про його внутрішню роботу (типу звички відкривати і закривати BAT-файл після кожного рядка, на випадок, якщо в процесі змінюватимуть дискети -- це була нормальна процедура в ранніх DOS-машинах, особливо без HDD) та програмні інтерфейси (свого роду API).

Із несподіваного. Не знав, що стандартний командний інтерпретатор DOS підтримує додавання користувацьких вбудованих команд! Навіть не чув про таке ніколи, або не усвідомив -- якщо чув. 

Багато уваги приділено змінним середовища і організації роботи із ними. Розповідається про запуск головного -- першого, командного інтерпретатора та пошук його (разом із головною копією змінних середовища, якою він володіє). Показано, що надійних способів немає -- кожен із своїми проблемами, але, в цілому -- жити можна.

Наведено приклад додавання своєї вбудованої команди та створення мінімалістичного командного інтерпретатора. 

В сьомій главі розглядається інтерфейс дебаггінгу (зневадження) DOS.

В принципі, сфера теж знайома -- перехоплювати перше і третє переривання в рамках вірусописання, як самозахист від дебаггінгу, теж практикувалося. Однак, глава присвячена іншому -- чим DOS може допомогти дебаггеру. Зокрема, описано недокументовану функцію завантаження програми без запуску (INT 21h, Fn. 4Bh, SubFn. 1, "load but do not execute"). Також, знову, пише про гру із PSP, бо поточний процес в DOS один -- і не хотілося б, щоб це був дебаггер, поки працює програма, запущена під ним. 

Цікаво, що розповідається про взаємодію відладочних інтерфейсів Windows 3.0 реального режиму! Показано, як ловити повідомлення від Windows про переміщення сегментів і т.д.  Є приклади. 

Восьма глава -- про програмку INTRSPY. Вона мені і в дикій природі траплялася. На диво просунута річ для того часу. Керований скриптами дебаггер, який перехоплює і записує вказані в скриптах функції вказаних переривань. Зроблений доволі елегантно, враховуючи технічні обмеження. Складається із двох програм. Одна -- резидентна, працює із скомпільованим скриптом, зберігає дані у внутрішньому буфері. Це мінімізує затрати пам'яті та позбавляє мороки із вводом-виводом в обробнику переривань. Інша -- дозволяє керувати першою, компілювати скрипти для неї та "забирати" журнал роботи і виводити його у зручній формі. 

Резидентна частина подробиць не знає, їй сказали перехопити функцію 3dh переривання 21h  та на вході зберегти те, що вказує на ім'я файлу (пару DS:DX), наголосили, що ім'я буде С-стрічкою (як автори називають -- ASCIIZ стрічкою), а на виході -- чи не було ознаки помилки, CF=1. Що це саме "відкрити файл", вона не знає. А користувач отримає осмислене: "намагався відкрити такий-то файл, вдалося":
Згадалося, як студент, пишучи в ролі семестрового проекту інфектор для PE та кейлоггер в ролі "боєголовки", дивувався, що Windows дозволяє перехоплювати будь-який ввід будь-якої програми поточного користувача. :-)
Додаток А -- недокументована частина славнозвісного списку переривань Ральфа Брауна, одного із співавторів. Актуальну (ну, наскільки це можна говорити про API DOS і компанії) версію його можна знайти на сайті автора: "The x86 Interrupt List aka "Ralf Brown's Interrupt List", "RBIL"" (востаннє оновлено в 2000 році). У більш зручній формі цей каталог є на сайті DJ Delorie, людини, що підтримує GCC для DOS -- DJGPP (майте на увазі, GCC 8.1 підтримується!): "Ralf Browns Interrupt List".
DJGPP, хоча і працює під DOS, є 32-бітною програмою, а сам GCC не вміє генерувати 16-бітний код. Так що Open Watcom (старіша версія тут) рано ще забувати. :-)
Довідник і є довідник (тим більше маю доступ до свіжішої версії), читати його нецікаво, в очі впало лише  пару цікавинок, виду: 
INT 21, Fn. 13h,  DELETE FILE USING FCB, баг: "DOS 1.25+ deletes everything in the current directory (including subdirectories) and sets the first byte of the name to 00h (entry never used) instead of E5h if called on an extended FCB with filename '???????????' and bits 0-4 of the attribute set (bits 1 and 2 for DOS 1.x).  This may have originally been an optimization to minimize directory searching after a mass deletion (DOS 1.25+ stop the directory search upon encountering a never-used entry), but can corrupt the filesystem under DOS 2+ because subdirectories are removed without deleting the files they contain."

(Цитую по актуальному списку -- лінь перенабирати цей текст із книжки).

Додаток B -- список літератури.

Фото







Дискети

Прочитавши книжку, не втримався -- розрізав пакет і дістав дискети. Не зважаючи на майже три десятки років, вони в ідеальному стані -- прочиталися без жодного зайвого "пчихання" дисководу (хто ще звук п'ятидюймового дисковода пам'ятає? навіть в тридюймового він інший). Вміст можна скачати тут. Архів містить побайтові образи обох дискет та, окремо -- їх вміст. В чистих областях дисків сходу нічого цікавого не побачив. В кінці 80-х master-диски вже не робили із робочих дискет. (Є цікаві історії про образи оригінальних перших версій DOS.) Але особливо не шукав. 

Кому цікаво, ось тут є errata і списки файлів до цього та наступного випуску даної книжки (щоправда, дати файлів та їх розміри, не зовсім точні -- очевидно, бралися із модифікованих образів).  Дуже рекомендую зайти в корінь цього сайту! Там старі системи можна спробувати безпосередньо із браузера! А завантаживши, "змонтувати" один із наявних дисків -- із величезного списку, включаючи диски цієї книги. 

Ремарка 1: антивіруси задовбали! Невинний приклад FAKEFMT із книги їх перезбудив на моїй 64-бітній, принципово не сумісній із Windows 10, машині. Ледве переконав не вбивати його. 

Ремарка 2: так незвично -- працюю із USB-FDD і постійно смикаюся, звик -- коли дисковод диринчить, комп'ютер гальмувати буде. (А все -- особливості реалізації роботи із дисководом в Windows 95, див коменти за посиланням).

Ремарка 2.1: ні, п'ятидюймового USB-FDD не маю, лише тридюймовий.

Діагноз


Ось і все. Мила книжка. Шкода, що вона не потрапила мені до рук в 95-му. Зараз хіба трішки розслабився, читаючи -- яке воно все просте та наївне було. :-) На цьому дану позбавлену сенсу рецензію закінчуватиму.

Не те щоб хтось аж сюди дочитав, але:

Дякую за увагу!

4 коментарі:

  1. Вийдіть на зв'язок, будь ласка

    ВідповістиВидалити
  2. цікава мабуть книжка, на початку 90-х років була б на вагу золота
    я почав програмувати на початку 2000-х років, звичайно під дос, інформації і тоді було мало, а потім мій ентузіазм пропав... Хоча десь у 2010 році я написав програмку яка додає флопік В до нових на той час компютерів, там де у біосі був тільки флопік А. Спеціально щоб другий дисковод підключити 5,25.. Але там ще треба апаратно на дисководі один тумблер допаяти :)

    ВідповістиВидалити
    Відповіді
    1. О! Цікава розвага :=) Ваша програма під Windows теж працювала, чи тільки DOS?

      Видалити