• XSS.stack #1 – первый литературный журнал от юзеров форума

Различие количества NumberOfFunctions в коде и PE-Bear

ymmfty0

HDD-drive
Пользователь
Регистрация
28.10.2022
Сообщения
29
Реакции
5
Приветствую всех! Я хотел бы узнать, из-за чего происходит отличие в значениях. При получение NumberOfFunctions при помощи этого кода
C++:
std::ifstream inputFile("C:\\Windows\\System32\\kernel32.dll", std::ios_base::binary);
inputFile.seekg(0, std::ios_base::end);
auto length = inputFile.tellg();
inputFile.seekg(0, std::ios_base::beg);

std::vector<BYTE> buffer(length);
inputFile.read(reinterpret_cast<char*>(buffer.data()), length);

std::cout << std::hex << buffer.data() << std::endl;

PBYTE pBaseAddrDll = buffer.data();

IMAGE_DOS_HEADER pBaseDosHdrDll = *reinterpret_cast<PIMAGE_DOS_HEADER>(pBaseAddrDll);

if (pBaseDosHdrDll.e_magic != IMAGE_DOS_SIGNATURE)
{
    std::cout << "Incorrect DLL loaded" << std::endl;
    return -1;
}

PIMAGE_NT_HEADERS ntHeaderDll = reinterpret_cast<PIMAGE_NT_HEADERS>
    ( reinterpret_cast<PBYTE>(pBaseAddrDll) + pBaseDosHdrDll.e_lfanew) ;

if (ntHeaderDll->Signature != IMAGE_NT_SIGNATURE)
{
    std::cout << "Incorrect DLL loaded" << std::endl;
    return -1;
}

IMAGE_DATA_DIRECTORY exportDirectoryTable =
    ntHeaderDll->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];

PIMAGE_EXPORT_DIRECTORY exportDirectory =
    reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(
        reinterpret_cast<PBYTE>(pBaseAddrDll) + exportDirectoryTable.VirtualAddress
    );

std::cout << "number of functions " << exportDirectory->NumberOfFunctions << std::endl;
std::cout << "base " << exportDirectory->Base << std::endl;
std::cout << "Name: " << reinterpret_cast<char*>(reinterpret_cast<PBYTE>(pBaseAddrDll) + exportDirectory->Name) << std::endl;

Я получаю вот такой результат:
Код:
number of functions: 687
number of names: 687
Base: 1
Name: KERNEL32.dll

PE-Bear отображает мне совершенно другой результат

1727937587137.png


Из-за чего такое может происходить ? Буду рад любой помощи.Заранее спасибо
 
Если ты читаешь файл с диска, то тебе нужно переводить RVA в файловое смещение, так как файла нет в памяти и он не смаплен и соответственно нормально не выровнен.
C++:
DWORD AlignUp(DWORD rva, DWORD aligment)
{
    if (aligment >= rva)
        return aligment;
    else
        return rva + (rva % aligment);
}

DWORD RvaToOffset(DWORD rva, PIMAGE_NT_HEADERS ntHeaders)
{
    PIMAGE_SECTION_HEADER sectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(reinterpret_cast<DWORD>(&ntHeaders) + sizeof(IMAGE_NT_SIGNATURE) + sizeof(IMAGE_FILE_HEADER) + ntHeaders->FileHeader.SizeOfOptionalHeader);

    for (INT i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++)
    {
        if (rva >= sectionHeader[i].VirtualAddress && rva < sectionHeader[i].VirtualAddress + AlignUp(rva, ntHeaders->OptionalHeader.SectionAlignment))
            return sectionHeader[i].PointerToRawData + (rva - sectionHeader[i].VirtualAddress);
    }

    return 0; //Не нашли
}
Почитать про это можно тут: Кстати, PE Bear выдает ошибку, потому что 687h это правильное кол-во функций в kernel32.dll , возможно ты не ту битность открыл (хотя почему в таком случае PE Bear не помешал этому?). CFF Explorer всё корректно выводит
1727978739821.png
 
Последнее редактирование:
Видимо тут , конкретно проблема с PE-Bear, потомучто действительно CFF Explorer выдает тот же результат, что и мой код. И кстати, значение не отличаются, что я читаю с файлового пространства и если я загружу DLL , через LoadLibraryA
 
Если ты читаешь файл с диска, то тебе нужно переводить RVA в файловое смещение, так как файла нет в памяти и он не смаплен и соответственно нормально не выровнен.
C++:
DWORD AlignUp(DWORD rva, DWORD aligment)
{
    if (aligment >= rva)
        return aligment;
    else
        return rva + (rva % aligment);
}

DWORD RvaToOffset(DWORD rva, PIMAGE_NT_HEADERS ntHeaders)
{
    PIMAGE_SECTION_HEADER sectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(reinterpret_cast<DWORD>(&ntHeaders) + sizeof(IMAGE_NT_SIGNATURE) + sizeof(IMAGE_FILE_HEADER) + ntHeaders->FileHeader.SizeOfOptionalHeader);

    for (INT i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++)
    {
        if (rva >= sectionHeader[i].VirtualAddress && rva < sectionHeader[i].VirtualAddress + AlignUp(rva, ntHeaders->OptionalHeader.SectionAlignment))
            return sectionHeader[i].PointerToRawData + (rva - sectionHeader[i].VirtualAddress);
    }

    return 0; //Не нашли
}
Почитать про это можно тут: Кстати, PE Bear выдает ошибку, потому что 687h это правильное кол-во функций в kernel32.dll , возможно ты не ту битность открыл (хотя почему в таком случае PE Bear не помешал этому?). CFF Explorer всё корректно выводит
Посмотреть вложение 96339
Кстати не могу понять, почему это происходит, раз ты говоришь про RVA и он не будет работать , потомучто DLL нет в памяти. Но мой код , как я выяснил работает корректно и он не требует вычисления offset из RVA
 
Кстати не могу понять, почему это происходит, раз ты говоришь про RVA и он не будет работать , потомучто DLL нет в памяти. Но мой код , как я выяснил работает корректно и он не требует вычисления offset из RVA
Если честно не знаю почему так происходит, мб тут найдуются эксперты кто ответит на этот вопрос, думаю файл на диске уже выровнен под нужные значения в целях оптимизации? Это же кернел32, он используется чаще всего...Попробуй на других файлах.
 
PE-Bear отображает мне совершенно другой результат

Посмотреть вложение 96324

Из-за чего такое может происходить ? Буду рад любой помощи.Заранее спасибо
У тебя винда x64 а PE-Bear x32 версия? А кернел32 ты грузил сразу из C:\Windows\System32 в PE-Bear? Если да, то все верно, PE-Bear из за fs редиректа подгрузил SysWow64 версию кернел32, в ней меньше экспортов чем в нативной
 
У тебя винда x64 а PE-Bear x32 версия? А кернел32 ты грузил сразу из C:\Windows\System32 в PE-Bear? Если да, то все верно, PE-Bear из за fs редиректа подгрузил SysWow64 версию кернел32, в ней меньше экспортов чем в нативной
Оказывается, действительно , PE-Bear у меня x32, а windows x64 , спасибо не знал. Проверил, загрузил и все стало на свои места. Не много не понял правда что такое fs redirect, но изучу, если есть что-то конкретное , можешь пожалуйста мне это скинуть про это, спасибо
1728462150195.png
 
Последнее редактирование:
Оказывается, действительно , PE-Bear у меня x32, а windows x64 , спасибо не знал. Проверил, загрузил и все стало на свои места. Не много не понял правда что такое fs redirect, но изучу, если есть что-то конкретное , можешь пожалуйста мне это скинуть про это, спасибо
Посмотреть вложение 96541
Fs redirector это часть wow64. https://learn.microsoft.com/en-us/windows/win32/winprog64/file-system-redirector
 
Спасибо, а не знаете почему, происходит так , то что как выше писали , если я читаю файл с системы , нужно переводить RVA в offset , но RVA работает корректно в моем случае для kernel32 ?
На windows 10 не будет работать корректно. На windows 11, первые секции выровнены, rva=offset, а экспорты как раз в .rdata

Windows 10

N5d_j


Windows 11

JBXws
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх