<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Reversing and Code</title>
		<link>http://peco.at.ua/</link>
		<description>Блог</description>
		<lastBuildDate>Mon, 26 Sep 2011 20:58:55 GMT</lastBuildDate>
		<generator>uCoz Web-Service</generator>
		<atom:link href="https://peco.at.ua/blog/rss" rel="self" type="application/rss+xml" />
		
		<item>
			<title>Снятие защиты PE Password 0.2 SMT/SMF</title>
			<description>&lt;div align=&quot;center&quot;&gt;* &lt;a href=&quot;http://peco.at.ua/SMT_SMF_FILES.rar&quot; target=&quot;_blank&quot;&gt;&lt;font color=&quot;#32cd32&quot;&gt;Скачать архив с необходимыми файлами&lt;/font&gt;&lt;/a&gt; *&lt;br&gt;&lt;/div&gt;Некто &lt;a href=&quot;http://exelab.ru/f/index.php?action=userinfo&amp;amp;user=25505&quot; target=&quot;_blank&quot;&gt;Loh_Ushastik&lt;/a&gt; на форуме &lt;a href=&quot;http://exelab.ru/f/&quot; target=&quot;_blank&quot;&gt;exelab&lt;/a&gt; попросил в личку помощи в снятии защиты PE Password 0.2 SMT/SMF. Обычно я такие просьбы игнорирую, но эта была довольно подробно расписана, что делал, где и как искал и что вроде как кроме одного корейца больше никто и не осилил. Даже нашел &lt;a href=&quot;http://exelab.ru/f/index.php?action=vthread&amp;amp;forum=2&amp;amp;topic=4175&quot; target=&quot;_blank&quot;&gt;древний топик на exelab&lt;/a&gt;, где уже спрашивали о данной защите. Поэтому я взялся. Защищенный файл есть в приложении.
Запускаем подопытного и видим:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/SMT_SMF1.png&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;Протектор запрашивает пароль. Закрываем программу и загружаем ее в отладчик. Ниже листинг с комментария...</description>
			<content:encoded>&lt;div align=&quot;center&quot;&gt;* &lt;a href=&quot;http://peco.at.ua/SMT_SMF_FILES.rar&quot; target=&quot;_blank&quot;&gt;&lt;font color=&quot;#32cd32&quot;&gt;Скачать архив с необходимыми файлами&lt;/font&gt;&lt;/a&gt; *&lt;br&gt;&lt;/div&gt;Некто &lt;a href=&quot;http://exelab.ru/f/index.php?action=userinfo&amp;amp;user=25505&quot; target=&quot;_blank&quot;&gt;Loh_Ushastik&lt;/a&gt; на форуме &lt;a href=&quot;http://exelab.ru/f/&quot; target=&quot;_blank&quot;&gt;exelab&lt;/a&gt; попросил в личку помощи в снятии защиты PE Password 0.2 SMT/SMF. Обычно я такие просьбы игнорирую, но эта была довольно подробно расписана, что делал, где и как искал и что вроде как кроме одного корейца больше никто и не осилил. Даже нашел &lt;a href=&quot;http://exelab.ru/f/index.php?action=vthread&amp;amp;forum=2&amp;amp;topic=4175&quot; target=&quot;_blank&quot;&gt;древний топик на exelab&lt;/a&gt;, где уже спрашивали о данной защите. Поэтому я взялся. Защищенный файл есть в приложении.
Запускаем подопытного и видим:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/SMT_SMF1.png&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;Протектор запрашивает пароль. Закрываем программу и загружаем ее в отладчик. Ниже листинг с комментариями:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/SMT_SMF2.png&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;Загрузчик вычисляет ImageBase, получает адреса всех нужных API, создает окно для ввода пароля и обрабатывает стек оконных сообщений. В листинге я пометил, что адрес обработчика оконных сообщений pDlgProc = 00409153. Посмотрим, что там происходит:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/SMT_SMF3.png&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;Видим, что при каком то событии (не важно каком) считывается пароль и рассчитывается его контрольная сумма. Пароль как видно не может быть больше 40 символов, а его контрольная сумма должна быть равна 0x085E75C3. Осталось посмотреть как считается контрольная сумма:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/SMT_SMF4.png&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;Берется один символ пароля и 65536 раз применяется разными битовыми операциями к контрольной сумме. Потом берется следующий символ пароля и всё повторяется. Все данные для брута у нас есть, можно писать брут. Я его написал, и сразу же после запуска он мне выдал пароль &quot;V12”. Прикольный пароль, вводим и… фак! Программа вылетела в ошибку. Я почему то сразу не полез проверять в чем дело, а предположил, что это плохой алгоритм CRC, который дает коллизии. Поэтому изменил брут так, что после нахождения пароля он не останавливался, а писал найденный пароль в файл и продолжал брутить. Мать моя! Почти каждый сотый пароль соответствовал контрольной сумме! Короче эта затея не увенчалась успехом, поэтому будем смотреть что с паролем делается дальше. Для этого смотрим, что там будет после закрытия окна:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/SMT_SMF5.png&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;Берется виртуальный размер первой секции, виртуальное смещение первой секции, смещение складывается с базой образа в памяти и получается абсолютный адрес первой секции в памяти. Далее виртуальный размер сравнивается с константой 0x12345678, которая является флагом зашифрована первая секция или нет, и если секция зашифрована, то происходит расшифровка секции. Теперь понятно, почему файл падал. Посмотрим как реализована процедура дешифровки секции:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/SMT_SMF6.png&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;Думаю я подробно прокомментировал листинг и в пояснениях он не нуждается. Используется 2 ключа. Первым (Key1) дешифруются 4 байта первой секции, а второй (Key2) используется для подготовки Key1 к дешифровки следующих 4 байт первой секции. Причем самое первое состояние и Key1 и Key2 получают путем вычисления CRC суммы из введенного пароля. Т.к. алгоритм весьма прост и при шифровании буфер сдвигается на 4 байта, а длинна ключей очень мала, то можно произвести plain text атаку. Если грубо, то plain text атака направлена не на подбор правильного пароля, а на подбор промежуточного значения, которое получается от пароля и которым и шифруются/упаковываются данные. В нашем случае это значения Key1 и Key2. Подумайте сами, даже грубо посчитать, есть разница перебирать пароль от 1 до 40 символов или перебирать ключ с фиксированной 8 байтовой длинной. Для plain text атаки нам нужно знать что зашифровано в какой либо части буфера. Кто часто работает с PE форматом знает, что очень большой редкостью является заполнение виртуальной секции данными до самого конца. Обычно в конце секции, идет подряд множество нулей. Возьмем последние 32 байта первой секции (берем сразу двойными словами):&lt;br&gt;&lt;br&gt;&lt;div align=&quot;center&quot;&gt;0xE380B32E, 0x238A8551, 0x191E9086, 0xBE2EB6EF,&lt;br&gt;0xBD6EB6A3, 0x3603BB70, 0x9DB00128, 0x01C6501C&lt;br&gt;&lt;/div&gt;&lt;br&gt;Предположим, что это зашифрованы нули. Каждые 4 байта дешифруются как Buff xor Key1. Составим выражение:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;BuffDecrypt = BuffEncrypt xor Key1&lt;br&gt;&lt;br&gt;&lt;/div&gt;Теперь выразим Key1:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;Key1 = BuffEncrypt xor BuffDecrypt&lt;br&gt;&lt;br&gt;&lt;/div&gt;Зная BuffEncrypt (0xE380B32E) и BuffDecrypt (0x00000000) получим Key1:&lt;br&gt;&lt;br&gt;&lt;div align=&quot;center&quot;&gt;Key1 = 0xE380B32E xor 0x00000000 = 0xE380B32E&lt;br&gt;&lt;/div&gt;&lt;br&gt;Т.е. у нас так совпало, что данные 8 двойных слов и есть значения Key1 в момент их шифрования. Теперь осталось, подобрать такой Key2, который изменит 8 раз подряд значение Key1 и оно будет соответствовать найденным 8 значениям Key1. Для этого восстановим цикл шифрования. Вкратце алгоритм следующий:&lt;br&gt;Key1 = 0xE380B32E;&lt;br&gt;Key2 = 0x00000000;&lt;br&gt;@NextKey2:&lt;br&gt;Key2 = Key2 + 1;&lt;br&gt;Key1 = CalcKey1ByKey2(Key1, Key2);&lt;br&gt;If Key1 != 0x238A8551 goto @NextKey2;&lt;br&gt;Key1 = CalcKey1ByKey2(Key1, Key2);&lt;br&gt;If Key1 != 0x191E9086 goto @NextKey2;&lt;br&gt;*****&lt;br&gt;Готовый брутфорс Key2, в приложении, называется FindKey2. Запускаем брутфорс и получаем Key2. Теперь мы знаем Key1 и Key2. Но что это нам дает? Мы знаем, что при шифровании первого из 8 двойных слов plain text, значения ключей были следующие:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;Key1 = 0xE380B32E, Key2 = 0x42919B46&lt;br&gt;&lt;br&gt;&lt;/div&gt;Пошифрованый буфер лежит по адресу 0x00404FE0. Теперь нам нужно изменить алгоритм мутации Key1 и Key2 в обратную сторону, как будто мы расшифровываем буфер не от начала к концу, а от конца к началу. Тогда, зная что буфер начинает расшифровываться с адреса 0x00401000 мы можем организовать цикл, в котором ключи Key1 и Key2 придут к своему исходному состоянию, когда они только получились путем подсчета CRC от пароля. Обратить мутацию ключей просто, нужно снизу вверх изменить все плюсы на минусы, rol на ror и т.д.&lt;br&gt;Псевдокод (оригинальная мутация ключей):&lt;br&gt;add BuffPtr, 4&lt;br&gt;rol Key2, byte Key1[4]&lt;br&gt;xor Key1, Key2&lt;br&gt;ror Key1, byte Key2[3]&lt;br&gt;add Key2, Key1&lt;br&gt;&lt;br&gt;Псевдокод (обратная мутация ключей):&lt;br&gt;sub Key2, Key1&lt;br&gt;rol Key1, byte Key2[3]&lt;br&gt;xor Key1, Key2&lt;br&gt;ror Key2, byte Key1[4]&lt;br&gt;sub BuffPtr, 4&lt;br&gt;&lt;br&gt;Осталось реализовать этот алгоритм в цикле и прервать цикл, когда BuffPtr станет равен 0x401000. В приложении есть проект ReverseKeys, он за это и отвечает. Запускаем утилиту и видим:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;Done! Key1: 51AC2180, Key2: EA903537&lt;br&gt;&lt;br&gt;&lt;/div&gt;Именно эти значения получаются при подсчете CRC от введенного пароля в процедуре DecryptSection. Осталось только подменить их сразу после подсчета и дать протектору расшифровать файл. Кому непонятно я сделал скриншот:&lt;br&gt;&lt;div align=&quot;center&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/SMT_SMF7.png&quot;&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;Сохраняем изменения и запускаем файл. Вводим что то, что пройдет первую проверку, например тот самый пароль &quot;V12” и… да, файл запустился. Требует правда start.exe, так как я понял, что это загрузчик для чего то, возможно игры, но нам это уже не интересно.&lt;br&gt;Файлы во вложении разделены на папки masm и delphi. Там одинаковые утили написанные под разные компиляторы, кому как понравится. Ну и ясен пень на masm всё работает в разы быстрее.&lt;br&gt;&lt;br&gt;&lt;b&gt;Резюме.&lt;/b&gt;
Автор защиты в корне неправильно подошел к реализации алгоритма шифрования. Основная ошибка в том, что введенный пароль практически никак не участвует в алгоритме шифрования, автор максимально отодвинул его от процесса шифрования данных.
&lt;div align=&quot;center&quot;&gt;* &lt;a href=&quot;http://peco.at.ua/SMT_SMF_FILES.rar&quot; target=&quot;_blank&quot;&gt;&lt;font color=&quot;#32cd32&quot;&gt;Скачать архив с необходимыми файлами&lt;/font&gt;&lt;/a&gt; *&lt;br&gt;&lt;/div&gt;</content:encoded>
			<link>https://peco.at.ua/blog/snjatie_zashhity_pe_password_0_2_smt_smf/2011-09-27-6</link>
			<category>Исследование защиты</category>
			<dc:creator>PE_Kill</dc:creator>
			<guid>https://peco.at.ua/blog/snjatie_zashhity_pe_password_0_2_smt_smf/2011-09-27-6</guid>
			<pubDate>Mon, 26 Sep 2011 20:58:55 GMT</pubDate>
		</item>
		<item>
			<title>Оптимизируя - оптимизируй</title>
			<description>На днях, переписывая один крипто компонент для Delphi, столкнулся со странной оптимизацией кода и алгоритма. В одном месте я увидел манипуляции с массивами, которые, если упростить, выглядели следующим образом:&lt;br&gt;&lt;br&gt;a := a &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; b;&lt;br&gt;b := b &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; a;&lt;br&gt;a := a &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; b;&lt;br&gt;&lt;br&gt;Если при манипуляции с &lt;b&gt;&lt;font color=&quot;#000000&quot;&gt;xor&lt;/font&gt;&lt;/b&gt; переменная встречается несколько раз, значит алгоритм подразумевает получение переменной в ее начальном состоянии. Для чего тут это нужно. Зная логику работы &lt;b&gt;&lt;font color=&quot;#000000&quot;&gt;xor&lt;/font&gt;&lt;/b&gt; можно составить следующие выражения:&lt;br&gt;&lt;br&gt;b := b &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; (a &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; b); &lt;font color=&quot;#006400&quot;&gt;что дает нам a&lt;/font&gt;&lt;br&gt;a := (a &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; b) &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; a; &lt;font color=&quot;#006400&quot;&gt;что дает нам b&lt;/font&gt;&lt;br&gt;&lt;br&gt;Т.е. это всего лишь обмен местами двух переменных без использования промежуто...</description>
			<content:encoded>На днях, переписывая один крипто компонент для Delphi, столкнулся со странной оптимизацией кода и алгоритма. В одном месте я увидел манипуляции с массивами, которые, если упростить, выглядели следующим образом:&lt;br&gt;&lt;br&gt;a := a &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; b;&lt;br&gt;b := b &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; a;&lt;br&gt;a := a &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; b;&lt;br&gt;&lt;br&gt;Если при манипуляции с &lt;b&gt;&lt;font color=&quot;#000000&quot;&gt;xor&lt;/font&gt;&lt;/b&gt; переменная встречается несколько раз, значит алгоритм подразумевает получение переменной в ее начальном состоянии. Для чего тут это нужно. Зная логику работы &lt;b&gt;&lt;font color=&quot;#000000&quot;&gt;xor&lt;/font&gt;&lt;/b&gt; можно составить следующие выражения:&lt;br&gt;&lt;br&gt;b := b &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; (a &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; b); &lt;font color=&quot;#006400&quot;&gt;что дает нам a&lt;/font&gt;&lt;br&gt;a := (a &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; b) &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; a; &lt;font color=&quot;#006400&quot;&gt;что дает нам b&lt;/font&gt;&lt;br&gt;&lt;br&gt;Т.е. это всего лишь обмен местами двух переменных без использования промежуточного буфера. С точки зрения алгоритма это конечно красиво, но у нас крипто компонент, который должен работать быстро и автор явно уделил время на оптимизацию алгоритмов по скорости. Даже в данном примере кода, он сделал проверку на равенство переменных, чтобы не отнимать процессорные такты на ненужный обмен местами двух одинаковых переменных. Но давайте посмотрим, а действительно ли автор кода таким образом ускорил работу своего творения. Как я уже говорил это лишь пример, в реальном коде речь шла о массивах. Набросаем аналог оригинального кода:&lt;br&gt;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;var&lt;/font&gt;&lt;br&gt;&amp;nbsp; a, b: &lt;font color=&quot;#000080&quot;&gt;array&lt;/font&gt; [&lt;font color=&quot;#0000cd&quot;&gt;0&lt;/font&gt;..&lt;font color=&quot;#0000cd&quot;&gt;9&lt;/font&gt;] of Byte;&lt;br&gt;&amp;nbsp; i : Byte;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;begin&lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;for&lt;/font&gt; i := &lt;font color=&quot;#0000cd&quot;&gt;0&lt;/font&gt; &lt;font color=&quot;#000080&quot;&gt;to&lt;/font&gt; &lt;font color=&quot;#000080&quot;&gt;9&lt;/font&gt; &lt;font color=&quot;#000080&quot;&gt;do&lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;begin&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a[i] := i;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; b[i] := &lt;font color=&quot;#0000cd&quot;&gt;9&lt;/font&gt; - i;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;end&lt;/font&gt;;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;for&lt;/font&gt; i := &lt;font color=&quot;#0000cd&quot;&gt;0&lt;/font&gt; &lt;font color=&quot;#000080&quot;&gt;to&lt;/font&gt; &lt;font color=&quot;#0000cd&quot;&gt;9&lt;/font&gt; &lt;font color=&quot;#000080&quot;&gt;do&lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;begin&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;if&lt;/font&gt; a[i] &lt;&amp;gt; a[b[i]] &lt;font color=&quot;#000080&quot;&gt;then&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;begin&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a[i] := a[i] &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; a[b[i]];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a[b[i]] := a[b[i]] &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; a[i];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a[i] := a[i] &lt;font color=&quot;#000080&quot;&gt;xor&lt;/font&gt; a[b[i]];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;end&lt;/font&gt;;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;end&lt;/font&gt;;&lt;br&gt;&lt;br&gt;Теперь посмотрим как выглядит цикл с обменом в скомпилированном виде:&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; EBX,BYTE PTR DS:[EDX]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; EBX,BYTE PTR DS:[EBX+ESI]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;CMP&lt;/font&gt; BL,BYTE PTR DS:[EAX] &lt;font color=&quot;#006400&quot;&gt;// if a[i] &lt;&amp;gt; a[b[i]]&lt;/font&gt;&lt;br&gt;&lt;font color=&quot;#800000&quot;&gt;JE&lt;/font&gt; SHORT 0040C200&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; EBX,BYTE PTR DS:[EDX]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; EBX,BYTE PTR DS:[EBX+ESI]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;XOR&lt;/font&gt; BYTE PTR DS:[EAX],BL&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; EBX,BYTE PTR DS:[EAX]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; EDI,BYTE PTR DS:[EDX]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;XOR&lt;/font&gt; BYTE PTR DS:[EDI+ESI],BL&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; EBX,BYTE PTR DS:[EDX]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; EBX,BYTE PTR DS:[EBX+ESI]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;XOR&lt;/font&gt; BYTE PTR DS:[EAX],BL&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;INC&lt;/font&gt; EDX&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;INC&lt;/font&gt; EAX&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;DEC&lt;/font&gt; CL&lt;br&gt;&lt;font color=&quot;#800000&quot;&gt;JNE&lt;/font&gt; SHORT 0040C1DA&lt;br&gt;&lt;br&gt;Как много бесполезного кода, а в оригинале еще больше. Предположим автор не знал о дизассемблере и замерим скорость работы кода в несколько проходов. У меня получилось ~470 msec. Теперь заведем переменную для нормального обмена переменных (тем более в оригинальном коде она есть, используется при следующих вычислениях) и перепишем код:&lt;br&gt;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;for&lt;/font&gt; i := &lt;font color=&quot;#0000cd&quot;&gt;0&lt;/font&gt; &lt;font color=&quot;#000080&quot;&gt;to&lt;/font&gt; &lt;font color=&quot;#0000cd&quot;&gt;9&lt;/font&gt; &lt;font color=&quot;#000080&quot;&gt;do&lt;/font&gt;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;begin&lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;if&lt;/font&gt; a[i] &lt;&amp;gt; a[b[i]] &lt;font color=&quot;#000080&quot;&gt;then&lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;begin&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; tmp := a[i];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a[b[i]] := a[i];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a[i] := tmp;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;end&lt;/font&gt;;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;end&lt;/font&gt;;&lt;br&gt;&lt;br&gt;Что получилось в скомпилированном виде:&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; ECX,BYTE PTR DS:[EAX]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; EBX,BYTE PTR DS:[ESI]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;CMP&lt;/font&gt; CL,BYTE PTR DS:[EBX+412D8C]&lt;br&gt;&lt;font color=&quot;#800000&quot;&gt;JE&lt;/font&gt; SHORT 0040C201&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOV&lt;/font&gt; BYTE PTR DS:[412DA2],CL&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; EBX,BYTE PTR DS:[ESI]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOV&lt;/font&gt; BYTE PTR DS:[EBX+412D8C],CL&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOVZX&lt;/font&gt; ECX,BYTE PTR DS:[412DA2]&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;MOV&lt;/font&gt; BYTE PTR DS:[EAX],CL&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;INC&lt;/font&gt; ESI&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;INC&lt;/font&gt; EAX&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;DEC&lt;/font&gt; DL&lt;br&gt;&lt;font color=&quot;#800000&quot;&gt;JNE&lt;/font&gt; SHORT 0040C1DB&lt;br&gt;&lt;br&gt;Уже лучше. Замерим скорость выполнения. У меня вышло ~240 msec. Теперь выбросим сравнение &lt;font color=&quot;#006400&quot;&gt;if a[i] &lt;&amp;gt; a[b[i]]&lt;/font&gt; и сделаем замер скорости. У меня вышло ~225 msec. В оригинале же, после такого изменения кода, размер скомпилированного кода уменьшился в ~6 раз, а скорость обработки увеличилась в ~4 раза. Даже не залезая в дизассемблер только замерами времени можно было убедиться, что выпендреж с алгоритмом без использования дополнительной переменной затормозил весь алгоритм шифрования.&lt;br&gt;&lt;br&gt;Ну а теперь немного об эстетике. Далее в коде мне встретилась работа с переменной типа Integer как с 4 байтовым массивом. Чтобы не использовать сдвиги автор описал свои типы данных и сделал преобразование типов:&lt;br&gt;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;type&lt;/font&gt;&lt;br&gt;&amp;nbsp; TDWordVar = &lt;font color=&quot;#000080&quot;&gt;packed record&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lo, Hi: Word;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;end&lt;/font&gt;;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;TWordVar&lt;/font&gt; = &lt;font color=&quot;#000080&quot;&gt;packed record&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lo, Hi: Byte;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;end&lt;/font&gt;;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;var&lt;/font&gt;&lt;br&gt;&amp;nbsp; a: DWord;&lt;br&gt;&amp;nbsp; b: Byte;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;begin&lt;/font&gt;&lt;br&gt;&amp;nbsp; b := TWordVar(TDWordVar(a).Hi).Hi +&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TWordVar(TDWordVar(a).Hi).Lo +&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TWordVar(TDWordVar(a).Lo).Hi +&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TWordVar(TDWordVar(a).Lo).Lo ;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;end&lt;/font&gt;;&lt;br&gt;&lt;br&gt;Тут конечно на вкус и цвет товарищей нет, но лично мне такая запись просто выедает глаза и я переписал всё следующим образом:&lt;br&gt;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;type&lt;/font&gt;&lt;br&gt;
&amp;nbsp; TKeyArray = &lt;font color=&quot;#000080&quot;&gt;packed record&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; A1, A2, A3, A4: Byte;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;end&lt;/font&gt;;&lt;br&gt;
&lt;font color=&quot;#000080&quot;&gt;var&lt;/font&gt;&lt;br&gt;
&amp;nbsp; a: DWord;&lt;br&gt;
&amp;nbsp; b: Byte;&lt;br&gt;
&lt;font color=&quot;#000080&quot;&gt;begin&lt;/font&gt;&lt;br&gt;
&amp;nbsp; b := TKeyArray(a).A4 +&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TKeyArray(a).A3 +&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TKeyArray(a).A2 +&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TKeyArray(a).A1 ;&lt;br&gt;
&lt;font color=&quot;#000080&quot;&gt;end&lt;/font&gt;;&lt;br&gt;&lt;br&gt;Вышло тоже самое, только теперь постороннему человеку, да и самому при правке кода, легко будет понять что делается с данной переменной.&lt;br&gt;</content:encoded>
			<link>https://peco.at.ua/blog/optimiziruja_optimiziruj/2011-09-13-5</link>
			<category>Программирование в Delphi</category>
			<dc:creator>PE_Kill</dc:creator>
			<guid>https://peco.at.ua/blog/optimiziruja_optimiziruj/2011-09-13-5</guid>
			<pubDate>Tue, 13 Sep 2011 16:53:15 GMT</pubDate>
		</item>
		<item>
			<title>Дела нужно делать, планы реализовывать</title>
			<description>Небольшой высер мысли. Вот уже год, как у меня зреет план написания грандиозного софта, под определенные нужды. По поводу нужд, сразу скажу - к делу это не относится и вам данный софт будет совсем не интересен. Так вот, начинал я его проектировку раз 100 точно. И каждый раз я стопорился на какой нибудь херне. То не мог выбрать базу данных, неделю изучая преимущества разных баз (не хотелось использовать серверную). То начинал проектировать один из модулей, понимал, что ему потребуется другой модуль, которого сейчас нет, бросал и начинал проектировать сначала нужный модуль. А тут была проблема, что этому модулю тоже нужен какой либо модуль, либо я понимал, что написание этого второстепенного модуля, по времени обойдется в 5 раз дольше основного и бросал это дело, надеясь на то, что скоро появится рабочее настроение. И в таком духе решались и другие проблемы. В итоге я оценил временные затраты на создание системы. Получилось, что написание всех модулей системы обойдется примерно в год раб...</description>
			<content:encoded>Небольшой высер мысли. Вот уже год, как у меня зреет план написания грандиозного софта, под определенные нужды. По поводу нужд, сразу скажу - к делу это не относится и вам данный софт будет совсем не интересен. Так вот, начинал я его проектировку раз 100 точно. И каждый раз я стопорился на какой нибудь херне. То не мог выбрать базу данных, неделю изучая преимущества разных баз (не хотелось использовать серверную). То начинал проектировать один из модулей, понимал, что ему потребуется другой модуль, которого сейчас нет, бросал и начинал проектировать сначала нужный модуль. А тут была проблема, что этому модулю тоже нужен какой либо модуль, либо я понимал, что написание этого второстепенного модуля, по времени обойдется в 5 раз дольше основного и бросал это дело, надеясь на то, что скоро появится рабочее настроение. И в таком духе решались и другие проблемы. В итоге я оценил временные затраты на создание системы. Получилось, что написание всех модулей системы обойдется примерно в год работы, если ежедневно тратить 2-3 часа, и доводка до идеала еще 6 месяцев. Вот после этого я окончательно забил на свой план написания этого софта.&lt;br&gt;&lt;br&gt;И вот позавчера, когда я жутко упахался за весь день, был в херовом настроении, с температурой 38 я подумал: &quot;Да какого хера?&quot;. Сел за комп (я всегда за ним сижу, просто ходил кофе наливать) и начал накидывать гавноподелку. Это был один из множества модулей той большой системы, которая была задумана, но в виде отдельного приложения. Начал делать по быстрому. Нужна база. Что я хорошо знаю? MSSQL Server. Ставлю на машину, не ставится. Срать, скачиваю виртуалку и образ Windows 7 Starter, взвожу систему, ставлю туда MSSQL Server 2005 и пробрасываю сетку на родительскую систему. Гавносервер под базу данных готов. Нужно спроектировать базу данных под систему. Работы на 7-8 дней для черновика. Срать, создаю несколько таблиц для работы только этого модуля, которые нельзя будет расширить для системы, да и похеру. Нужно написать несколько вспомогательных классов/модулей. Каждый должен быть потокобезопасным и самостоятельно работать с базой данных. Нафиг, никаких классов, всё в одном модуле в виде отдельных процедур. Нужен механизм транзакций для целостности данных в базе, а это хранимые процедуры и функции, а это несколько дней работы. Забываю про это и делаю одну CriticalSection и одно подключение к базе, работать будет в 10-20 раз медленнее - срать. Интерфейс. Это отдельная песня. Куча окон для тонкой настройки даже одного модуля, ведение логов, протоколирование критических ошибок, статистика работы модуля. Нах. Всё константами. Интерфейс - кнопка запуска и кнопка остановки для каждой подсистемы (вспомогательного модуля), да поле вывода минимальной информации. Нужно реализовать несколько потоков для каждой подсистемы. Обойдется, 1 поток - 1 подсистема. Готово. Запускаем - полезли ошибки, в первую очередь из-за того, что модуль получился линейный, без классов. 2 часа на правку. Заработало. Всего ушло времени 8 часов.&lt;br&gt;&lt;br&gt;Этот модуль работает уже 3 суток и дело свое делает. Работает медленно, иногда косячит, но работает. Зато теперь, анализируя его работу я начал реализовывать подсистемы в виде отдельных модулей, при этом уже зная как это должно выглядеть. И самое главное, что пока я привожу модуль в нормальное состояние, его несовершенная копия продолжает трудиться 24 часа нонстоп. Да, она работает 300-400 раз медленнее, чем можно сделать, но она РАБОТАЕТ, а до этого год не работало вообще ничего.&lt;br&gt;&lt;br&gt;Для себя я сделал вывод. Не надо загадывать далеко вперед, не надо неделю выбирать лучшее из нескольких инструментов. Надо брать и делать, а если что то не понравится использовать что то другое. Так дело будет двигаться, иначе это всего лишь мечты, нехватка времени и прочие отмазки.&lt;br&gt;&lt;br&gt;PS Вот это меня срыгнуло поносом мыслей, сам поражаюсь. Видимо алкогольная завязка, сроком в 2 месяца дает о себе знать :)&lt;br&gt;&lt;br&gt;</content:encoded>
			<link>https://peco.at.ua/blog/dela_nuzhno_delat_plany_realizovyvat/2011-08-18-4</link>
			<category>Мысли</category>
			<dc:creator>PE_Kill</dc:creator>
			<guid>https://peco.at.ua/blog/dela_nuzhno_delat_plany_realizovyvat/2011-08-18-4</guid>
			<pubDate>Thu, 18 Aug 2011 19:01:18 GMT</pubDate>
		</item>
		<item>
			<title>Samsung Galaxy S 2 - обнуление счетчика кастомных прошивок</title>
			<description>Купил недавно смартфон Samsung Galaxy S 2. На следующий день у него отказал акселерометр, т.е. при повороте смартфона приложения не переворачиваются. Делал Wipe/Hard reset, программный reset, обновил прошивку через Kies до последней официальной - ничего не помогло. Тогда я решил перейти к более сложным методам. Установил на него взломанную прошивку и попытался покопаться во внутренностях андроида, но это тоже не дало результат. Нужно нести в сервисный центр. Но тут проблема. При прошивании смартфона неофициальной прошивкой срабатывает защитный механизм от Samsung&apos;а, который увеличивает счетчик прошиваний на 1. Т.е. при переходе в Download Mode отображается, что телефон прошивался неродной прошивкой и указано сколько раз. Это автоматически снимает гарантию. Почитал в интернете, оказывается всё решаемо, причем довольно просто. Нужно купить MicroUSB штекер, резистор на 301 килоом и припаять резистор в виде перемычки на 4 и 5 ногу штекера, потом воткнуть штекер в разъем выключенного смартф...</description>
			<content:encoded>Купил недавно смартфон Samsung Galaxy S 2. На следующий день у него отказал акселерометр, т.е. при повороте смартфона приложения не переворачиваются. Делал Wipe/Hard reset, программный reset, обновил прошивку через Kies до последней официальной - ничего не помогло. Тогда я решил перейти к более сложным методам. Установил на него взломанную прошивку и попытался покопаться во внутренностях андроида, но это тоже не дало результат. Нужно нести в сервисный центр. Но тут проблема. При прошивании смартфона неофициальной прошивкой срабатывает защитный механизм от Samsung&apos;а, который увеличивает счетчик прошиваний на 1. Т.е. при переходе в Download Mode отображается, что телефон прошивался неродной прошивкой и указано сколько раз. Это автоматически снимает гарантию. Почитал в интернете, оказывается всё решаемо, причем довольно просто. Нужно купить MicroUSB штекер, резистор на 301 килоом и припаять резистор в виде перемычки на 4 и 5 ногу штекера, потом воткнуть штекер в разъем выключенного смартфона и он перейдет в режим Download Mode, обнулив при этом счетчик кастомных прошивок. Называется такое самопальное устройство Jig. Но вот беда, у меня такая схема не сработала. Теперь я расскажу как сработало у меня и как поступать в случае если не сработает и у вас, даже моя схема.&lt;br&gt;&lt;br&gt;Для начала купим необходимые комплектующие. Нам понадобится MicroUSB штекер. У меня в мухосранске такого не оказалось и я купил в Евросети MicroUSB дата кабель. Отрезал от него шнур и полностью срезал корпус, остались только внутренности. Вот как он стал выглядеть.&lt;br&gt;&lt;center&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/microusb_1.jpg&quot;&gt;&lt;br&gt;&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/microusb_2.jpg&quot;&gt;&lt;br&gt;&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/microusb_3.jpg&quot;&gt;&lt;br&gt;&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/microusb_4.jpg&quot;&gt;&lt;br&gt;&lt;/center&gt;&lt;br&gt;
&lt;br&gt;
Далее нам понадобится резистор на 301 килоом. Лучше именно такой, но можно и 300 килоом. В моем мухосранске опять же таких не оказалось и я купил 1 резистор на 270 килоом, 1 резистор на 30 килоом, 1 резистор на 1 килоом, скрутил и спаял их последовательно. Вот как это стало выглядеть.&lt;br&gt;
&lt;center&gt;&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/resisters.jpg&quot;&gt;&lt;br&gt;&lt;/center&gt;&lt;br&gt;
Далее я прозвонил ножки штекера и нашел 4 и 5 ногу, припаялся к ним, ну дальше не интересно, потому что ничего не сработало. Поэтому вам ничего повторять не надо. Но лучше если вы все же найдете первую и пятую ногу, это облегчит действия, которые я опишу дальше. Теперь нам нужен материал, которым бы мы могли изолировать все контакты резисторов, чтобы не прикасаться к ним пальцами, иначе сопротивление резисторов повысится. Можно замотать их изолентой или еще чем. Я не заморачивался и просто взял кусок туалетной бумаги:&lt;br&gt;
&lt;center&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/tualet.jpg&quot;&gt;&lt;br&gt;&lt;/center&gt;&lt;br&gt;
Выключаем смартфон. Теперь втыкаем MicroUSB штекер в разъем смартфона. А вот теперь нам нужно последовательным перебором найти ноги MicroUSB, ответственные за очистку счетчика кастомных прошивок. Берем изолированный резистор:&lt;br&gt;&lt;center&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/izo1.jpg&quot;&gt;&lt;br&gt;&lt;br&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/izo2.jpg&quot;&gt;&lt;br&gt;&lt;/center&gt;
&lt;br&gt;
Один конец резистора(ов) ставим на ногу 5, а второй конец резистора(ов) ставим на ногу 4. Ждем 2 секунды, если смартфон не включился, то ставим второй конец резистора(ов) на ногу 3 и т.д. Если не помогло, то ставим первый конец резистора(ов) на ногу 1, а второй конец резистора(ов) ставим на ногу 2 и т.д. Если и так не помогло, то просто последовательно перебираем все комбинации. Всего их 25 так что не устанете.&lt;br&gt;&lt;center&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/test.jpg&quot;&gt;&lt;br&gt;&lt;br&gt;&lt;/center&gt;&lt;br&gt;
У меня сработало на 2 и 5 ноге:&lt;br&gt;&lt;center&gt;&lt;img alt=&quot;&quot; src=&quot;https://peco.at.ua/pins.jpg&quot;&gt;&lt;br&gt;&lt;/center&gt;&lt;br&gt;
С помощью таких нехитрых действий смартфон переходит в режим Download Mode, даже если аппаратно не поддерживает его (запуск тремя кнопками), обнуляется информация о кастомных прошивках (обнуляется счетчик и тип прошивки), убирается восклицательный знак при загрузке смартфона, сигнализирующий о не лицензионной прошивке. На этом всё, надеюсь кому то будет полезно</content:encoded>
			<link>https://peco.at.ua/blog/samsung_galaxy_s_2_obnulenie_schetchika_kastomnykh_proshivok/2011-08-11-3</link>
			<category>Железо</category>
			<dc:creator>PE_Kill</dc:creator>
			<guid>https://peco.at.ua/blog/samsung_galaxy_s_2_obnulenie_schetchika_kastomnykh_proshivok/2011-08-11-3</guid>
			<pubDate>Thu, 11 Aug 2011 12:38:40 GMT</pubDate>
		</item>
		<item>
			<title>Управление формами</title>
			<description>Просматривая код других Delphi программистов, я постоянно вижу одни и те же ошибки. Самое ужасное, что я вижу такое и в очень дорогостоящих проектах, где, казалось бы должны работать профи. Давайте я немного расскажу о них, чтобы в последствии ВЫ писали код правильно.&lt;br&gt;&lt;br&gt;Начнем с того, что по умолчанию все формы в Delphi создаются сразу же при загрузке программы и болтаются в памяти до ее закрытия. Если форм мало (2-3), то это не страшно, и для небольших утилит я даже не заостряю на этом внимание. Но если проект начинает обрастать большим количеством форм, это серьезно отражается на производительности. Простой пример. Мне попалась программа, в которой использовалось ~150 форм. Все они создавались автоматически. У многих были процедуры инициализации и финализации. Загрузка exe до момента показа главной формы занимала почти минуту (!!!). При этом в постоянной работе использовались только 3 (!) формы. Убрав инициализацию форм при запуске я выиграл во времени эту самую минуту, которая ...</description>
			<content:encoded>Просматривая код других Delphi программистов, я постоянно вижу одни и те же ошибки. Самое ужасное, что я вижу такое и в очень дорогостоящих проектах, где, казалось бы должны работать профи. Давайте я немного расскажу о них, чтобы в последствии ВЫ писали код правильно.&lt;br&gt;&lt;br&gt;Начнем с того, что по умолчанию все формы в Delphi создаются сразу же при загрузке программы и болтаются в памяти до ее закрытия. Если форм мало (2-3), то это не страшно, и для небольших утилит я даже не заостряю на этом внимание. Но если проект начинает обрастать большим количеством форм, это серьезно отражается на производительности. Простой пример. Мне попалась программа, в которой использовалось ~150 форм. Все они создавались автоматически. У многих были процедуры инициализации и финализации. Загрузка exe до момента показа главной формы занимала почти минуту (!!!). При этом в постоянной работе использовались только 3 (!) формы. Убрав инициализацию форм при запуске я выиграл во времени эту самую минуту, которая так раздражала заказчика. При этом существенно упал объем потребляемой памяти.&lt;br&gt;&lt;br&gt;Теперь я расскажу как увидеть эту ошибку. Зайдите в Project-&amp;gt;Options-&amp;gt;Forms. В левом списке (Auto-create forms) находятся формы, которые будут создаваться автоматом. В правом списке (Available forms) формы, которые будут прилинкованы к проекту, но не созданы автоматом. Вам всего лишь надо перекинуть в правый список те формы, которые будут использовать редко.&lt;br&gt;&lt;br&gt;Теперь о том, как такие формы использовать. Например у нас есть форма настроек. Настройки открывают крайне редко, и те 1-2 секунды, которые уйдут на создание формы роли не сыграют. Например у нас есть пункт меню, который открывает окно формы ввода настроек. Вот такой код выполнит создание и показ формы:&lt;br&gt;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;procedure&lt;/b&gt;&lt;/font&gt; TfrmMain.ItemOptionsClick(Sender: TObject);&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&amp;nbsp; frmOptions: TfrmOptions; &lt;font color=&quot;#6b8e23&quot;&gt;&lt;i&gt;// Наша форма&lt;/i&gt;&lt;br&gt;&lt;/font&gt;&lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;begin&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&amp;nbsp; frmOptions := TfrmOptions.Create(frmMain); &lt;font color=&quot;#6b8e23&quot;&gt;// Создаем форму&lt;/font&gt;&lt;br&gt;&amp;nbsp; frmOptions.ShowModal; &lt;font color=&quot;#6b8e23&quot;&gt;// Показываем и ждем результат&lt;/font&gt;&lt;br&gt;&amp;nbsp; frmOptions.Free; &lt;font color=&quot;#6b8e23&quot;&gt;// Уничтожаем форму&lt;/font&gt;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;;&lt;br&gt;&lt;br&gt;Как можно заметить для показа формы я использовал ShowModal. ShowModal создает модальную форму, которая должна вернуть в основную форму статус, с которым она закрылась. Т.е. при вызове ShowModal код будет ждать закрытия формы, а основная будет неактивна, что и требуется в 99.99% случаев. Но почему то начинающие программисты (и не только) использую самопальные кривые способы синхронизации форм (а то и вообще не используют) посредством метода Show. Что приводит к глюкобагам пользовательского интерфейса. Есть одна особенность при работе формы в режиме ShowModal. Если в режиме Show для закрытия формы достаточно вызвать Close, то для модальной формы, свойству ModalResult нужно присвоить статус закрытия формы. Все статусы начинаются с префикса mr (&lt;b&gt;m&lt;/b&gt;odal &lt;b&gt;r&lt;/b&gt;esult). Вот пример закрытия модальной формы для сообщения основной формы, что пользователь сохраняет настройки:&lt;br&gt;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;procedure&lt;/b&gt;&lt;/font&gt; TfrmOpions.btnApplyClick(Sender: TObject);&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;begin&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&amp;nbsp; ModalResult := mrOk;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;;&lt;br&gt;&lt;br&gt;После этого форма сразу же закроется сама. Обработать статус закрытия формы можно так:&lt;br&gt;&lt;br&gt;&lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;procedure&lt;/b&gt;&lt;/font&gt; TfrmMain.ItemOptionsClick(Sender: TObject);&lt;br&gt;
&lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;var&lt;/b&gt;&lt;/font&gt;&lt;br&gt;
&amp;nbsp; frmOptions: TfrmOptions; &lt;font color=&quot;#6b8e23&quot;&gt;&lt;i&gt;// Наша форма&lt;/i&gt;&lt;br&gt;
&lt;/font&gt;&lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;begin&lt;/b&gt;&lt;/font&gt;&lt;br&gt;
&amp;nbsp; frmOptions := TfrmOptions.Create(frmMain); &lt;font color=&quot;#6b8e23&quot;&gt;// Создаем форму&lt;/font&gt;&lt;br&gt;
&amp;nbsp; frmOptions.ShowModal; &lt;font color=&quot;#6b8e23&quot;&gt;// Показываем и ждем результат&lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt; frmOptions.ModalResult = mrOk &lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;then&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;begin&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=&quot;#6b8e23&quot;&gt;&lt;i&gt;// Тут сохраняем новые настройки&lt;/i&gt;&lt;/font&gt;&lt;br&gt;&amp;nbsp; &lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;;&lt;br&gt;
&amp;nbsp; frmOptions.Free; &lt;font color=&quot;#6b8e23&quot;&gt;// Уничтожаем форму&lt;/font&gt;&lt;br&gt;
&lt;font color=&quot;#000080&quot;&gt;&lt;b&gt;end&lt;/b&gt;&lt;/font&gt;;&lt;br&gt;&lt;br&gt;На этом всё. Надеюсь, что мои советы кому то будут полезны.&lt;br&gt;</content:encoded>
			<link>https://peco.at.ua/blog/upravlenie_formami/2011-08-06-2</link>
			<category>Программирование в Delphi</category>
			<dc:creator>PE_Kill</dc:creator>
			<guid>https://peco.at.ua/blog/upravlenie_formami/2011-08-06-2</guid>
			<pubDate>Sat, 06 Aug 2011 14:54:17 GMT</pubDate>
		</item>
		<item>
			<title>Обновление служб Windows Update, Microsoft Security Essentials и др. через прокси сервер.</title>
			<description>Купил недавно новый компьютер и решил перейти на новую опреационку Windows 7. Первая проблема, с которой я столкнулся - это обновление служб и компонентов Windows через прокси сервер. Windows XP подхватывала настройки из настроек подключения сети, которыми пользуются Internet Explorer и Google Chrome. Семерка не захотела этого делать. Почитал, что пишут люди и нашел решение. Оказывается в семерке службы работают через транспорт WinHTTP, который можно конфигурировать из командной строки. Жмем пуск, набираем cmd, когда в пуске найдется cmd жмем правой кнопкой-&amp;gt;запустить от имени администратор. Набираем&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;netsh winhttp import proxy source=ie&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;и настройки считаются из эксплорера. Либо задаем руками:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;netsh winhttp set proxy 127.0.0.1:8080 (это лишь пример)&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Чтобы посмотреть текущие настройки прокси, набираем:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;netsh winhttp show proxy&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Вот и всё.&lt;/div&gt;</description>
			<content:encoded>Купил недавно новый компьютер и решил перейти на новую опреационку Windows 7. Первая проблема, с которой я столкнулся - это обновление служб и компонентов Windows через прокси сервер. Windows XP подхватывала настройки из настроек подключения сети, которыми пользуются Internet Explorer и Google Chrome. Семерка не захотела этого делать. Почитал, что пишут люди и нашел решение. Оказывается в семерке службы работают через транспорт WinHTTP, который можно конфигурировать из командной строки. Жмем пуск, набираем cmd, когда в пуске найдется cmd жмем правой кнопкой-&amp;gt;запустить от имени администратор. Набираем&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;netsh winhttp import proxy source=ie&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;и настройки считаются из эксплорера. Либо задаем руками:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;netsh winhttp set proxy 127.0.0.1:8080 (это лишь пример)&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Чтобы посмотреть текущие настройки прокси, набираем:&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;netsh winhttp show proxy&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Вот и всё.&lt;/div&gt;</content:encoded>
			<link>https://peco.at.ua/blog/obnovlenie_sluzhb_windows_update_microsoft_security_essentials_i_dr_cherez_proksi_server/2011-03-29-1</link>
			<category>Windows 7</category>
			<dc:creator>PE_Kill</dc:creator>
			<guid>https://peco.at.ua/blog/obnovlenie_sluzhb_windows_update_microsoft_security_essentials_i_dr_cherez_proksi_server/2011-03-29-1</guid>
			<pubDate>Tue, 29 Mar 2011 07:36:40 GMT</pubDate>
		</item>
	</channel>
</rss>