Дрессированные окна Александр Гайша Хакер, номер #086, стр. 086-116-4 function lpEnumFunc(hWind:HWND;lPar:LPARAM):Boolean;stdcall; var wintext:PChar; begin GetMem(wintext,128); GetClassName(hWind,wintext,127); if(CompareText(wintext,'EDIT')=0)then begin hPassEdit:=hWind; Result:=FALSE; end else Result:=TRUE; FreeMem(wintext); end; В приведенной функции, в общем-то, ничего сложного: выделили немного памяти под переменную строку, потом вызвали API-функцию GetClassName, которая по хэндлу окна возвращает имя его класса в текстовой форме. Если это имя совпадает с мистическим «Edit», то мы вернем FALSE (а значит, перебор дочерних окон прекратится, потому что в основной программе возврат этой функции дает условие выхода из цикла while-do). Иначе, если это какой-нибудь «Static», то пусть еще перебирает. Хэндл текстового поля, куда будем вводить пароль, мы нашли и сохранили в hPassEdit. Теперь есть два варианта развития событий: полный перебор всех возможных комбинаций (это очень долго даже с таким ускоренным автоматизацией методом, как наш) и атака с помощью словарю (это уже реальнее). Правда, если первый вариант не требует ничего дополнительного, то для второго нужен будет словарик – текстовый файл, в котором будут выписаны различные часто употребляемые слова-пароли. Впрочем, на дисках журнала такие файлы иногда встречаются, поэтому постоянным читателям даже искать в инете ничего не придется. Спросим у пользователя, хочет ли он брутфорс от балды или атаку по словарю. В первом случае также спросим, какое максимальное количество символов в комбинации требуется для перебора, во втором – откроем словарь и спросим, какой длины слова оттуда брать. Все это ты и сам сможешь реализовать. В общем, тут все не выходит за рамки школьного курса программирования и легко реализуется парой операторов: writeln, readln и if-then-else. Теперь, когда все готово к непосредственному запуску перебора, возникает еще одна засада. Если мы просто в консольной программке запустим какой-нибудь длительный цикл, то она как бы подвиснет :). На самом деле она, конечно, будет мирно просчитывать всякие там нужные ей вещи, но реагировать ни на что не будет, пока не закончится ее цикл. Для такого случая в винде предусмотрено создание дополнительных потоков приложения. То есть основной поток занимается интерфейсом и реагирует на пользователя, а второй (третий, восемнадцатый и т.д.) обсчитывает прикладную задачу. Короче, для всей длительной работы надо создавать новые потоки. Это делается API-функцией CreateThread (описание находится во врезке). Параметров у нее куча, да только нам надо лишь указать процедуру, которая будет выполняться в потоке (у нас - lpStartRoutine). hThread:=CreateThread(nil,0,@lpStartRoutine,nil,0,ThreadID); Итак, начнется наш второй поток входом в функцию lpStartRoutine, а закончится - выходом из нее. Первый поток будет обрабатывать действия пользователя и, когда тот окончательно задолбается, позволит ему культурно выйти из программы, без всяких там приколов в стиле «Программа сейчас пошла погулять, зайди попозже». |