Чтение онлайн

на главную - закладки

Жанры

Программирование на Visual C++. Архив рассылки

Jenter Алекс

Шрифт:
Модификация таблиц импорта/экспорта

Весь API, доступный из какого-либо модуля, описан в так называемой таблице экспорта этого модуля. С другой стороны, список API, необходимый для нормальной работы опять-таки, любого модуля, находится в его таблице импорта.

Код вызова процедуры из другого модуля выглядит примерно так:

call dword ptr [__imp__MessageBeep@4 (004404cc)]

И, если изменить значение по этому адресу, можно подменить оригинальнкю функцию своей. Для этого нам понадобится:

• Отыскать таблицу импорта функций

для нужного нам модуля

• Отыскать там указатель на перехватываемую функцию

• Снять с этого участка памяти утрибут ReadOnly

• Записать указатель на нашу функцию

• Вернуть защиту обратно

HRESULT ApiHijackImports(HMODULE hModule, LPSTR szVictim, LPSTR szEntry, LPVOID pHijacker, LPVOID *ppOrig) {

 // Check args

 if (::IsBadStringPtrA(szVictim, –1) || (!IIS_INTRESOURCE(szEntry) && ::IsBadStringPtrA(szEntry, -1)) || ::IsBadCodePtr(FARPROC(pHijacker))) {

return E_INVALIDARG;

 }

 PIMAGE_DOS_HEADER pDosHeader = PIMAGE_DOS_HEADER(hModule);

 if (::IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER)) || IMAGE_DOS_SIGNATURE != pDosHeader->e_magic) {

return E_INVALIDARG;

 }

 PIMAGE_NT_HEADERS pNTHeaders = MakePtr(PIMAGE_NT_HEADERS, hModule, pDosHeader->e_lfanew);

 if (::IsBadReadPtr(pNTHeaders, sizeof(IMAGE_NT_HEADERS)) || IMAGE_NT_SIGNATURE != pNTHeaders->Signature) {

return E_INVALIDARG;

 }

 HRESULT hr = E_UNEXPECTED;

 // Locate the victim

 IMAGE_DATA_DIRECTORY& impDir =

pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];

 PIMAGE_IMPORT_DESCRIPTOR pImpDesc =

MakePtr(PIMAGE_IMPORT_DESCRIPTOR, hModule, impDir.VirtualAddress),

pEnd = pImpDesc + impDir.Size / sizeof(IMAGE_IMPORT_DESCRIPTOR) - 1;

 while (pImpDesc < pEnd) {

if (0 == ::lstrcmpiA(MakePtr(LPSTR, hModule, pImpDesc->Name), szVictim)) {

if (0 == pImpDesc->OriginalFirstThunk) {

// no import names table

return E_UNEXPECTED;

}

// Locate the entry

PIMAGE_THUNK_DATA pNamesTable =

MakePtr(PIMAGE_THUNK_DATA, hModule, pImpDesc->OriginalFirstThunk);

if (IS_INTRESOURCE(szEntry)) {

// By ordinal

while(pNamesTable->u1.AddressOfData) {

if (IMAGE_SNAP_BY_ORDINAL(pNamesTable->u1.Ordinal) && WORD(szEntry) == IMAGE_ORDINAL(pNamesTable->u1.Ordinal)) {

hr = S_OK;

break;

}

pNamesTable++;

}

} else {

// By name

while(pNamesTable->u1.AddressOfData) {

if (!IMAGE_SNAP_BY_ORDINAL(pNamesTable->u1.Ordinal)) {

PIMAGE_IMPORT_BY_NAME pName = MakePtr(PIMAGE_IMPORT_BY_NAME, hModule, pNamesTable->u1.AddressOfData);

if (0 == ::lstrcmpiA(LPSTR(pName->Name), szEntry)) {

hr = S_OK;

break;

}

}

pNamesTable++;

}

}

if (SUCCEEDED(hr)) {

// Get address

LPVOID *pProc = MakePtr(LPVOID *, pNamesTable, pImpDesc->FirstThunk - pImpDesc->OriginalFirstThunk);

// Save original handler

if (ppOrig) *ppOrig = *pProc;

// write to write-protected memory

return WriteProtectedMemory(pProc, &pHijacker, sizeof(LPVOID));

}

break;

}

pImpDesc++;

 }

 return hr;

}

HRESULT WriteProtectedMemory(LPVOID pDest, LPCVOID pSrc, DWORD dwSize) {

 // Make it writable

 DWORD dwOldProtect = 0;

 if (::VirtualProtect(pDest, dwSize, PAGE_READWRITE, &dwOldProtect)) {

::MoveMemory(pDest, pSrc, dwSize);

// Restore protection

::VirtualProtect(pDest, dwSize, dwOldProtect, &dwOldProtect);

return S_OK;

 }

 return HRESULT_FROM_WIN32(GetLastError);

}

Впрочем,

такой способ не будет работать если используется позднее связывание (delay load) или связывание во время исполнения (run-time load) с помощью ::GetProcAddress. Это можно побороть если перехватить саму ::GetProcAddress, и подменять возвращяемое значение при необходимости. А можно и подправить таблицу экспорта аналогичным способом:

Поделиться:
Популярные книги

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Картофельное счастье попаданки

Иконникова Ольга
Фантастика:
фэнтези
5.00
рейтинг книги
Картофельное счастье попаданки

Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Корнев Павел Николаевич
Фантастика:
фэнтези
героическая фантастика
5.50
рейтинг книги
Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Доктора вызывали? или Трудовые будни попаданки

Марей Соня
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Доктора вызывали? или Трудовые будни попаданки

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Сумеречный стрелок 7

Карелин Сергей Витальевич
7. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок 7

Жизнь под чужим солнцем

Михалкова Елена Ивановна
Детективы:
прочие детективы
9.10
рейтинг книги
Жизнь под чужим солнцем

Красноармеец

Поселягин Владимир Геннадьевич
1. Красноармеец
Фантастика:
боевая фантастика
попаданцы
4.60
рейтинг книги
Красноармеец