Pull to refresh
14
0
Алексей Шумкин @ashumkin

системный разработчик

Send message

Как найти зловреда (нет) с WinDbg

Reading time 6 min
Views 2.9K

Как найти зловреда (нет) с WinDbg


Вступление


В этой статье я покажу, как, например, с помощью WinDbg найти, какой такой зловред (или нет) заменил адрес вызова системной функции в DLL, подгружаемым каким-нибудь приложением. Так я, к примеру, искал почему не загружается модуль защиты в конфигурацию 1С.
Для демонстрации нам понадобится приложение, которое загружает пару DLL: одну из них назовём victim (жертва), другую — хищник injector. Последнняя внедряется в жертву, заменяя вызов системной функции (для простоты возьмём Sleep), и будет вызывать AV при определённых условиях (что понадобится в следующей статье).


Т.к. приложения, написанные на Delphi, "не падают" в core-dump из-за необработаных исключений, то наше главное приложение (DLLInjectionDemo) написано на С, линковано ранним связыванием с DLL-жертвой, а для простоты воспроизведения ситуации, будет загружать DLL-injector, переданную в опциях при запуске, и вызывать в ней метод, который навредит жертве. Конкретно для этой статьи нам подошло бы приложение, написанное на любом языке программирования, но убьём двух зайцев сразу.


Исходные коды приложений написаны на C и Delphi 10.3 Rio Community Edition, и компилируются MinGW и Delphi, как для Win32, так и для Win64 (а также FPC в Lazarus-е).


Итак компилируем обе DLL и главное приложение

Читать дальше →
Total votes 4: ↑4 and ↓0 +4
Comments 6

Автоматизированная сборка Delphi-приложения

Reading time 14 min
Views 22K

Я довольно часто сталкивался с тем, что разработчики на Delphi (можно сказать традиционно) компилируют свои приложения "ручками", что далеко не production-решение, а со стороны выглядит кустарщиной и "делаем на-коленке", хотя продукты бывают весьма серьёзными и продаваемыми. Вероятно, это пошло ещё с тех пор, когда для автоматизации нужно было придумывать свои батнички, которые запускали компилятор командной строки dcc32 с нужными параметрами. Некоторые даже сделали свой "Публикатор" — Delphi-expert, который делает работу сервера сборок: компилирует (правда, открытый в IDE) проект, выставляя ему взятый из какой-то БД инкрементированный номер версии, записывает некий changelog и копирует это куда-то в сетевой каталог.


Я не буду вдаваться в исторический экскурс как было раньше. Я расскажу как есть/можно сейчас, и как это использовать для повышения эффективности своей работы.


Файл проекта современной версии Delphi — это .dproj-файл (здесь и далее я буду ориентироваться на Delphi 10 Rio, но с небольшими отличиями это верно для всех более ранних версий Delphi, начиная с 2007). В нём хранятся все настройки проекта, которые обычно изменяют в IDE (меню Project - Options (Ctrl+Shift+F11)). В рамках данной статьи я сконцентрируюсь на "основных", которые понадобятся для демонстрации общих принципов: это Config — конфигурация, Platform — платформа, OutputDirectory — путь выходного файла и ConditionalDefines (директивы условной компиляции). Остальные настройки, если таковые нужно менять при сборке, я предлагаю выявить самостоятельно. Этот же .dproj-файл, если в него заглянуть обычным текстовым редактором, является ничем иным как скриптом сборки MSBuild (давайте создадим простое консольное приложение и назовём его DelphiAutomatedBuild):

Читать дальше →
Total votes 28: ↑28 and ↓0 +28
Comments 46

Как организовать тестирование БД в dUnit

Reading time 7 min
Views 7.6K
Как известно, в xUnit-фреймворках, простейший test-case состоит из последовательности вызовов SetUp, TestSomething, TearDown. И довольно часто в unit-тестировании требуется подготовить какие-то ресурсы перед основными тестами. Типичный пример этого — соединение с базой данных. И логика подсказывает нам, что было бы весьма затратно, запуская несколько тестов, перед каждым устанавливать соединение с БД в SetUp, и отключаться в TearDown.

Пример модуля
...
type
  TTestDB1 = class(TTestCase)
  protected
  public
    procedure SetUp; override;
    procedure TearDown; override;
  published
    procedure TestDB1_1;
    procedure TestDB1_2;
  end;
...
implementation
...
procedure TTestDB1.SetUp;
begin
  inherited;
  // connect to DB
end;

procedure TTestDB1.TearDown;
begin
  // disconnect from DB
  inherited;
end;
...
initialization
  RegisterTest(TTestDB1.Suite);
end.



Схема вызовов будет такая:

-- TTestDB1.SetUp
---- TTestDB1.TestDB1_1
-- TTestDB1.TearDown
-- TTestDB1.SetUp
---- TTestDB1.TestDB1_2
-- TTestDB1.TearDown

К тому же с БД может статься, что перед тем, как к БД подключиться, её нужно создать с требуемой структурой.

Для решения такой задачи в dUnit есть класс TTestSetup (описан в модуле TTestExtensions).
Читать дальше →
Total votes 8: ↑7 and ↓1 +6
Comments 2

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity

Specialization

Backend Developer
Lead
Linux
Git
Golang
Docker
OOP
Kubernetes
Python
Design patterns
SQL
Nginx