Print This Post Логируем необрабатываемые исключения

Пятница, 21. Декабрь 2012
Раздел: C/C++, Windows, автор:

Надоело созерцать зелёную морду на титульной странице блога, поэтому настало время эту морду сместить.

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

Основу библиотеки фактически будет составлять одна функция - MiniDumpWriteDump, которая делает дамп памяти процесса. Этот дамп впоследствии можно открыть, например, в WinDBG и посмотреть причину неожиданного падения процесса. Также хочу отметить, что мы "покладем" на замечание из MSDN о необходимости вызова данной функции из отдельного процесса.
Читать дальше »

Print This Post Защищаем пароль в TeamViewer

Суббота, 27. Октябрь 2012
Раздел: Assembler, C/C++, Windows, автор:

TeamViewer, как и большинство программных продуктов, обладает опцией сохранения пароля от своего профиля (профиль используется для упорядоченного хранения перечня идентификаторов удаленных компьютеров с реквизитами доступа к ним). При включенной опции сохранения, пароль прозаично сохраняется в реестре по адресу HKCU\Software\TeamViewer\Version* в переменной BuddyLoginPWAES.


Как видно из названия переменной, да и непосредственно из реестра, перед сохранением пароль шифруется, однако это не является проблемой, т.к. ключи шифрования легко получить, а также никто не мешает просто скопировать содержимое переменной из реестра, перенести на другой компьютер и там успешно авторизоваться. Отсюда возникает некоторое опасение, так как всегда существует вероятность запустить очередной password stealer, который всё благополучно утащит.
Попробуем решить эту проблему костыльно-велосипедным способом. Для этого напишем небольшую библиотеку, которая будет перехватывать обращения к реестру и осуществлять дополнительное шифрование пароля, а также лаунчер для тимвьювера, который будет запускать его и заодно подгружать нашу библиотеку.
Читать дальше »

Print This Post Пишем упаковщик по шагам. Шаг 11. Интерфейс командной строки. Финальная версия.

Четверг, 4. Октябрь 2012
Раздел: C/C++, Windows, Для новичков, автор:

Предыдущий шаг здесь.

Появилась новая версия библиотеки для работы с PE-файлами (0.1.9). Никакие баги там поправлены не были, был добавлен функционал, который упаковщик не использует, так что ваше дело, перекачивать ее или нет :)

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

Читать дальше »

Print This Post Менеджер плагинов для клиента LastFM

Суббота, 29. Сентябрь 2012
Раздел: C/C++, Windows, автор:

В перерыве между состоянием ретроспективной рефлексии и созерцанием километровых постов dx'a немного пришел в себя и решил сделать какой-нибудь пост в блог.

В результате написал небольшую вспомогательную библиотеку, которая позволяет загружать-выгружать "плагины" в клиент LastFM. Если быть точным, то не совсем плагины, а своеобразные надстройки, которые я несколько раз описывал, например, тут и тут.
GUI минималистичен и выглядит следующим образом:

Функционал элементарен. Окно менеджера можно вызвать с помощью нажатия Alt+M. В контекст клиента LastFM библиотеку следует либо грузить инжектором, либо править импорты, либо ещё как-нибудь.

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

Исходный код и скомпилированная версия менеджера: скачать.

Print This Post Пишем упаковщик по шагам. Шаг девятый. Delay-loaded DLLs и Image Config.

Пятница, 28. Сентябрь 2012
Раздел: C/C++, Windows, Для новичков, автор:

Предыдущий шаг здесь.

Появилась новая версия библиотеки для работы с PE-файлами (0.1.8). Перекачайте и пересоберите ее.

Сегодня мы будем заниматься теми мелочами, на которые я в свое время забил при написании старого упаковщика. Наш распаковщик уже умеет всё, но есть пара мелких нюансов, которые неплохо бы допилить. Первое - это отложенный импорт (Delay-loaded). Этот механизм позволяет загружать необходимые PE-файлу библиотеки тогда, когда они реально становятся нужны, тем самым экономя время на загрузку образа в память. Механизм этот реализуется исключительно компиляторами/линкерами и никакого отношения к загрузчику не имеет, однако в PE-заголовке есть директория IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, указывающая на данные отложенного импорта. Не знаю, используется ли это линкером и собранной программой, но загрузчику определенно пофиг. Но лучше оставим эту директорию, не будем ее обнулять. Уберем строку

Читать дальше »

Print This Post Пишем упаковщик по шагам. Шаг восьмой. DLL и экспорты.

Среда, 26. Сентябрь 2012
Раздел: Assembler, C/C++, Windows, Для новичков, автор:

Предыдущий шаг здесь.

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

Пока что можно немного расслабиться - в упаковщике кода добавится совсем немного (в распаковщике, в общем-то, тоже, но он будет на ассемблере).

Читать дальше »

Print This Post Пишем упаковщик по шагам. Шаг седьмой. Релокации.

Вторник, 25. Сентябрь 2012
Раздел: C/C++, Windows, Для новичков, автор:

Предыдущий шаг здесь. Там, кстати, имелась ошибка в коде, я ее поправил. Она проявлялась, когда у файла было больше одного TLS-коллбэка.

Появилась новая версия библиотеки для работы с PE-файлами (0.1.7). Перекачайте и пересоберите ее.

Перейдем к следующей немаловажной части многих PE-файлов - релокациям. Они используются, когда невозможно загрузить образ по указанному в заголовке базовому адресу. Преимущественно такое поведение характерно для DLL-файлов (они в принципе без релокаций не могут нормально работать). Представьте, что exe-файл грузится по адресу 0x400000. Этот exe-файл грузит DLL, которая также грузится по этому адресу. Адреса совпадают, и загрузчик будет искать релокации у DLL-файла, потому что он грузится вторым после exe. И если релокаций не будет, то загрузка не пройдет.

Сами релокации - это просто набор таблиц с указателеми на DWORD'ы, которе загрузчик должен пересчитать, если образ загружается по адресу, отличному от базового. Типов релокаций много, но реально в x86 (PE) используются только два: IMAGE_REL_BASED_HIGHLOW = 3 и IMAGE_REL_BASED_ABSOLUTE = 0, причем второй ничего не делает, а нужен только для выравнивания таблиц релокаций.

Сразу скажу, что загрузчик exe-файлы грузит практически всегда по базовому адресу, не применяя релокации. DLL наш упаковщик паковать пока не умеет, поэтому для теста упаковки релокаций мы должны создать exe-файл с некорректным базовым адресом, и тогда загрузчик будет вынужден этот файл в памяти переместить. Я тут не буду приводить исходный код проекта для теста, вы найдете его в солюшене в конце статьи. Базовый адрес загрузки (Linker - Advanced - Base Address) я выбрал 0x7F000000.

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

Чтобы дать загрузчику знать о том, что у нашего файла есть релокации, делать ничего и не надо - у нас еще от оригинального файла остались нужные флаги, выставленные в заголовках PE-файла. Однако, нам нужно знать, по какому адресу файл загрузился.

Читать дальше »

Print This Post Пишем упаковщик по шагам. Шаг шестой. TLS.

Пятница, 21. Сентябрь 2012
Раздел: Assembler, C/C++, Windows, Для новичков, автор:

Предыдущий шаг здесь.

Появилась новая версия библиотеки для работы с PE-файлами (0.1.5). Перекачайте и пересоберите ее.

Пришло время заняться обработкой такой важной вещи, как Thread Local Storage (TLS) - локальной памяти потока. Что она из себя представляет? Это небольшая структура, которая говорит загрузчику PE-файлов о том, где находятся данные, которые должны быть выделены в памяти для каждого потока. Загрузчиком также производится вызов функции TlsAlloc, и значение, возвращенное ей, записывается по адресу, также указанному в этой структуре (называется это индексом). Кроме того, эта же структура может содержать адрес массива, хранящего набор коллбэков (адресов функций), которые будут вызваны загрузчиком при загрузке файла в память или при создании нового потока в процессе.

С TLS, признаться честно, все будет несколько хардкорнее, чем с остальным, так что приготовьтесь и напрягите мозг. Мой прошлый упаковщик TLS-коллбэки не поддерживал, трусливо выдавая сообщение о том, что они есть, но не обрабатываются. В принципе, поведение разумное, так как TLS-коллбеки имеют в основном всякие странные файлы, использующие эту вещь как антиотладочный прием. Ни один штатный линкер, вроде линкера от Майкрософт или Борланд, не поддерживают создание TLS-коллбэков. Тем не менее, для создания годного упаковщика мы их поддержку запилим.

Читать дальше »

Print This Post Пишем упаковщик по шагам. Шаг пятый. Ресурсы.

Среда, 19. Сентябрь 2012
Раздел: C/C++, Windows, Для новичков, автор:

Предыдущий шаг здесь.

Пора усовершенствовать наш упаковщик. Он уже способен упаковывать и запускать самые простые бинарники, имеющие лишь таблицу импорта. Бинарники с экспортами, ресурсами, TLS, DLL с релокациями ему пока что не под силу. Нужно над этим работать. Для начала сделаем обработку второй по важности вещи после импортов - директории ресурсов.

Читать дальше »

Print This Post Пишем упаковщик по шагам. Шаг четвертый. Запускаем.

Вторник, 18. Сентябрь 2012
Раздел: C/C++, Windows, Для новичков, автор:

Предыдущий шаг: здесь.

Появилась новая версия библиотеки для работы с PE-файлами (0.1.4). Перекачайте и пересоберите ее.

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

Читать дальше »