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

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

10.02.2025, 23:35. Показов 5071. Ответов 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
Модератор
10061 / 3906 / 885
Регистрация: 22.02.2013
Сообщений: 5,856
Записей в блоге: 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
Модератор
10061 / 3906 / 885
Регистрация: 22.02.2013
Сообщений: 5,856
Записей в блоге: 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
Модератор
10061 / 3906 / 885
Регистрация: 22.02.2013
Сообщений: 5,856
Записей в блоге: 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
Модератор
10061 / 3906 / 885
Регистрация: 22.02.2013
Сообщений: 5,856
Записей в блоге: 79
15.02.2025, 15:31
Цитата Сообщение от YDean Посмотреть сообщение
Как бы RVA адресация не зависит от физического положения секции в файле. Их можно даже перемешать.
А заголовок можно пересоздать с нуля. Разве что Rich-сигнатуры потеряются.
Смотрите. Возьмем гитпотетический exe файл:
Название: Безымянный-1.png
Просмотров: 94

Размер: 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
Модератор
10061 / 3906 / 885
Регистрация: 22.02.2013
Сообщений: 5,856
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Очистка реквизитов и табличных частей документа при копировании
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2. Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
Более приземисто - Эстафету хвоста в .cdl (деревья эстафеты в сад).
Hrethgir 24.07.2026
В будущем, после написания блока инверсии обхода дерева (эстафеты хвоста), я планирую вернуться к нашему прошлому разговору о том, обладают ли знания целеполаганием. Тогда я пришел к выводу, что. . .
Вот представьте что вам дали бессмертие.
kumehtar 24.07.2026
Вот представьте что вам дали бессмертие, ничего более не меняя. Вообще ничего, только бессмертие в нынешнем виде. Рады были бы? Что бы вы тут делали всё это время? Никакой пенсии. Никакого нового. . .
сукцессия 41
anaschu 24.07.2026
Численная верификация бифуркации в агентной модели лесной сукцессии: от одного параметра к ансамблю Автор: пользователь @Shumilov_AS | Раздел: Прикладная математика / Численные методы Кратко. . .
сукцессия 40. Ансамблевая кластерная параметризаци, часть 1.
anaschu 24.07.2026
Пр# Сопровождение научной статьи ИИ-ассистентом: подготовка публикации и калибровка агентно-ориентированной модели сукцессии микоризных систем **Полевые заметки о двухнедельной совместной работе**. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru