Spread the love

Что нового в Delphi, C++Builder и RAD Studio 10.4.2 Sydney

 24 февраля 2021 будет проходить вебинар "What’s Coming in Delphi, C++Builder, and RAD Studio 10.4.2 Sydney". Из него вы узнаете, что нового стоит ожидать от

Читать на сайте автора.

Вебинар "Что нового в Delphi, C++Builder и RAD Studio 10.4.2 Sydney?"

    Согласно RAD Studio roadmap на 2020/2021 новый выпуск Delphi, C++Builder и RAD Studio 10.4.2 запланирован на первую половину 2021 года. Завтра компания Embarcadero проводит вебинар

Читать на сайте автора.

EurekaLog и VirusTotal: непредвиденные последствия

К нам обратился человек, который сообщил о непредвиденном последствии загрузки программы с внедрённой EurekaLog на сервис VirusTotal.

Дело было так: клиент скомпилировал приложение с EurekaLog. В приложении была настроена отправка баг-отчётов по e-mail. Он загрузил скомпилированное приложение на сайт VirusTotal и получил результат проверки, что всё в порядке.

Пока всё достаточно типично. Странные дела начались на следующий день, когда клиент получил на e-mail отчёт от EurekaLog. Странность заключалась в том, что клиент не запускал своё приложение и не распространял его. А сам отчёт выглядел… необычно.

В частности, исполняемый файл был переименован в случайный набор букв, равно как и случайным набором оказались имя пользователя и компьютера. В списке модулей и процессов не оказалось ничего подозрительного, и вообще машина казалась «голой». Единственным выделяющимся аспектом была загруженная библиотека pancore.dll, которая создала один поток. Google подсказывает, что pancore.dll — это часть Oracle AutoVue, корпоративного решения для визуализации и просмотра CAD и подобных данных.

Ответ «загадки» пришёл позже. Вот как выглядели результаты анализа файла при первой проверке:

А вот что показывает сайт при повторной загрузке того же файла день спустя (после получения «загадочного» отчёта):

Как видим, результаты проверки изменились: в заголовок были добавлены «интересные» шаблоны поведения, а в полном отчёте появились новые вкладки с анализом поведения файла: какие файлы он открывает, какие URL посещает, какие ключи реестра изменяет, какие процессы запускает, и так далее.

Оказывается, VirusTotal запускает загруженные программы в нескольких виртуальных машинах / песочницах (т.н. multisandboxing), чтобы определить детали поведения. В частности, загруженный нами файл был проверен в C2AE (предположительно, это CAPE Sandbox), утилитой Sysinternals Sysmon, и собственной песочницей VirusTotal: Jujubox.

Такая возможность существует в VirusTotal с 2012 года, когда они использовали VirusTotal Cuckoofork — клон CuckooBox. В 2017 году VirusTotal запустили multi-sandbox, а в 2019 году Cuckoofork заменили на новый Jujubox Sandbox.

Несложно сообразить, что отчёт получился в результате выполнения загруженного файла в одной из этих песочниц (предположительно — Jujubox). Теперь получение «внезапного» отчёта уже не кажется таким удивительным.

Читать на сайте автора.

Создание PDF файла в Linux без графической оболочки используя FastReport FMX

    В комментариях к статье «Создание PDF файла в Windows и Linux» читатели рассказали о использовании для создания документов в формате PDF генератора отчетов FastReport. У

Читать на сайте автора.

MS SQL Server. Преобразование из ASCII в HEX и обратно

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

Читать на сайте автора.

ODAC от Devart

…я хочу вспомнить о библиотеке компонентов, которую я активно использовал много лет назад, и с которой совершенно недавно столкнулся вновь. Речь идёт о библиотеке компонентов,

Читать на сайте автора.

Мир без Delphi. 26-летию Delphi посвящается

    26 лет тому назад, 14 февраля 1995 года, компания Borland выпустила новый продукт для быстрой разработки приложений — Borland Delphi. Я могу писать это предложение

Читать на сайте автора.

Создание PDF файла в Windows и Linux

    Различные операционные системы все больше теснят MS Windows в технических заданиях. Часто все усугубляется пугающим в недалеком прошлом словом «кроссплатформенность». Многие задачи могут потребовать серьезной

Читать на сайте автора.

Добавление EurekaLog в программу вызывает EOutOfResources (Out of system resources)

К нам обратился человек, который пожаловался на то, что его приложение работало нормально, пока он не добавил в него EurekaLog. После включения в проекте EurekaLog стало появляться исключение Out of system resources. Исключение возбуждалось вспомогательной функцией OutOfResources из модуля Vcl.Graphics.

Стек вызова для исключения выглядел следующий образом:

  • Vcl.Graphics.OutOfResources
  • Vcl.Graphics.GDIError
  • Vcl.Graphics.GDICheck
  • Vcl.Graphics.TransparentStretchBlt
  • Vcl.Graphics.TBitmap.Draw
  • Vcl.Graphics.TCanvas.Draw
  • SomeComponent.TSomeDBGrid.DrawCell
  • Vcl.Grids.DrawCells
  • Vcl.Grids.TCustomGrid.Paint
  • Vcl.Controls.TCustomControl.PaintWindow
  • Vcl.Controls.TWinControl.PaintHandler
  • Vcl.Controls.TWinControl.WMPrintClient

Само исключение возбуждается такой функцией:

procedure OutOfResources;
begin
raise EOutOfResources.Create(SOutOfResources);
end;

Которая в свою очередь вызывается из:

procedure GDIError;
const
BufSize = 256;
var
ErrorCode: Integer;
Buf: array [Byte] of Char;
begin
ErrorCode := GetLastError;
if (ErrorCode <> 0) and (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, ErrorCode, LOCALE_USER_DEFAULT, Buf, BufSize, nil) <> 0) then
raise EOutOfResources.Create(Buf)
else
OutOfResources;
end;

function GDICheck(Value: THandle): THandle;
begin
if Value = 0 then
GDIError;
Result := Value;
end;

Заметьте, что такая реализация в VCL имеет проблему: вне зависимоси от ошибки возбуждается исключение класса EOutOfResources, даже если ошибка не равна ERROR_NOT_ENOUGH_MEMORY, ERROR_NO_SYSTEM_RESOURCES (или аналогичной). Логичнее было бы возбуждать что-то типа EInvalidGraphicOperation в общем случае и возбуждать EOutOfResources только для ошибок подобного типа.

Из полного баг-отчёта EurekaLog было видно, что показатели памяти и описателей находятся в разумной норме, т.е. проблема не в нехватке памяти. Откуда следует, что (вероятнее всего) GetLastError вернула 0. В самом деле, строка в TransparentStretchBlt, которая проваливает проверку GDICheck выглядит следующим образом:

MemBmp := GDICheck(CreateCompatibleBitmap(SrcDC, SrcW, SrcH));

Из документации видно, что функция CreateCompatibleBitmap не устанавливает значение GetLastError при неудаче.

Впрочем, у функции не так много причин завершиться неудачей: либо ей переданы неверные аргументы, либо ей нехватает памяти для создания bitmap. Заметьте, что нехватка памяти также возможна, если в SrcW и SrcH находится «мусор», который «слишком большой». Таким образом, хотя мы не знаем точную причину неудачи CreateCompatibleBitmap, но мы можем предположить, что проблема — в аргументах.

Значения SrcDC, SrcW и SrcH являются параметрами функции и приходят в неё из TBitmap.Draw:

TransparentStretchBlt
(ACanvas.FHandle, Left, Top, Right - Left, Bottom - Top,
Canvas.FHandle { SrcDC }, 0, 0,
FDIB.dsbm.bmWidth { SrcW }, FDIB.dsbm.bmHeight { SrcH },
MaskDC, 0, 0);

Где Canvas — это поле FCanvas bitmap-а, создаваемое по запросу, а FDIB — поле из FImage: TBitmapImage. Таким образом, все параметры (SrcDC, SrcW и SrcH) приходят в функцию TransparentStretchBlt из полей объекта класса TBitmap.

Следовательно, TBitmap, который пытается рисовать TSomeDBGrid.DrawCell, повреждён. Поскольку исключения не происходит без EurekaLog, но происходит с EurekaLog, то содержимое памяти TBitmap меняется при включении EurekaLog. Наиболее вероятное объяснение такого поведения: ошибка типа «use after free». Без отладочных инструментов в программе код может обратиться к уже удалённому TBitmap и «успешно» выполнить с ним операцию — поскольку память освобождённых объектов не удаляется физически, а лишь помечается как «свободная», без изменения её содежимого. При добавлении в программу EurekaLog её конфигурация по умолчанию включает проверки памяти, которые стирают память при её освобождении.

Проверить эту гипотезу можно изменив настройку «When memory is released» в положение «Do nothing». Если после этого исключение EOutOfResources пропадёт, то в коде имеется ошибка вида «use after free». Наиболее вероятна ошибка в коде SomeComponent, но есть небольшой ненулевой шанс, что клиент нашёл ошибку в VCL.

К сожалению, мы не получили ответа от клиента.

Читать на сайте автора.

Быстрое заполнение нового столбца таблицы

    Недавно мне дали скрипт для обновления структуры базы данных на MS SQL Server. В нем было полно блоков, которые добавляли в таблицу столбец, заполняли его

Читать на сайте автора.