[Из песочницы] Отключение главной нити приложения от отладчика и уход от перехвата CreateFile()
Это будет пробная статья на хабре, скажем так, первый блин :) Основывается она на материалах блога: alexander-bagel.blogspot.ru/ Поэтому все отсылки к контексту, подразумевают изучение ранее опубликованных материалов. Собственно приступим к цитированию: Как уже описывалось ранее, стандартным приемом, осложняющим изучение вашего приложения, является эмуляция выполнения API функций. Рассмотрим некий частный случай. Например, когда требуется определить критическое место в приложении, допустим, открытие самого себя с целью проверить контрольную сумму приложения, устанавливается BP на API функцию CreateFile (), где мы будем ждать входного параметра с путем к нашему исполняемому файлу, после чего в отладчике пройдем до кода, вызвавшего данную функцию и приступим непосредственно к анализу. Можно поступить даже еще проще, взяв утилиту Process Monitor, за авторством небезызвестных Марка Руссиновича и Брюса Когсвела. Данная утилита, абсолютно спокойно показывает полный стек вызовов, включая интересующие нас адреса возврата. Нам остается только запустить отладчик и установить BP на нужный адрес. Правда данная утилита показывает уже адреса возврата, а не сам адрес вызова непосредственной функции. Но об этом позже. Представьте, что тело нашего приложения уже изменено. Самым простым решением обхода проверки контрольной суммы приложения, будет подмена параметра lpFileName в перехваченной функции CreateFile () на путь к не измененному телу приложения. После данной операции не нужно даже изучать механизм расчета контрольной суммы, не важно что там применяется, проверка цифровой подписи, MD5 хэш или банальная CRC32. Т.к. данный алгоритм будет работать с телом оригинального приложения — все проверки будут успешно пройдены. Стало быть задача выглядит в первом приближении так: максимально затруднить возможность изменения параметров вызываемой функции. Использование навесных защит в данном случае не спасет, т.к. в итоге всегда останется вызов функции CreateFile (), тело которой поместить под защиту виртуальной машины мягко говоря проблематично (тут с нюансом, некоторые навесные защиты могут самостоятельно проэмулировать данный вызов, но сейчас речь не о них). Одним из вариантов обхода CreateFile () является прямой вызов соответствующей функции ядра, в обход kernel32→kernelbase→ntdll. Результат такого вызова можно увидеть на картинке: При прямом вызове уже не идет речь о установке BP на какие либо функции, т.к. такие вызовы попросту отсутствуют. Да, у нас остается на руках адрес возврата после вызова, но нюанс в том, что подавляющее большинство современных навесных протекторов достаточно толково размазывают код и наличие на руках кода возврата вызова еще не означает, что мы сможем определить место самого вызова с целью изменить тот или иной параметр.Читать дальше →