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

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

Жанры

Программирование на 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, и подменять возвращяемое значение при необходимости. А можно и подправить таблицу экспорта аналогичным способом:

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

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

Черный дембель. Часть 1

Федин Андрей Анатольевич
1. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 1

Лишняя дочь

Nata Zzika
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Лишняя дочь

Темный Лекарь 5

Токсик Саша
5. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 5

Последний из рода Демидовых

Ветров Борис
Фантастика:
детективная фантастика
попаданцы
аниме
5.00
рейтинг книги
Последний из рода Демидовых

Чиновникъ Особых поручений

Кулаков Алексей Иванович
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чиновникъ Особых поручений

Попаданка в академии драконов 4

Свадьбина Любовь
4. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
7.47
рейтинг книги
Попаданка в академии драконов 4

Боги, пиво и дурак. Том 6

Горина Юлия Николаевна
6. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 6

Курсант: Назад в СССР 10

Дамиров Рафаэль
10. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: Назад в СССР 10

Сделай это со мной снова

Рам Янка
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сделай это со мной снова

Болотник 2

Панченко Андрей Алексеевич
2. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Болотник 2

Камень Книга двенадцатая

Минин Станислав
12. Камень
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Камень Книга двенадцатая

Небо для Беса

Рам Янка
3. Самбисты
Любовные романы:
современные любовные романы
5.25
рейтинг книги
Небо для Беса

Надуй щеки! Том 4

Вишневский Сергей Викторович
4. Чеболь за партой
Фантастика:
попаданцы
уся
дорама
5.00
рейтинг книги
Надуй щеки! Том 4