С Новым годом! Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 18.10.2019
Сообщений: 31
1

Парсинг импортов PE файла

16.03.2023, 23:25. Показов 1084. Ответов 1

Author24 — интернет-сервис помощи студентам
Здравствуйте, пытаюсь написать программу на ОС Linux.
Программа предназначена для парсинга секций, релокаций и импортов PE файла.

У меня возникла проблема с парсингом импортов 64-х разрядного DLL файла.
К примеру, при обращении к директории импорта и получении его виртуального адреса или имени модуля, происходит Segmentation fault, т.е. адреса, которые необходимы, неверные и равны нулям.

Это происходит только с 64-х разрядным DLL файлом. на 32-х разрядной DLL, парсинг удачный, все адреса правильные.
Сначала я думал что дело в OptionalHeader, т.к. существуют структуры как и для 64-х, так и 32-х (IMAGE_OPTIONAL_HEADER64 и IMAGE_OPTIONAL_HEADER32). Но я пробовал менять, ничего не выходит.

Структуры

Кликните здесь для просмотра всего текста
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
struct import_directory_t
{
    union
    {
        uint32_t  characteristics;                // 0 for terminating null import descriptor
        uint32_t  rva_original_first_thunk;       // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
    };
    uint32_t      timedate_stamp;                 // 0 if not bound,
    // -1 if bound, and real date    ime stamp
    //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
    // O.W. date/time stamp of DLL bound to (Old BIND)
 
    uint32_t      forwarder_chain;                // -1 if no forwarders
    uint32_t      rva_name;
    uint32_t      rva_first_thunk;                // RVA to IAT (if bound this IAT has actual addresses)
};
 
struct image_thunk_data_x86_t
{
    union
    {
        uint32_t        forwarder_string;
        uint32_t        function;
        uint32_t        address;                   // -> image_named_import_t
        struct
        {
            uint32_t    ordinal : 16;
            uint32_t    _reserved0 : 15;
            uint32_t    is_ordinal : 1;
        };
    };
};
 
struct image_named_import_t
{
    uint16_t            hint;
    char                name[1];
};
 
 
struct IMAGE_SECTION_HEADER
{
    BYTE Name[NT_SHORT_NAME_LEN];
 
    union
    {
        uint32_t PhysicalAddress;
        uint32_t VirtualSize;
    } Misc;
 
    uint32_t   VirtualAddress;
    uint32_t   SizeOfRawData;
    uint32_t   PointerToRawData;
    uint32_t   PointerToRelocations;
    uint32_t   PointerToLinenumbers;
    uint16_t   NumberOfRelocations;
    uint16_t   NumberOfLinenumbers;
    uint32_t   Characteristics;
};


Функция парсинга импортов x32 DLL

Кликните здесь для просмотра всего текста
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
std::uint64_t* get_ptr_from_rva(std::uint64_t m_dwRVA, IMAGE_NT_HEADERS* m_pNtHeaders, uint8_t* m_aImage)
{
    auto GetSectionHeader = [m_dwRVA, m_pNtHeaders]() -> IMAGE_SECTION_HEADER*
    {
        IMAGE_SECTION_HEADER* m_pSection = IMAGE_FIRST_SECTION(m_pNtHeaders);
        for (int i = 0; i < m_pNtHeaders->FileHeader.NumberOfSections; i++, m_pSection++)
        {
            std::uint64_t m_dwSize = m_pSection->Misc.VirtualSize;
            if (!m_dwSize)
                m_dwSize = m_pSection->SizeOfRawData;
 
            if ((m_dwRVA >= m_pSection->VirtualAddress) && (m_dwRVA < (m_pSection->VirtualAddress + m_dwSize)))
                return m_pSection;
        }
 
        return nullptr;
    };
 
    IMAGE_SECTION_HEADER* m_pSectionHeader = GetSectionHeader();
    if (!m_pSectionHeader)
        return nullptr;
 
    auto m_dwDelta = (std::uint64_t)(m_pSectionHeader->VirtualAddress - m_pSectionHeader->PointerToRawData);
    return (std::uint64_t*)(m_aImage + m_dwRVA - m_dwDelta);
}
 
 
 
void parse_imports() {
 
    // std::vector< std::uint8_t > m_image -> dll buffer;
 
    // getting dos header
    m_pDOSHeader = reinterpret_cast<IMAGE_DOS_HEADER*>(m_image.data());
    if (!m_pDOSHeader || m_pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
        return;
 
    // getting nt headers
    m_pNTHeaders = reinterpret_cast<IMAGE_NT_HEADERS*>(m_image.data() + m_pDOSHeader->e_lfanew);
    if (!m_pNTHeaders || m_pNTHeaders->Signature != IMAGE_NT_SIGNATURE)
        return;
 
    std::uint64_t* ptr = get_ptr_from_rva(m_pNTHeaders->OptionalHeader.DataDirectory[DIR_IMPORT].VirtualAddress, m_pNTHeaders, m_image.data());
    import_directory_t* import_dir = reinterpret_cast<import_directory_t*>(ptr);
 
 
    for (uint32_t previous_name = 0; previous_name < import_dir->rva_name; previous_name = import_dir->rva_name, ++import_dir) {
 
        auto name_ptr = get_ptr_from_rva(import_dir->rva_name, m_pNTHeaders, m_image.data());
        auto mod_name = std::string(reinterpret_cast<char*>(name_ptr));
 
        printf("module name : %s\n", mod_name.c_str());
        printf("rva_first_thunk : 0x%X\n", import_dir->rva_first_thunk);
 
        auto thunk = reinterpret_cast<image_thunk_data_x86_t*>(
            get_ptr_from_rva(import_dir->rva_original_first_thunk, m_pNTHeaders, m_image.data()));
 
        printf("\nimported functions\n\n");
 
        auto step = x64 ? sizeof(uint64_t) : sizeof(uint32_t);
        for (uint32_t index = 0; thunk->address; index += step, ++thunk) {
 
 
            auto named_import = reinterpret_cast<image_named_import_t*>(get_ptr_from_rva(thunk->address, m_pNTHeaders, m_image.data()));
 
            if (thunk->is_ordinal) {
                printf("found import by ordinal in module %s", mod_name.c_str());
                continue;
            }
 
            printf("function name : %s\n\n", data.name.c_str());
    
        }
    }
}


На выходе получаю

Кликните здесь для просмотра всего текста
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
module name : USER32.dll
rva_first_thunk : 0x2030
 
imported functions
 
function name : MessageBoxA
 
module name : VCRUNTIME140.dll
rva_first_thunk : 0x2038
 
imported functions
 
function name : memset
 
function name : _except_handler4_common
 
function name : __std_type_info_destroy_list
 
module name : api-ms-win-crt-runtime-l1-1-0.dll
rva_first_thunk : 0x2048
 
imported functions
 
function name : _seh_filter_dll
 
function name : _initterm_e
 
function name : _initterm
 
function name : _initialize_narrow_environment
 
function name : _initialize_onexit_table
 
function name : _cexit
 
function name : _configure_narrow_argv
 
function name : _execute_onexit_table
 
module name : KERNEL32.dll
rva_first_thunk : 0x2000
 
imported functions
 
function name : GetCurrentProcessId
 
function name : IsDebuggerPresent
 
function name : InitializeSListHead
 
function name : GetSystemTimeAsFileTime
 
function name : GetCurrentThreadId
 
function name : UnhandledExceptionFilter
 
function name : QueryPerformanceCounter
 
function name : IsProcessorFeaturePresent
 
function name : TerminateProcess
 
function name : GetCurrentProcess
 
function name : SetUnhandledExceptionFilter
 
module name : USER32.dll
rva_first_thunk : 0x2030
 
imported functions
 
function name : MessageBoxA
 
module name : VCRUNTIME140.dll
rva_first_thunk : 0x2038
 
imported functions
 
function name : memset
 
function name : _except_handler4_common
 
function name : __std_type_info_destroy_list
 
module name : api-ms-win-crt-runtime-l1-1-0.dll
rva_first_thunk : 0x2048
 
imported functions
 
function name : _seh_filter_dll
 
function name : _initterm_e
 
function name : _initterm
 
function name : _initialize_narrow_environment
 
function name : _initialize_onexit_table
 
function name : _cexit
 
function name : _configure_narrow_argv
 
function name : _execute_onexit_table
 
module name : KERNEL32.dll
rva_first_thunk : 0x2000
 
imported functions
 
function name : GetCurrentProcessId
 
function name : IsDebuggerPresent
 
function name : InitializeSListHead
 
function name : GetSystemTimeAsFileTime
 
function name : GetCurrentThreadId
 
function name : UnhandledExceptionFilter
 
function name : QueryPerformanceCounter
 
function name : IsProcessorFeaturePresent
 
function name : TerminateProcess
 
function name : GetCurrentProcess
 
function name : SetUnhandledExceptionFilter


С 32-х битной DLL всё работает!

Но если взять 64-х, то я уже получаю Segmentation fault на этой строке
C++
1
2
import_directory_t* import_dir = reinterpret_cast<import_directory_t*>(ptr);
// import_dir -> Segmentation fault
Пожалуйста, помогите!
Компилятор GCC linux_x64
ОС Ubuntu 20.04
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.03.2023, 23:25
Ответы с готовыми решениями:

Большое количество импортов - плохо?
Господа! Кто давно работает в React? Помогите разобраться. Есть некий файл. В нем слишком много...

Как сделать слияние двух импортов в mysql без повторов?
Есть такая задача. Делаю импорт в mysl из файлов *.csv. Один раз, второй раз. Как сделать, чтобы...

Парсинг XML файла и сохранение информации из файла в структуре или массиве
Доброго времени суток. Пытаюсь распарсить XML файл и вытащить оттуда все данные, а после записать...

Парсинг Файла
Всем привет. Сильно не пинайте если не там написал. Подскажите нужен скрипт выполняющее следующие...

1
596 / 418 / 136
Регистрация: 02.10.2008
Сообщений: 1,782
Записей в блоге: 1
17.03.2023, 13:10 2
Поиграться с выравниванием структур через #pragma pack
0
17.03.2023, 13:10
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.03.2023, 13:10
Помогаю со студенческими работами здесь

Парсинг файла
Добрый день. Есть переменная defindex. И есть файл, не в json, но имеющий логическую структуру...

Парсинг файла
Здравствуйте, есть такой файл с расширением *.par(в итоге это обычный .txt) с следующим содержанием...

Парсинг файла
Вопрос отпал сам собой. Удалите тему пожалуйста

Парсинг файла
Хотелось бы запарсить такой вот файлик: { type: 0 target: target_source: attacker_name:...

Парсинг файла
Привет всем! Создаю файл со списком изображений *.png (часть этого списка под спойлером)...

Парсинг файла
Загружаю файл в string, строка в файле только одна, так что масив ненужен. В чем задача стоит?...


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

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
Что такое CQRS и как это реализовать на C# с MediatR
InfoMaster 15.01.2025
Концепция CQRS и её роль в современной разработке В современном мире разработки программного обеспечения архитектурные паттерны играют ключевую роль в создании масштабируемых и поддерживаемых. . .
Как настроить CI/CD с Azure DevOps
InfoMaster 15.01.2025
CI/ CD, или непрерывная интеграция и непрерывное развертывание, представляет собой современный подход к разработке программного обеспечения, который позволяет автоматизировать и оптимизировать процесс. . .
Как настроить CI/CD с помощью Jenkins
InfoMaster 15.01.2025
Введение в CI/ CD и Jenkins В современной разработке программного обеспечения непрерывная интеграция (CI) и непрерывная доставка (CD) стали неотъемлемыми элементами процесса создания качественных. . .
Как написать микросервис на Go/Golang с Kafka и GitHub CI/CD
InfoMaster 14.01.2025
Определение микросервиса, преимущества использования Go/ Golang Микросервис – это архитектурный подход к разработке программного обеспечения, при котором приложение состоит из небольших, независимо. . .
Как написать микросервис с нуля на C# с RabbitMQ, CQRS и CI/CD
InfoMaster 14.01.2025
В современном мире разработки программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот архитектурный подход предполагает. . .
Как создать интернет-магазин на PHP и JavaScript
InfoMaster 14.01.2025
В современном мире электронная коммерция стала неотъемлемой частью бизнеса. Создание собственного интернет-магазина открывает широкие возможности для предпринимателей, позволяя достичь большей. . .
Как написать Тетрис на Ассемблере
InfoMaster 14.01.2025
Тетрис – одна из самых узнаваемых и популярных компьютерных игр, созданная в 1984 году советским программистом Алексеем Пажитновым. За прошедшие десятилетия она завоевала симпатии миллионы людей по. . .
Как создать игру "Танчики" на Unity3d и C#
InfoMaster 14.01.2025
Разработка игр – это увлекательный процесс, сочетающий в себе творчество и технические навыки. В этой статье мы рассмотрим создание классической игры "Танчики" с использованием Unity3D и языка. . .
Организую платный онлайн микро-курс по доработке Android-клиента Telegram
_Ivana 14.01.2025
Официальная версия и распространенные форки не полностью устраивают? Сделай свою кастомную версию клиента! 4 занятия по 2 часа (2 недели пн, ср 19:00-21:00 по Москве). Первое вводное занятие. . .
Как создать приложение для фитнеса для iOS/iPhone на Kotlin
InfoMaster 14.01.2025
Создание собственного фитнес-приложения — это не только захватывающий, но и полезный процесс, ведь оно может стать вашим верным помощником на пути к здоровому и активному образу жизни. В современных. . .
Как создать приложение магазина для iOS/iPhone на Swift
InfoMaster 14.01.2025
Введение в разработку iOS-приложений Разработка приложений для iPhone и других устройств на базе iOS открывает огромные возможности для создания инновационных мобильных решений. В данной статье мы. . .
Это работает. Скорость асинхронной логики велика. Вопрос видимо останется в стабильности. Плата - огонь!
Hrethgir 13.01.2025
По прошлому проекту в Logisim Evolution https:/ / www. cyberforum. ru/ blogs/ 223907/ blog8781. html прилагаю файл архива проекта в Gowin Eda. Восьмибитный счётчик из сумматора+ генератор сигнала. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru