Отладка приложений




Подключение функций, экспортируемых по порядковому значению - часть 2


 // pImportDesc->FirstThunk, т. к. загрузчик уже изменил этот массив 

// при установке всех импортов. Исходный переходник обеспечивает

 // доступ к именам функций.

 PIMAGE_THUNK_DATA pOrigThunk =

MakePtr ( PIMAGE_THUNK_DATA

hModule , 

pImportDesc->OriginalFirstThunk );

// Получить массив p!mportDesc->FirstThunk, в котором будут

 // выполняться подключения и вся черная работа.

PIMAGE_THUNK_DATA pRealThunk = MakePtr ( PIMAGE_THUNK_DATA ,

hModule , 

pImportDesc->FirstThunk );

// Флажок будет устанавливаться из переходника,

// что облегчает его поиск.

DWORD dwCompareOrdinal = IMAGE JDRDINAL_FLAG | dwOrdinal;

// Цикл поиска подключаемых функций.

while ( NULL != pOrigThunk->ul.Function)

{

// Отыскивать только функции, которые импортируются по

 // порядковому значению, а не по имени, 

if ( IMAGE__ORDINAL_FLAG ==

( pOrigThunk->ul.Ordinal & IMAGE_ORDINAL_FLAG))

 {

// Найдена ли функция подключения? 

if ( dwCompareOrdinal == pOrigThunk->ul.Ordinal) . 

{

// Функция для подключения найдена. Теперь нужно

 // изменить защиту памяти на "read-write" (для записи),

 // прежде чем перезаписывать указатели функций. Заметьте,

 // что ничего не записывается в реальную область 

// переходников!

MEMORY_BASIC__IN FORMATION mbi_thunk ; 

VirtualQuery ( pRealThunk , 

 &mbi_thunk , 

sizeof ( MEMORY_BASIC_INFORMATION) ); 

if ( FALSE == VirtualProtect ( mbi_thunk.BaseAddress,

rabi_thunk.RegionSize ,

 PAGE_READWRITE ,

&mbi_thunk.Protect ))

 {

ASSERT ( !"VirtualProtect failed!");

 // Здесь приходится фиксировать неуспешное 

// выполнение функции (возвращая FALSE),

 // предварительно указав причину ошибки.

 SetLastErrorEx ( ERROR__INVALID_PARAMETER,

SLE^ERROR );

return ( FALSE); 

}

// Сохранить исходные адреса, если требуется

 if ( NULL != ppOrigAddr)




Содержание  Назад  Вперед