45824 (665168), страница 2

Файл №665168 45824 (Методы перехвата API-вызовов в Win32) 2 страница45824 (665168) страница 22016-07-31СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 2)

Существует множество примеров реализации этого метода. Я рассмотрю метод, предлагаемый Microsoft – Detours library.

Detours – это первая официальная библиотека, предназначенная для перехвата функций (не только системных, но и любых других). К основным понятиям Detours относятся:

целевая функция (target function) – функция, перехват которой осуществляется;

функция-перехватчик (detour function) – функция, замещающая перехватываемую;

функция-трамплин (trampoline function) – функция, состоящая из заголовка целевой функции и команды перехода к остальному коду целевой функции.

ПРИМЕЧАНИЕ

Trampoline в переводе с английского – «батут», однако словосочетание «функция-трамплин» более точно передаёт логику её работы.

Таким образом, если целевая функция имеет следующий заголовок:

TargetFunction:

push ebp

mov ebp, esp

push ebx

push esi

push edi

...

то в результате перехвата получится следующее:

TargetFunction:

jmp DetourFunction:

TargetFunction+5:

push edi

...

TrampolineFunction:

push ebp

mov ebp, esp

push ebx

push esi

jmp TargetFunction+5

...

Причём функция-перехватчик может вызывать функцию-трамплин в качестве оригинальной целевой функции.

Библиотека Detours предлагает два метода внедрения «трамплинов» – статический и динамический. Статический метод используется, когда адрес целевой функции известен на этапе сборки модуля. Реализуется он так:

#include

#include //Подключим библиотеку Detours

//Этот макрос создаёт функцию-трамплин для функции Sleep

DETOUR_TRAMPOLINE(VOID WINAPI SleepTrampoline(DWORD), Sleep);

VOID WINAPI SleepDetour(DWORD dw) //Это – функция-перехватчик

{

//В этом примере она ничего не делает, просто вызывает оригинальную функцию

return SleepTrampoline(dw);

}

void main(void)

{

//Здесь осуществляется перехват

DetourFunctionWithTrampoline((PBYTE)SleepTrampoline, (PBYTE)SleepDetour);

//...

//А здесь снимается

DetourRemoveTrampoline(SleepTrampoline);

}

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

#include

#include //Подключим библиотеку Detours

VOID (*DynamicTrampoline)(VOID) = NULL; //Это будет функция-трамплин

VOID DynamicDetour(VOID) //Это – функция-перехватчик

{

//В этом примере она ничего не делает, просто вызывает оригинальную функцию

return DynamicTrampoline();

}

void main(void)

{

//Получим адрес целевой функции

VOID (*DynamicTarget)(VOID) = SomeFunction;

//Здесь осуществляется перехват

DynamicTrampoline=(FUNCPTR)DetourFunction((PBYTE)DynamicTarget, (PBYTE)DynamicDetour);

//...

DetourRemoveTrampoline(DynamicTrampoline); //А здесь снимается

}

При перехвате функция DetourFunction динамически создаёт трамплин и возвращает его адрес. В качестве функции SomeFunction, которая в данном примере возвращает адрес целевой функции, можно использовать DetourFindFunction, которая пытается найти нужную функцию в нужном модуле. Сначала она пытается сделать это через LoadLibrary и GetProcAddress, а в случае неудачи – использует библиотеку ImageHlp для поиска отладочных символов.

Макрос DETOUR_TRAMPOLINE и функция DetourFunction включают в себя встроенный табличный дизассемблер, который определяет, какое количество байт из заголовка целевой функции должно быть скопировано в функцию-трамплин (не менее 5 байт (размер команды jmp), составляющих целое число команд процессора). Если целевая функция занимает менее 5 байт, то перехват оканчивается неудачей.

К достоинствам данного метода следует отнести простоту и надёжность. В отличие от метода с использованием раздела импорта, не нужно учитывать все возможные методы, которыми может быть получен реальный адрес функции. Недостаток – не удастся перехватить функцию с размером менее 5 байт или функцию со следующим заголовком:

push ecx ;в функцию передаётся количество итераций цикла

begin_loop:

;...

;здесь какой-то код

;...

loop begin_loop

ret

Вышеприведённый пример Galen Hunt, один из авторов Detours, прокомментировал следующим образом: «Существует множество теоретических примеров кода, где пролог функции меньше 5 байт, требуемых для команды jmp. Однако никто не сообщал о реальных примерах функции с такими проблемами».

ПРЕДУПРЕЖДЕНИЕ

На момент установки/снятия перехвата нужно останавливать все остальные потоки процесса, в котором происходит перехват (или удостовериться, что они не могут вызывать перехватываемую функцию).

Существует другой способ реализации данного метода. Вместо команды jmp в начало функции помещается команда INT 3, а управление функции-перехватчику передаётся косвенно в обработчике необработанных исключений (её адрес заносится в pExceptionInfo->ContextRecord->Eip и обработчик возвращает EXCEPTION_CONTINUE_EXECUTION). Так как команда INT 3 занимает 1 байт, то вышеописанная ситуация в этом случае даже теоретически невозможна.

ПРЕДУПРЕЖДЕНИЕ

Основным недостатком данного способа является его крайне малое быстродействие (обработка исключения в Windows занимает довольно продолжительное время). Кроме того, наличие обработчика исключений в перехватываемом процессе приведёт к тому, что данный метод работать не будет. Также данный способ не будет работать под отладчиком.

Глобальный перехват

Глобальный перехват может быть реализован различными способами. Первый способ – применение локального перехвата ко всем приложениям в системе (запущенным в момент перехвата или позже). Второй способ – «взлом системы» – подразумевает подмену кода перехватываемой функции непосредственно в DLL-файле или его образе в памяти.

Глобальный перехват методом тотального локального перехвата

Данный метод основан на следующем: если можно перехватить функцию из текущего процесса, то нужно выполнить код перехвата во всех процессах в системе. Существует несколько методов заставить чужой процесс выполнить код перехвата. Самый простой – внести этот код в DllMain некоторой библиотеки, а затем внедрить её в чужой процесс. Методов внедрения DLL также существует несколько (см. Джеффри Рихтер). Самый простой, работающий и в Win9X, и в WinNT – внедрение DLL при помощи ловушек. Реализуется он так: в системе устанавливается ловушка (при помощи функции SetWindowsHookEx) типа WH_GETMESSAGE (эта ловушка служит для перехвата Windows-сообщений). В этом случае модуль, в котором находится ловушка, автоматически подключается к потоку, указанному в последнем аргументе SetWindowsHookEx (если указан 0, то производится подключение ко всем потокам в системе). Однако подключение происходит не сразу, а перед тем, как в очередь сообщений потока будет послано какое-нибудь сообщение. Поэтому перехват осуществляется не сразу после запуска приложения, а перед обработкой процессом первого сообщения. Так что все вызовы перехватываемой функции до обработки процессом первого сообщения перехватываться не будут. А в приложениях без очереди сообщений (например, консольных) этот способ внедрения вообще не работает.

Я написал пример, реализующий глобальный перехват функции GetDriveTypeA с использованием внедрения DLL при помощи ловушек и перехвата с использованием секции импорта.

Функция GetDriveTypeA из библиотеки kernel32.dll используется программами Windows для определения типа диска (локальный, CD-ROM, сетевой, виртуальный и т. д.). Она имеет следующий прототип:

UINT GetDriveType(LPCTSTR lpRootPathName);

lpRootPathName – путь до диска (А:\, В:\ и т.д.)

GetDriveTypeA возвращает одно из следующих значений:

#define DRIVE_UNKNOWN 0

#define DRIVE_NO_ROOT_DIR 1

#define DRIVE_REMOVABLE 2

#define DRIVE_FIXED 3

#define DRIVE_REMOTE 4

#define DRIVE_CDROM 5

#define DRIVE_RAMDISK 6

Перехват этой функции позволяет «обманывать» программы Windows, переопределяя значение, возвращаемое этой функцией, для любого диска.

Программа DriveType2 состоит из двух модулей: DriveType2.exe и DT2lib.dll.

DriveType2.exe реализует интерфейс, а вся работа выполняется в DT2lib.dll.

Проект DT2lib состоит из трёх основных файлов:

APIHook.cpp – этот файл написан Джеффри Рихтером (за исключением некоторых исправлений, сделанных мной. О них я расскажу ниже). В этом файле описан класс CAPIHook, реализующий перехват заданной API-функции во всех модулях текущего процесса. Здесь же автоматически перехватываются функции LoadLibraryA, LoadLibraryW, LoadLibraryExA, LoadLibraryExW и GetProcAddress.

Toolhelp.h – этот файл также написан Джеффри Рихтером. В нём описан класс CToolhelp, реализующий обращение к системным toolhelp-функциям. В данном случае он используется классом CAPIHook для перечисления всех модулей, подключенных к процессу.

DT2Lib.cpp – в этом файле я реализовал перехват функции GetDriveTypeA с использованием класса CAPIHook, а также установку ловушки типа WH_GETMESSAGE, обеспечивающей подключение данного модуля (DT2lib.dll) ко всем потокам в системе.

Как же происходит перехват?

Сразу же после запуска DriveType2.exe вызывается функция DT2_HookAllApps из DT2lib.dll, которая устанавливает ловушку.

BOOL WINAPI DT2_HookAllApps(BOOL fInstall, DWORD dwThreadId)

{

BOOL fOk;

if (fInstall)

{

chASSERT(g_hhook == NULL); // 2 раза перехватывать ни к чему

g_hhook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc,

ModuleFromAddress(DT2_HookAllApps), dwThreadId); // Установим ловушку

fOk = (g_hhook != NULL);

}

else

{

chASSERT(g_hhook != NULL); // Снимать-то нечего

fOk = UnhookWindowsHookEx(g_hhook); // Снимем ловушку

g_hhook = NULL;

}

return(fOk);

}

Функция ловушки GetMsgProc ничего не делает, а просто вызывает следующую функцию ловушки (возможно, не только наша программа установила ловушку, и это, как минимум нужно проверить). Перед тем, как поместить в очередь, ассоциированную с некоторым потоком, какое-то сообщение, система должна вызвать все установленные ловушки типа WH_GETMESSAGE (обычно такие ловушки используются для мониторинга или изменения некоторых сообщений, однако мы ничего подобного не делаем – нам нужно просто подключиться ко всем потокам в системе). Система не может просто вызвать нашу функцию ловушки – она и получатель сообщения находятся в разных процессах, а значит, и в разных адресных пространствах. И выход из этой ситуации один – система просто подключает модуль (а это обязательно должен быть DLL-модуль), в котором находится ловушка, к тому процессу, которому посылается сообщение (что нам собственно и нужно).

Характеристики

Тип файла
Документ
Размер
162,44 Kb
Тип материала
Учебное заведение
Неизвестно

Список файлов реферата

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7027
Авторов
на СтудИзбе
260
Средний доход
с одного платного файла
Обучение Подробнее