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

Здесь есть возможность читать онлайн «Алекс Jenter - Программирование на Visual C++. Архив рассылки» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Программирование на Visual C++. Архив рассылки: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Программирование на Visual C++. Архив рассылки»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ
, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.

Программирование на Visual C++. Архив рассылки — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Программирование на Visual C++. Архив рассылки», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать
Модификация самого обработчика

Эти два способа работают в 99% случаев. Последний процент – это подмена функции, вызываемой внутри чужого модуля, т.е. когда и вызаваемая и вызывающая процедура находятся в одном и том же, да к тому же чужом, модуле. В этом случае, вызов будет сделан напрямик, а не через таблицы импорта/экспорта. Тут уже ничего сделать нельзя. Почти. Можно изменить саму функцию-обработчик , с тем чтобы перенаправить вызовы в нашу собственную. Делается это довольно просто: в начало исходного обработчика прописывается команда безусловного перехода на нашу процедуру, а если нужно вызвать оригинал, то нужно просто сохранить первые 5 байт затертых командой перехода, добавить после них опять-таки команду безусловного перехода на изначальный код +5 байт. Разумется, эти пять байт кода не дожны содержать команд перехода или вызова. Кроме того, может понадобиться больше чем 5 байт, ведь команда перехода посреди длинной инструкции работать не будет. Это случается крайне редко. Обычно код функции, как его генерит компилятор для I86 выглядит примерно так: инициализация стека, загрузка в регистры параметров функции, их проверка и переход в случае неудовлетворительных результатов. Этого вполне хватает чтобы вставить наш маленький перехватчик. Но бывает и так:

CSomeClass::Release:

FF152410E475 call dword ptr [InterlockedDecrement]

85C0 test eax,eax

Или даже

CSomeClass::NonImplemented:

C20400 ret 4

Что, впрочем, можно распознать и вернуть код ошибки если инструкции ret, jmp или call встретится слишком рано. Но вот такой случай распознать не получится:

SomeFunction:

33C0 xor eax,eax

SomeFunction2:

55 push ebp

8BEC mov ebp,esp

Иными словами, модификация SomeFunction приведет к неизвестным изменениям в SomeFunction2 , и, возможно, краху всей системы.

Все это сильно усложняет нам задачу. Нужно дизассемблировать эти байты и проверить каждую инструкцию. Чтобы немного облегчить нам жизнь, фирма Майкрософт разработала специальный SDK для такого рода трюков: Microsoft Detours. С этим SDK задача подмены чужой функции реализуется удивительно просто:

#include

DetourFunction(PBYTE(::MessageBeep), PBYTE(MyMessageBeep));

После чего все вызовы ::MessageBeep(), откуда бы они не были произведены, окажутся вызовами нашей MyMessageBeep(). Что и требовалось.

Модификация самого обработчика 2

Довольно оригинальный вариант предыдущего способа был предложен Дмитрием Крупорницким: первая инструкция перехватываемой функции заменяется инструкцией прерывания INT 3. Далее процедура обработки необработанных исключений (unhandled exception handler) подменяет регистр EIPна адрес нашей функции-перехватчика.

static DWORD_PTR m_dwFunction;

static LONG WINAPI MyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo) {

if (pExceptionInfo->ContextRecord->Eip != m_dwFunction)

return EXCEPTION_CONTINUE_SEARCH;

// Continue execution from MyMessageBeep

pExceptionInfo->ContextRecord->Eip = (DWORD_PTR)MyMessageBeep;

return EXCEPTION_CONTINUE_EXECUTION;

}

LRESULT CMainDlg::OnMethod5(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {

m_dwFunction =

(DWORD_PTR)::GetProcAddress(::GetModuleHandle("USER32.dll"), "MessageBeep");

BYTE nSavedByte = *(LPBYTE)m_dwFunction;

LPTOP_LEVEL_EXCEPTION_FILTER pOldFilter =

::SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);

const BYTE nInt3 = 0xCC;

// Inject int 3

HRESULT hr = WriteProtectedMemory(LPVOID(m_dwFunction), &nInt3, sizeof(const BYTE));

if (SUCCEEDED(hr)) {

::MessageBeep(m_uType);

// Restore function

hr = WriteProtectedMemory(LPVOID(m_dwFunction), &nSavedByte, sizeof(BYTE));

}

::SetUnhandledExceptionFilter(pOldFilter);

return 0;

}

Недостатком такого способа является его непредсказуемость. Кто угодно может зарегистрировать свой обработчик исключений и поломать нам логику. Более того, инструкции (…)/(), часто встречающиеся в программах, могут перехватить управление и не дать нашему обработчику шанса.

Подмена с использованием оберток(wrappers)

Еще один способ, о котором я хотел бы упомянуть. Он заключается в написании собственной динамической библиотеки с тем же именем и набором экспортимых функций. Такая библиотека кладется на место ориганальной, запускается использующий эту библиотеку процесс, тот находит нашу DLL и ничего не подозревая ее использует. А если переименовать оригинальную DLL и положить рядом, то можно даже переадресовывать часть вызовов в оригинальную библиотеку, а часть оставлять себе. К сожалению, это будет работать с экспортируемыми функциями, но не с экспортируемыми переменными. Пример такого рода обертки можно найти у Алексея Остапенко.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

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

Представляем Вашему вниманию похожие книги на «Программирование на Visual C++. Архив рассылки» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Алексей Макеев - Смертельный архив
Алексей Макеев
libcat.ru: книга без обложки
Алексей Апухтин
Отзывы о книге «Программирование на Visual C++. Архив рассылки»

Обсуждение, отзывы о книге «Программирование на Visual C++. Архив рассылки» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x