Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
0 / 0 / 0
Регистрация: 25.07.2022
Сообщений: 29

Добавление секции в Portable Executable

10.02.2025, 23:35. Показов 4623. Ответов 28
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Изучая PE исполняемых файлов стало интересно модифицировать свой hello_world.exe, чтобы он выводил какой-нибудь messagebox. Дело до messagebox-а ещё не долшо, потому что не получается даже секцию добавить, ибо windows мою модификацию обрабатывать отказывается. Порядок действий программы следующий:

1. Прочитать DOS, найти смещение до PE
2. В PE найти кол-во секций
3. Прочитать n секций, чтобы дойти до последней
4. Создать свою секцию
5. Записать секцию в таблицу секций
6. Добавить полезной нагрузки (опционально, ломается и без этого пункта)

Далее код разбитый на вышеупомянутые пункты.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <iostream>
#include <windows.h>
#include <fstream>
#include <string>
#include <vector>
#include <conio.h>
 
using namespace std;
 
DWORD align(DWORD value, DWORD alignment) { //Делает value кратным alignment (Пр. value=89, alignment=32 -> вернёт 96)
    return (value + alignment - 1) & ~(alignment - 1);
}
 
void insert(fstream& file, char what[], int size, int where) { //просто вставляет what между уже записанными данными, что-то типа append в середине файла
    file.seekg(0, ios::end);
    int remaining = (int)file.tellg() - where;
    char* mem = new char[remaining];
    file.seekg(where);
    file.read(mem, remaining);
    file.seekp(where);
    file.write(what, size);
    file.write(mem, remaining);
    delete[] mem;
}
 
int main(int agrc, char* argv[]) {
    char hash[] = "\x55\x8B\xEC\x6A\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\x6A\x00\xFF\x15\x00\x00\x00\x00\x90\x33\xC0\x5D\xC3"; //мой messagebox
 
    fstream file("C:\\Users\\someUser\\Desktop\\app1.exe", ios::in | ios::out | ios::binary);
    if (!file.is_open()) {
        cout << "This file cannot be opened\n";
        _getch();
        return 0;
    }
 
    //Пункт 1
 
    IMAGE_DOS_HEADER dos;
    file.read((char*)&dos, sizeof(dos));
 
    //Пункт 2
 
    IMAGE_NT_HEADERS pe;
    file.seekg(dos.e_lfanew, ios::beg);
    file.read((char*)&pe, sizeof(pe));
    if (pe.Signature != IMAGE_NT_SIGNATURE) {
        cout << "This program cannot be infected\n";
        _getch();
        return 0;
    }
    WORD numOfSec = pe.FileHeader.NumberOfSections;
 
    //Пункт 3
 
    file.seekg(dos.e_lfanew + sizeof(IMAGE_NT_HEADERS), ios::beg);
    IMAGE_SECTION_HEADER* sections = new IMAGE_SECTION_HEADER[numOfSec + 1];
    file.read((char*)sections, sizeof(IMAGE_SECTION_HEADER) * numOfSec);
 
    //Пункт 4
 
    IMAGE_SECTION_HEADER sec{0};
    string secname = ".secsec";
    memcpy(sec.Name, secname.c_str(), secname.size());
    sec.Misc.VirtualSize = align(28, pe.OptionalHeader.SectionAlignment); //28 - это длина хеша с messagebox
    sec.VirtualAddress = align(sections[numOfSec - 1].VirtualAddress + sections[numOfSec - 1].Misc.VirtualSize, pe.OptionalHeader.SectionAlignment);
    sec.SizeOfRawData = align(28, pe.OptionalHeader.FileAlignment);
    sec.PointerToRawData = align(sections[numOfSec - 1].PointerToRawData + sections[numOfSec - 1].SizeOfRawData, pe.OptionalHeader.FileAlignment);
    sec.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE;
    sections[numOfSec] = sec;
 
    //Пункт 5
 
    ++pe.FileHeader.NumberOfSections;
    pe.OptionalHeader.SizeOfImage = align(pe.OptionalHeader.SizeOfImage + sec.Misc.VirtualSize, pe.OptionalHeader.SectionAlignment);
    file.seekp(dos.e_lfanew, ios::beg);
    file.write((char*)&pe, sizeof(pe));
    file.seekp(dos.e_lfanew + sizeof(IMAGE_NT_HEADERS), ios::beg);
 
    //запись новой секции тут
    file.write((char*)sections, sizeof(IMAGE_SECTION_HEADER) * numOfSec);
    insert(file, (char*)&sections[numOfSec], sizeof(IMAGE_SECTION_HEADER), dos.e_lfanew + sizeof(IMAGE_NT_HEADERS) + sizeof(IMAGE_SECTION_HEADER) * numOfSec);
    
    //Пункт 6
 
    file.seekp(sec.PointerToRawData, ios::beg);
    file.write(hash, 28);
    file.close();
    delete[] sections;
    
    cout << "Hash has been injected\n";
    _getch();
}


Возможно ли, что хеш я записываю write-ом, а надо insert-ом? Или же может быть такое, что когда я использую insert для новой секции, где-то на её место указывал какой-то указатель, чем я опять же могу ломать PE. Просто если это так, то как добавить секцию и возможно ли это автоматизировать под любое PE приложение вовсе?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.02.2025, 23:35
Ответы с готовыми решениями:

Удаление TimeDateStamp из Portable Executable
Добрый день. Мне необходимо удалить все штампы времени в исполняемых файлов (иначе контрольные суммы не сходятся при пересборке). Из...

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

Portable Executable (PE-Формат. Теория)
Здравствуйте. Кто сможет однозначно прояснить момент, самый базовый момент, касательно PE-Файла? Правильно ли я понимаю следующую...

28
Модератор
10046 / 3892 / 883
Регистрация: 22.02.2013
Сообщений: 5,844
Записей в блоге: 79
14.02.2025, 17:57
Лучший ответ Сообщение было отмечено Koresup как решение

Решение

Студворк — интернет-сервис помощи студентам
Исходя из 1-го поста у Вас ошибки:

1. При вставке заголовка секций - не нужно раздвигать файл, т.к. все съедет. Обычно в PE файле достаточно места - можно просто перезаписать нули за последней записью в списке секций. Т.е. сделать что-то типа этого: file.write((char*)sections, sizeof(IMAGE_SECTION_HEADER) * (numOfSec + 1));

2. У Вас новая секция записывается в конец файла, но в поле SizeOfRawData у Вас размер с учетом файлового выравнивания, а по факту там без файлового выравнивания.

Цитата Сообщение от Koresup Посмотреть сообщение
Почему файл сразу закрывается? Ну уже неплохо, что хотя бы открывается, но всё же.
А оригинальный app1.exe что должен делать? М.б. там простое консольное приложение которое и закрывается сразу. Вот я у себя сделал внедрение в 64 битный EXE с выводом обычного MessageBox вставку секции с исправлениями о которых выше написал:


По правильному так вставлять секцию не следует. Нужно парсить весь EXE файл, т.к. там еще могут быть EOF данные, которые нужно также переносить.
1
Модератор
10046 / 3892 / 883
Регистрация: 22.02.2013
Сообщений: 5,844
Записей в блоге: 79
14.02.2025, 18:16
Добавлю, чтобы передать управление на вставленный код нужно еще переопределить AddressOfEntryPoint, но и тут работать не будет т.к. шеллкод у Вас содержит 32 битный код который содержит абсолютные адреса:


В 64 битах он выглядит так и тут используется уже RIP адресация:
0
0 / 0 / 0
Регистрация: 25.07.2022
Сообщений: 29
15.02.2025, 00:04  [ТС]
Morgot, alnmem.zip этот уже ошибку выбивает, моя просто закрывается.
0
0 / 0 / 0
Регистрация: 25.07.2022
Сообщений: 29
15.02.2025, 00:20  [ТС]
The trick, да, второй пункт уже исправил. Проблема в том, что использую insert, вместо write-а. Возникает вопрос - всегда ли будет кармашек из нулевых байтов после таблицы секций? Что, если после таблицы не будет места для ещё одного IMAGE_SECTION_HEADER?
0
Модератор
10046 / 3892 / 883
Регистрация: 22.02.2013
Сообщений: 5,844
Записей в блоге: 79
15.02.2025, 12:20
Цитата Сообщение от Koresup Посмотреть сообщение
Возникает вопрос - всегда ли будет кармашек из нулевых байтов после таблицы секций?
В подавляющем большинстве случаев будет хватать. Я ни разу не встречал подобных файлов.

Цитата Сообщение от Koresup Посмотреть сообщение
Что, если после таблицы не будет места для ещё одного IMAGE_SECTION_HEADER?
В общем случае в такой файл не получится засунуть секцию. Проще будет расширить последнюю секцию, засунуть туда код и поменять у нее атрибуты. При сдвиге секций "улетит" вся RVA адресация и без секции релоков нельзя узнать в каких местах была такая адресация. В теории (в файле без релоков) можно попробовать еще сменить базу на 64КБ вниз, а виртуальные адреса соответственно прибавить чтобы при размещении образа абсолютные адреса остались прежними, но это в теории, а на практике неизвестно с какими подводными камнями можно столкнуться.
0
6 / 5 / 1
Регистрация: 06.11.2016
Сообщений: 39
15.02.2025, 14:47
Цитата Сообщение от The trick Посмотреть сообщение
"улетит" вся RVA адресация
Как бы RVA адресация не зависит от физического положения секции в файле. Их можно даже перемешать.
А заголовок можно пересоздать с нуля. Разве что Rich-сигнатуры потеряются.
0
Модератор
10046 / 3892 / 883
Регистрация: 22.02.2013
Сообщений: 5,844
Записей в блоге: 79
15.02.2025, 15:31
Цитата Сообщение от YDean Посмотреть сообщение
Как бы RVA адресация не зависит от физического положения секции в файле. Их можно даже перемешать.
А заголовок можно пересоздать с нуля. Разве что Rich-сигнатуры потеряются.
Смотрите. Возьмем гитпотетический exe файл:
Название: Безымянный-1.png
Просмотров: 80

Размер: 16.1 Кб
В нашем случае SECHDR - заголовки секций стоят "впритык" к данным секции .text. Как вставить новую запись не вызвав конфликт между заголовками и первой секцией? Если в файле данные секции переместить в другое место - это не избавит от того что заголовки секций будут размещены по RVA 0x1000.
0
6 / 5 / 1
Регистрация: 06.11.2016
Сообщений: 39
15.02.2025, 16:10
Цитата Сообщение от The trick Посмотреть сообщение
заголовки секций будут размещены по RVA 0x1000
Согласен.
Ситуация довольно экзотическая. Если в заголовок не напихано недокументированного мусора, то для переполнения размера 1000h там должно быть около 90 секций (x32). А если напихано, то заголовок можно пересоздать.

И хороший инструмент для такого: CFF Explorer.

PS
Посмотрел сейчас для примера notepad.exe от WinXP. Там впритык к последней секции в заголовке идёт блок Bound Import Directory. Еще один подводный камень автору темы.
0
Модератор
10046 / 3892 / 883
Регистрация: 22.02.2013
Сообщений: 5,844
Записей в блоге: 79
15.02.2025, 16:29
Цитата Сообщение от YDean Посмотреть сообщение
Если в заголовок не напихано недокументированного мусора, то для переполнения размера 1000h там должно быть около 90 секций (x32).
Да это я просто для примера привел - открыл exe от VB6. Так если выставить выравнивание секций в 16 к примеру там можно
упереться сразу же:

Другое дело что практически никто так не делает.

Цитата Сообщение от YDean Посмотреть сообщение
Там впритык к последней секции в заголовке идёт блок Bound Import Directory.
Ее можно двигать куда угодно, только в каталогах обновить инфу. По сути нужно весь файл парсить как я изначально и написал и пересобирать его после модификации.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.02.2025, 16:29
Помогаю со студенческими работами здесь

Добавление секции в таблицу
Здравствуйте! Есть такой код --Создаем партиционированную таблицу drop table if exists test1.myTable1; create table...

Добавление секции в EXE файл
Выполняя курсовую работу возникла ошибка. При добавлении секции, она добавляется куда нужно(после всех секций), но при запуске...

Добавление секции в нужное место на Elementor
Ситуация такая. Есть страница сайта с фоновым изображением и заголовком во весь экран. Не получается создать секцию в пределах...

Добавление в очередь (xQueueSend) внутри критической секции
Есть задача, которая заключается в следущем: 1. Входим в критическую секцию. 2. Изменяем некоторые глобальные переменные - для вывода...

Fasm section '.data' readable writeable executable и readable executable
Если section '.data' readable executable, то наш exe файл не сможет записывать в область даты информацию. Будет вылет программы. А если...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
29
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru