45821 (API Spying), страница 3

2016-07-31СтудИзба

Описание файла

Документ из архива "API Spying", который расположен в категории "". Всё это находится в предмете "информатика" из , которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "рефераты, доклады и презентации", в предмете "информатика, программирование" в общих файлах.

Онлайн просмотр документа "45821"

Текст 3 страницы из документа "45821"

Не содержит в себе ничего сложного. Работает по алгоритму установки одной функции-шпиона, в качестве сохранения информации о перехваченной функции сообщает внешнему приложению имя функции и получает в ответ соответствующий этой функции номер.

void* __stdcall myGetProcAddress(HMODULE hLib, const char* name)

{

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

void* address = _GetProcAddress(hLib, name);

if (address == 0)

{

// Не судьба

return NULL;

}

char full_name[MAX_PATH * 2];

GetModuleFileNameA(hLib, full_name, sizeof(full_name)/sizeof(full_name[0]));

strcat(full_name, " ");

if (reinterpret_cast(name) > 0x0000ffff)

{

// Копируем имя

strcat(full_name, name);

}

else

{

// А некоторые функции экспортируются по ординалам...

char ordinal[10];

strcat(full_name, "by ordinal: ");

strcat(full_name, itoa(reinterpret_cast(name), ordinal, 16));

}

COPYDATASTRUCT cd = {0};

// 1 требуется, чтобы учесть в длине завершающий NULL-символ.

cd.cbData = strlen(full_name) + 1;

cd.lpData = full_name;

// посылаем строчку

int number = SendMessage(g_hSecretWindow, WM_COPYDATA, 0,

reinterpret_cast(&cd));

// Генерируем функцию-шпиона

try

{

// См. «Чем же всё это закончится?»

void* spyMem = HeapAlloc(GetProcessHeap(), 0, sizeof(spy_function));

spy_function* spy = new(spyMem) spy_function;

// Устанавливаем её параметры.

spy->number.value = number;

spy->statistic.address.set_absolute(collectStatistic);

spy->func.address.set_absolute(address);

// Возвращаем указатель на функцию-шпион.

return spy;

}

catch (...)

{

// Не судьба

PostMessage(g_hSecretWindow, WM_CANNOTHOOK, number, 0);

// Возвращаем указатель на функцию

return address;

}

}

collectStatistic

Поскольку данных мало и посылать их несложно, функция collectStatistic получилась просто замечательная:

void __stdcall collectStatistic(unsigned long n)

{

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

PostMessage(g_hSecretWindow, WM_CALLED, n, 0);

}

Хранение и отображение

И тем и другим занимается внешнее приложение. Реализовано всё крайне незамысловато:

// Структура, хранящая статистику для одной функции

struct func_descrition

{

std::string name; // Имя функции

int count; // Количество вызовов

};

// Вектор, хранящий всю статистику вообще

std::vector functions;

#define WM_CALLED (WM_USER + 1)

#define WM_CANNOTHOOK (WM_USER + 2)

// Процедура окна, которому внедрённая dll посылает данные

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

switch (uMsg)

{

// Вызвана GetProcAddress

case WM_COPYDATA:

{

// Получаем указатель на переданную структуру

COPYDATASTRUCT* pcd = reinterpret_cast(lParam);

// Получаем имя

char* str = (char*)pcd->lpData;

printf("New function: %s\n", str);

// Новая функция

func_descrition f;

f.count = 0;

f.name = str;

// Добавляем её в вектор

functions.push_back(f);

}

// Возвращаем номер

return (functions.size() - 1);

// Вызвана перехваченная функция

case WM_CALLED:

// Увеличиваем количество вызовов

functions[wParam].count++;

printf("Called %s\n", functions[wParam].name.c_str());

return 0;

// Не удалось установиь перехватчик на функцию

case WM_CANNOTHOOK:

// Уведомляем пользователя

printf("Can not hook %s\n", functions[wParam].name.c_str());

return 0;

}

return DefWindowProc(hwnd, uMsg, wParam, lParam);

}

ПРИМЕЧАНИЕ

Для простоты этот код не проверяет имя функции на уникальность, поэтому в functions может оказаться несколько записей для одной и той же функции.

Внедрение в приложение и перехват GetProcAddress

Так как эта статья не посвящена ни перехвату, ни внедрению (на эти темы есть много других хороших статей), для реализации выбраны простые, но радикальные средства. Внедрение сделано через CreateRemoteThread, а перехват GetProcAddress – заменой её первых пяти байт на команду jmp.

Для передачи внедрённой dll описателя окна, которому она должна посылать сообщения (g_hSecretWindow в примере), использована техника из статьи «HOWTO: Вызов функции в другом процессе».

Чем же всё это закончится?

Будет завершение процесса. Как известно, во время завершения процесса все dll выгружаются, и вся выделенная память освобождается. При этом могут произойти следующие неприятности:

Наша dll будет выгружена раньше времени.

Раньше времени будет освобождена память, в которой расположены сгенерированные функции.

В обоих случаях исследуемое приложение получит Access Violation, после чего говорить о том, что его работа не нарушена, будет достаточно сложно.

Невыгружаемая dll

Поскольку у нашей dll счётчик ссылок всегда больше 0 (LoadLibrary была вызвана, а FreeLibrary нет), она выгружается одной из последних, но в некоторых случаях этого может оказаться недостаточно. Радикальным решением проблемы является «ручная» загрузка dll, описанная в статье Максима М. Гумерова «Загрузчик PE-файлов». Это довольно трудоёмкий, но зато практически гарантированный вариант. Другим возможным решением (для NT/2000/…) может быть удаление dll из списка загруженных модулей в PEB, но как это сделать и будет ли это работать, я пока не знаю…

Последняя идея, пришедшая мне в голову:

честно загрузить dll в процесс, позволить загрузчику выполнить свою работу

скопировать получившийся образ

выгрузить dll

записать в то же место адресного пространства образ dll.

молиться.

Это один из самых «грязных хаков», которые я когда-либо проворачивал :) Иногда оно работает, иногда – нет. И даже если всё на первый взгляд работает, я не берусь сказать, какие будут побочные эффекты.

Подводя итог: если задача и имеет хорошее решение, его описание выходит далеко за рамки этой статьи. Поэтому наша dll будет выгружаться, хотя иногда это и может привести к проблемам.

Неосвобождаемая память

С памятью проще: чтобы её точно никто не освободил, достаточно отказаться от стандартного оператора new, и использовать вместо него placement new, выделяя память как-нибудь иначе.

ПРИМЕЧАНИЕ

Во время тестов обнаружилось, что в Windows XP, при выделении памяти обычным new и статической линковке CRT, некоторые (не все и не всегда, но вполне воспроизводимо) блоки памяти с функциями-шпионами оказываются освобождены. При использовании CRT в dll этой проблемы не было, с чем всё это связано, я не знаю.

Результат

Yes! Оно работает!! :)

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

Нормального тестирования не проводилось, кроме того, у меня под рукой не оказалось Windows NT 4. Но на Windows 2000, XP и 2003 Server проверил, на первый взгляд всё путём… И даже XP SP2 не страшен :)

Для успешного старта надо положить spyloader.exe и apispy.dll в один каталог, после чего запустить spyloader, передав ему в командной строке путь к exe-файлу исследуемого приложения.

Только приготовьтесь к тому, что GetProcAddress – довольно популярная функция, и получить сотню функций-шпионов (то есть вызовов GetProcAddress) при исследовании notepad.exe – не вопрос, достаточно попытаться открыть какой-нибудь файл. А уж если вы запустите справку и немного по ней походите… У меня получилось 530 функций-шпионов за две минуты :) Поэтому, если вы действительно будете реализовывать нечто подобное, то лучше фиксировать не всё подряд, а фильтровать вызовы хотя бы по имени модуля.

Список литературы

Тихомиров В.А. «Перехват API-функций в Windows NT/2000/XP».

Игорь Филимонов «Методы перехвата API-вызовов в Win32»

Intel Corporation «IA-32 Intel Architecture Software Developer’s Manual», части 2A и 2B

Максим М. Гумеров «Загрузчик PE-файлов»

Сергей Холодилов «HOWTO: Вызов функции в другом процессе»

Для подготовки данной работы были использованы материалы с сайта http://www.rsdn.ru/

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