Как получить функцию, расположенную по адресу памяти в Windows - PullRequest
0 голосов
/ 19 апреля 2019

Я пытаюсь получить функцию, расположенную по определенному адресу в DLL.

Я пытался просмотреть разборку DLL, но нет символов отладки.

auto lib = LoadLibrary("lib.dll");
auto proc = GetProcAddress(lib, "proc1"); // Getting the address of the function.

Как мне получить "proc1" (имя функции) из proc (адрес) без вызова GetProcAddress для каждой функции в dll? Кажется, не существует функции для этой цели. Есть ли другой способ получить имя функции?

Ответы [ 2 ]

1 голос
/ 19 апреля 2019

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

, тогда нам нужно получить каталог экспорта через, скажем, ImageDirectoryEntryToData из Dbghelp.dll или через RtlImageDirectoryEntryToData из ntdll.dll и перечислите все функции экспорта.Первый взгляд по имени.если нет имени для такого адреса - смотрите порядковый номер.

void FromAddress(LPCVOID Address)
{
    PVOID BaseOfImage = RtlPcToFileHeader(Address, &BaseOfImage);

    if (!BaseOfImage)
    {
        return;
    }

    ULONG Size;
    PIMAGE_EXPORT_DIRECTORY pied = (PIMAGE_EXPORT_DIRECTORY)
    RtlImageDirectoryEntryToData(BaseOfImage, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &Size);

    ULONG NumberOfFunctions, NumberOfNames;

    if (!pied || !(NumberOfFunctions = pied->NumberOfFunctions))
    {
        return;
    }

    NumberOfNames = pied->NumberOfNames;

    PULONG AddressOfFunctions = (PULONG)RtlOffsetToPointer(BaseOfImage, pied->AddressOfFunctions);
    PULONG AddressOfNames = (PULONG)RtlOffsetToPointer(BaseOfImage, pied->AddressOfNames); 
    PUSHORT AddressOfNameOrdinals = (PUSHORT)RtlOffsetToPointer(BaseOfImage, pied->AddressOfNameOrdinals);

    bool bFound = false;

    if (NumberOfNames)
    {
        do 
        {
            ULONG rva = *AddressOfNames++;

            if (RtlOffsetToPointer(BaseOfImage, AddressOfFunctions[*AddressOfNameOrdinals++]) == Address)
            {
                DbgPrint("%s\n", RtlOffsetToPointer(BaseOfImage, rva));
                bFound = true;
            }
        } while (--NumberOfNames);
    }

    if (!bFound)
    {
        DWORD Base = pied->Base;

        do 
        {
            if (Address == RtlOffsetToPointer(BaseOfImage, *AddressOfFunctions++))
            {
                DbgPrint("#%u\n", Base);
            }
        } while (Base++, --NumberOfFunctions);
    }
}
1 голос
/ 19 апреля 2019

Если вы хотите увидеть список функций внутри DLL, можно использовать инструмент. http://www.dependencywalker.com/

Но я не уверен, что понимаю, зачем тебе это делать во время выполнения. Большую часть времени функции, которую вам нужно использовать из DLL, вы уже знаете имя и параметры и уже имеете готовый заголовок для взаимодействия с ним.

Но если вам действительно нужно выполнить обратный процесс проверки этого проекта с открытым исходным кодом, вы можете найти внутри исходного кода то, что вам нужно. Это в C #, но может дать вам несколько советов. https://github.com/lucasg/Dependencies

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...