точка останова, шпионящая за открытием файлов, начинающихся с буквы 'a'
Проблема в том, что если функции CreateFileA передается полное имя файла с путем, наша точка останова уже не сработает, поскольку она проверяет только первый символ имени, а функции поиска подстроки в арсенале soft-ice увы, нет. Как говориться, конструктивно непредусмотрено. Какая жалость, но… хакеры мы или нет?!
Будем исходить из того, что память, лежащая выше указателя стека, как правило свободна и может быть использована по нашему усмотрению. Что если записать туда крошечную ассемблерную программу и передать на нее управление? Если это получится (а это получится, уж поверьте мне, парни) мы сможем неограниченно наращивать функционал отладчика, не прибегая к плагинам, которые не совсем документированы (точнее, совсем не документированы), довольно громоздки, неповоротливы и т. д.
Для выполнения программы на стеке нам очевидно нужен исполняемый стек. Вплоть до настоящего времени это не представляло проблемы и в стеке можно было выполнять любой код без каких бы то ни было ухищрений, но теперь ситуация изменилась и на пике борьбы с вирусами и сетевыми червями, производители процессоров скооперировались с Microsoft и в последних версиях Windows XP, а так же ненавистной мне Longhorn, по умолчанию стек защищен от исполнения, впрочем, при первой же попытке выполнения машинного кода в его окрестностях, система выбрасывает диалоговое окно, предлагающее либо отключить защиту, либо сделать нехорошей программе харакири.
Чтобы осуществить задуманное, мы должны сделать следующее:
q поместить машинный код нашей функции выше вершины стека;
q сохранить текущее значение регистра EIP и регистра флагов (например, в том же стеке);
q сохранить все регистры, которые изменяет наша функция;
q установить EIP на начало нашей функции;
q тем или иным образом передать аргументы (например, через регистры);
q выполнить функцию, возвратив результат работы например через EAX;
q проанализировать возвращенное значение, выполнив те или иные операции;
q восстановить измененные регистры;
q восстановить регистр EIP и регистр флагов;
q продолжить нормальное выполнение программы.
Звучит устрашающе, но ничего сложного в этом нет. Давайте для начала попытаемся выполнить функцию XOR EAX,EAX/RET. Как перевести ее в машинный код? Можно, конечно, воспользоваться HIEW'ом или даже FASM'ом, но зачем выходить из soft-ice? Достаточно переместиться в любое свободное место памяти и дать команду 'a' (assemble – то есть ассемблировать), только предварительно убедитесь, что вы находитесь в контексте отлаживаемого приложения (его имя отображается в правом нижнем углу экрана), а не в ядре, иначе случится крах.
:a esp-10
0023:0012B0DC xor eax,eax
0023:0012B0DE ret
0023:0012B0DF
:d esp-10
0023:0012B0DC 33 C0 C3 00 DB 80 FB 77-88 AE F8 77 FF FF FF FF 3......w...w....
0023:0012B0EC 31 D8 43 00 E8 59 48 00-00 00 00 C0 03 00 00 00 1.C..YH.........