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

PE hender из процесса

18.11.2017, 21:37. Показов 1938. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Ситуация такая пишу функцию которая будет ловить pe inject или runPE

как я понял способ только 1, это сравнить IMAGE_DOS_HEADER если правильно понимаю

то есть заголовки файла и процесса который запущен, получить PE hender процесса легко инструкций и примеров сотни...

но как получит тоже самое из памяти процесса? помогите разобраться.


вот пример как получить PE hender из файла

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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <iostream>
#include <fstream>
#include <iomanip>
 
#include <Windows.h>
 
#define Is2power(x) (!(x & (x - 1)))
#define ALIGN_DOWN(x, align) (x & ~(align - 1))
#define ALIGN_UP(x, align) ((x & (align - 1)) ? ALIGN_DOWN(x, align) + align : x) 
 
int main(int argc, const char* argv[])
{
    if (argc != 2)
    {
        std::cout << "Usage: sectons.exe pe_file" << std::endl;
        return 0;
    }
 
    std::ifstream pefile;
    pefile.open(argv[1], std::ios::in | std::ios::binary);
    if (!pefile.is_open())
    {
        std::cout << "Can't open file" << std::endl;
        return 0;
    }
    pefile.seekg(0, std::ios::end);
    std::streamoff filesize = pefile.tellg();
    pefile.seekg(0);
 
    IMAGE_DOS_HEADER dos_header;
    pefile.read(reinterpret_cast<char*>(&dos_header), sizeof(IMAGE_DOS_HEADER));
    if (pefile.bad() || pefile.eof())
    {
        std::cout << "Unable to read IMAGE_DOS_HEADER" << std::endl;
        return 0;
    }
 
    if (dos_header.e_magic != 'ZM')
    {
        std::cout << "IMAGE_DOS_HEADER signature is incorrect" << std::endl;
        return 0;
    }
 
    if ((dos_header.e_lfanew % sizeof(DWORD)) != 0)
    {
        std::cout << "PE header is not DWORD-aligned" << std::endl;
        return 0;
    }
 
    pefile.seekg(dos_header.e_lfanew);
    if (pefile.bad() || pefile.fail())
    {
        std::cout << "Cannot reach IMAGE_NT_HEADERS" << std::endl;
        return 0;
    }
 
    IMAGE_NT_HEADERS32 nt_headers;
    pefile.read(reinterpret_cast<char*>(&nt_headers), sizeof(IMAGE_NT_HEADERS32)-sizeof(IMAGE_DATA_DIRECTORY)* 16);
    if (pefile.bad() || pefile.eof())
    {
        std::cout << "Error reading IMAGE_NT_HEADERS32" << std::endl;
        return 0;
    }
 
    if (nt_headers.Signature != 'EP')
    {
        std::cout << "Incorrect PE signature" << std::endl;
        return 0;
    }
 
    if (nt_headers.OptionalHeader.Magic != 0x10B)
    {
        std::cout << "This PE is not PE32" << std::endl;
        return 0;
    }
 
    DWORD first_section = dos_header.e_lfanew + nt_headers.FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER)+sizeof(DWORD) /* Signature */;
 
    pefile.seekg(first_section);
    if (pefile.bad() || pefile.fail())
    {
        std::cout << "Cannot reach section headers" << std::endl;
        return 0;
    }
 
    std::cout << std::hex << std::showbase << std::left;
 
    for (int i = 0; i < nt_headers.FileHeader.NumberOfSections; i++)
    {
        IMAGE_SECTION_HEADER header;
        pefile.read(reinterpret_cast<char*>(&header), sizeof(IMAGE_SECTION_HEADER));
        if (pefile.bad() || pefile.eof())
        {
            std::cout << "Error reading section header" << std::endl;
            return 0;
        }
 
        if (!header.SizeOfRawData && !header.Misc.VirtualSize)
        {
            std::cout << "Virtual and Physical sizes of section can't be 0 at the same time" << std::endl;
            return 0;
        }
 
        if (header.SizeOfRawData != 0)
        {
            if (ALIGN_DOWN(header.PointerToRawData, nt_headers.OptionalHeader.FileAlignment) + header.SizeOfRawData > filesize)
            {
                std::cout << "Incorrect section address or size" << std::endl;
                return 0;
            }
 
            DWORD virtual_size_aligned;
 
            if (header.Misc.VirtualSize == 0)
                virtual_size_aligned = ALIGN_UP(header.SizeOfRawData, nt_headers.OptionalHeader.SectionAlignment);
            else
                virtual_size_aligned = ALIGN_UP(header.Misc.VirtualSize, nt_headers.OptionalHeader.SectionAlignment);
 
            if (header.VirtualAddress + virtual_size_aligned > ALIGN_UP(nt_headers.OptionalHeader.SizeOfImage, nt_headers.OptionalHeader.SectionAlignment))
            {
                std::cout << "Incorrect section address or size" << std::endl;
                return 0;
            }
        }
 
        char name[9] = { 0 };
        memcpy(name, header.Name, 8);
        std::cout << std::setw(20) << "Section: " << name << std::endl << "=======================" << std::endl;
        std::cout << std::setw(20) << "Virtual size:" << header.Misc.VirtualSize << std::endl;
        std::cout << std::setw(20) << "Raw size:" << header.SizeOfRawData << std::endl;
        std::cout << std::setw(20) << "Virtual address:" << header.VirtualAddress << std::endl;
        std::cout << std::setw(20) << "Raw address:" << header.PointerToRawData << std::endl;
 
        std::cout << std::setw(20) << "Characteristics: ";
        if (header.Characteristics & IMAGE_SCN_MEM_READ)
            std::cout << "R ";
        if (header.Characteristics & IMAGE_SCN_MEM_WRITE)
            std::cout << "W ";
        if (header.Characteristics & IMAGE_SCN_MEM_EXECUTE)
            std::cout << "X ";
        if (header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
            std::cout << "discardable ";
        if (header.Characteristics & IMAGE_SCN_MEM_SHARED)
            std::cout << "shared";
 
        std::cout << std::endl << std::endl;
    }
    system("pause");
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.11.2017, 21:37
Ответы с готовыми решениями:

Завершение процесса при обнаружении другого процесса на .bat или .vbs
Будет всегда висеть в системе не закрываясь и смотреть при открытии даже одной из этих программ notepad.exe aimp.exe tc.exe будет...

Чтение памяти другого процесса по таймеру: нужно ли закрывать хэндл процесса?
В моём варианте работает так: По таймеру (0,1 сек) определяю ID процесса по ехе-шнику, получаю хэндл процесса(открываю процесс) ...

Разработать три процесса: процесс-сервер и два процесса-клиента
Требуется разработать три процесса, запускаемые из командной строки UNIX: процесс-сервер, запускаемый в оперативном режиме, и два...

4
0 / 0 / 0
Регистрация: 17.07.2014
Сообщений: 12
18.11.2017, 22:03  [ТС]
ошибка

"получить PE hender процесса"

получить PE hender файла
0
Maniac
Эксперт С++
 Аватар для ISergey
1465 / 966 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
18.11.2017, 22:52
Цитата Сообщение от Night Wolf Посмотреть сообщение
Ситуация такая пишу функцию которая будет ловить pe inject или runPE
как я понял способ только 1, это сравнить IMAGE_DOS_HEADER если правильно понимаю
не совсем так... этого мало и может не дать нужный результат.
PeInject или runPE как я понимаю может замапить новый имедж не только поверх старого, тоесть:
  • Новый имедж вписали поверх старого, и передали управление.
  • Новый имедж был записан в отдельно записанную память.
  • Записали в память только шелл.
Для первого случаю наверное хватить в памяти сравнивать кодовые секции с оригиналом на диске ( будет ложно кричать если был пакер, но к примеру в системном процессе такого не должно быть)
Для второго немого сложнее, нужно в процессе перебрать всю память по атрибуту IMAGE_SCN_MEM_EXECUTE и если кусок памяти не ссылается в какой-то модуль, то уже подозрительно, а если в одном куске памяти еще присутствует PE то точно гадость.

Ну а если записали только шелл.... хз. нужно как то с потоками игратся и смотреть откуда ноги растут

Цитата Сообщение от Night Wolf Посмотреть сообщение
но как получит тоже самое из памяти процесса? помогите разобраться
C
1
2
3
IMAGE_DOS_HEADER dos_header;
hProcess = OpenProcess(...)
ReadProcessMemory(hProcess, ImageBase, &dos_header, sizeof(IMAGE_DOS_HEADER ), &lpNumberOfBytesRead)
1
0 / 0 / 0
Регистрация: 17.07.2014
Сообщений: 12
18.11.2017, 23:07  [ТС]
Цитата Сообщение от ISergey Посмотреть сообщение
не совсем так... этого мало и может не дать нужный результат.
PeInject или runPE как я понимаю может замапить новый имедж не только поверх старого, тоесть:
  • Новый имедж вписали поверх старого, и передали управление.
  • Новый имедж был записан в отдельно записанную память.
  • Записали в память только шелл.
Для первого случаю наверное хватить в памяти сравнивать кодовые секции с оригиналом на диске ( будет ложно кричать если был пакер, но к примеру в системном процессе такого не должно быть)
Для второго немого сложнее, нужно в процессе перебрать всю память по атрибуту IMAGE_SCN_MEM_EXECUTE и если кусок памяти не ссылается в какой-то модуль, то уже подозрительно, а если в одном куске памяти еще присутствует PE то точно гадость.

Ну а если записали только шелл.... хз. нужно как то с потоками игратся и смотреть откуда ноги растут


C
1
2
3
IMAGE_DOS_HEADER dos_header;
hProcess = OpenProcess(...)
ReadProcessMemory(hProcess, ImageBase, &dos_header, sizeof(IMAGE_DOS_HEADER ), &lpNumberOfBytesRead)
оказывается все гораздо обширней чем казалось на первый взгяд, я на git нашел вот такой детектор написаннанный на c#

моих знаний не хватает чтоб понять все что он делает, но похоже что он только сравнивает

я использовал разные способы runPe и он все определяет

https://github.com/gubed/RunPE-Shield

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
 public bool HasRunPE(ProcessModule module, int processPID)
        {
            string modulePath = module.FileName;
            PEInfomation procPE = PELoader.Load(processPID, module);
            PEInfomation filePE = PELoader.Load(modulePath);
            int unmachedValues = 0;
 
            unmachedValues += ScanType(procPE.FileHeader, filePE.FileHeader); // File Header
            unmachedValues += ScanType(procPE.OptionalHeader32, filePE.OptionalHeader32); // Optional Header
            int sectionAmmount = Math.Min(Convert.ToInt32(procPE.Overview.NumberOfSections), Convert.ToInt32(filePE.Overview.NumberOfSections));
 
            for (int i = 0; i < sectionAmmount; i++)
            {
                unmachedValues += ScanType(procPE.Sections[i], filePE.Sections[i]);
            }
            return (unmachedValues >= 8);
        }
по 2 и 3 пункту нет примеров как используется?
как говориться чтоб понять как защититься от ижекта, надо сначала самому сделать инжект
0
Maniac
Эксперт С++
 Аватар для ISergey
1465 / 966 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
18.11.2017, 23:22
Лучший ответ Сообщение было отмечено Night Wolf как решение

Решение

По второму пункту
https://www.adlice.com/runpe-h... t-process/

C
1
LPVOID pImageBase = VirtualAllocEx(res.hProcess, LPVOID(dwImageBase), src_pe.NtHeadersx86.OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
поменяй на
C
1
LPVOID pImageBase = VirtualAllocEx(res.hProcess, 0, src_pe.NtHeadersx86.OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.11.2017, 23:22
Помогаю со студенческими работами здесь

Порождение нового процесса и запуск программы в рамках порожденного процесса
Цель работы. Изучение программных средств создания процессов, а также простейших способов обмена данными между процессами. Задание к...

Получить id процесса родителя, если исходный id процесса дочерний
Добрый день. У меня есть вот такой код на C#, который должен позволить получить id процесса родителя, если исходный id процесса дочерний: ...

Как сверить имя процесса и путь основного процесса?
Подскажите как мне сверить путь с именем процесса svchost.exe если файл запущен из папки System32 то продолжить поиск, если не из папки то...

Запуск нового процесса в контейнере существующего процесса
Здравствуйте. Недавно задался целью запустить игру(minecraft), которая уже имеется на компьютере, с помощью кода на C#. Реализовал это с...

Завершение процесса при обнаружении другого процесса
Здравствуйте. Люди добрые подскажите пожалуйста как мне быть. Есть приложение которое следит за процессами в диспетчере, запущены 2...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru