Экспортированная функция перенаправлена ​​сама себе?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Экспортированная функция перенаправлена ​​сама себе?

Сообщение Anonymous »

Сегодня я столкнулся с чрезвычайно странной проблемой, когда возился с анализом файловой структуры портативного исполняемого файла Windows. В частности, в таблице экспорта.

Я обнаружил, что получаю сообщение о переполнении стека (так что это казалось наиболее подходящей платой контроля качества) при попытке определить адрес функции экспортированной функции. в DLL.

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

В большинстве ситуаций, с которыми я сталкиваюсь, моя версия работала превосходно и не вызывала никаких проблем. Однако функция была протестирована на DLL с именем API-MS-Win-Core-ProcessThreads-L1-1-0.dll (как часть рекурсивного анализа Kernel32.dll), и именно тогда произошел StackOverflow.

Я сузил его до следующей функции, экспортированной из API-MS-Win-Core-ProcessThreads-L1-1-0.dll:

Код: Выделить всё

CreateRemoteThreadEx
Эта экспортируемая функция на самом деле является перенаправленным экспортом. Обычно это не вызывает беспокойства; Я написал свою функцию так, чтобы она обрабатывала перенаправленный экспорт. Однако эта функция перенаправляется на

Код: Выделить всё

api-ms-win-core-processthreads-l1-1-0.CreateRemoteThreadEx
Кто-нибудь видит здесь проблему? Проходя по коду, моя функция GetProcAddress затем вызывает LoadLibrary в api-ms-win-core-processthreads-l1-1-0, а затем пытается рекурсивно найти CreateRemoteThreadEx . Однако уже на следующей итерации функция CreateRemoteThreadEx снова перенаправляется... в

Код: Выделить всё

api-ms-win-core-processthreads-l1-1-0.CreateRemoteThreadEx
И так начинается StackOverflow. После небольшого расследования я обнаружил, что результат звонка

Код: Выделить всё

LoadLibraryA("api-ms-win-core-processthreads-l1-1-0");
Возвращает тот же результат, что и

Код: Выделить всё

LoadLibraryA("kernel32.dll");
Я в тупике.

Вот мой текущий код:

Код: Выделить всё

#include 

#define MKPTR(p1,p2) ((DWORD_PTR)(p1) + (DWORD_PTR)(p2))

INT LookupExport(IMAGE_DOS_HEADER* pDosHd, DWORD* pNames, DWORD nNames, LPCSTR lpProcName)
{
// Do a binary search on the name pointer table
INT start = 0,
index = -1,
middle = -1,
end = nNames - 1,
cmp = 0;

CHAR *pName;

while (start > 1;
pName = (CHAR*)MKPTR(pDosHd, pNames[middle]);

if ((cmp = strcmp(pName, lpProcName)) == 0)
index = middle; // found
else if (cmp < 0)
start = middle + 1;
else
end = middle;
}

return index;
}

FARPROC InternalGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
BOOL ordinalSearch = HIWORD(lpProcName) == 0;
WORD ordinal = 0;
IMAGE_DOS_HEADER *pDosHd = (IMAGE_DOS_HEADER*)hModule;

if (pDosHd->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;

IMAGE_NT_HEADERS *pNtHd = (IMAGE_NT_HEADERS*)MKPTR(pDosHd, pDosHd->e_lfanew);
if (pNtHd->Signature != IMAGE_NT_SIGNATURE)
return NULL;

IMAGE_DATA_DIRECTORY directory = pNtHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if (directory.Size == 0 || directory.VirtualAddress == 0)
return NULL;

IMAGE_EXPORT_DIRECTORY *pExports = (IMAGE_EXPORT_DIRECTORY*)MKPTR(pDosHd, directory.VirtualAddress);
if (!ordinalSearch)
{
INT index = LookupExport(pDosHd, (DWORD*)MKPTR(pDosHd, pExports->AddressOfNames), pExports->NumberOfNames, lpProcName);
if (index == -1)
return NULL;
ordinal = ((WORD*)MKPTR(pDosHd, pExports->AddressOfNameOrdinals))[index];
}
else
{
ordinal = LOWORD(lpProcName);
}

INT delta = pExports->Base - 1;
DWORD dwAddress = ((DWORD*)MKPTR(pDosHd, pExports->AddressOfFunctions))[ordinal - delta];
// Check whether forwarded:
if (dwAddress >= directory.VirtualAddress && dwAddress < (directory.VirtualAddress + directory.Size))
{
CHAR pForward[256];
strcpy(pForward, (CHAR*)MKPTR(pDosHd, dwAddress));
CHAR *pFunction = strchr(pForward, '.');
if (pFunction == NULL)
return NULL;

// break into seperate parts and recurse
*pFunction++ = 0;
return InternalGetProcAddress(LoadLibraryA(pForward), pFunction);
}

return (FARPROC)MKPTR(hModule, dwAddress);
}
Будем благодарны за любую информацию.

Подробнее здесь: https://stackoverflow.com/questions/147 ... -to-itself
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»