Как обычно, программа исключительно для ознакомления и использование на свой страх и риск, к стати по этому алгоритм намеренно замедлен, но ускорить его не проблема, выкинув некоторое количество кода. Естественно алгоритм и код можно улучшить, так что на истину в последней инстанции не претендую.
В принципе в программе ничего сложного нет, алгоритм SHA-1 я расписывал раньше. Это тупо обертка на алгоритм со свистелочками и перделочками.
Единственное, что в нем наверно интересно, это алгоритм перебора, который я и опишу:
Состоит из двух процессов, первый это верхний уровень рекурскии.
Второй это собственно сам алгоритм рекурсии.
Итак, процесс верхнего уровня рекурсии:
topLVL proc uses eax ebx ecx edx esi edi countSym:DWORD, pBrutaddr:DWORD lea esi, tempdict ; в esi - адрес временно словаря mov edi, pBrutaddr ; в edi - адрес массива со ссылками на позиции в словаре xor ecx, ecx ; нулим ecx mov DWORD PTR [edi], esi ; копируем ссылку на нулевую позицию в словаре @@: invoke compileString, offset string, offset pBrut ; вычисляем строчку invoke CalcKey, offset string ; вычисляем SHA-1 хэш invoke CheckSHA, offset sha1H0, offset tmpH0 ; сравниваем хэши inc DWORD PTR [edi] ; сдвигаем словарь на 1 позицию inc ecx ; увеличиваем ecx .if ecx == countSym ; сравниваем счетчик с количеством позиций в словаре jmp @f ; если достигли конца словаря - прыгаем на выход .endif jmp @b ; двигаем на следующую позицию @@: lea esi, dict ; возвращаем ссылку на словарь ret topLVL endp
А теперь основное тело алгоритма перебора:
Permute proc uses ebx ecx edx esi edi countSym:DWORD, recur:DWORD, pBrutaddr:DWORD lea esi, tempdict ; в esi ссылка на временный словарь mov edi, pBrutaddr ; в edi адрес на массив сылок на словарь .if recur == 0 ; если рекурсия равна нулю, выполняем этот иф invoke topLVL, countSym, pBrutaddr ; выполняем процесс верхнего уровня рекурсии mov eax, recur ; в eax помещаем текущую глубину рекурсии inc eax ; увеличиваем на 1 mov ebx, pBrutaddr ; в ebx кладем текущий адрес на позицию в массиве add ebx, 4h ; увеличиваем его на 4 invoke Permute, countSym, eax, ebx ; вызываем рекурсию с параметрами выше mov DWORD PTR [edi], esi ; копируем в текущую рекурсию нулевую позицию массива jmp exitTopLvl ; прыгаем на выход .endif mov eax, esi ; в eax копируем esi add eax, countSym ; прибавляем количество символов в словрае, чтобы знать где окончание перебора .if DWORD PTR [edi-4h] == eax && DWORD PTR [edi] == 0 ; если предущая ссылка достигла окончания массива и текущая равна нулю mov DWORD PTR [edi], esi ; делаем вывод, что нужно создать следующий уровень рекурсии .elseif .if DWORD PTR [edi] == eax ; если текущая ссылка стала равна указателю на окончание массива mov eax, recur ; в eax помещаем текущую глубину рекурсии inc eax ; увеличиваем на 1 mov ebx, pBrutaddr ; в ebx кладем текущий адрес на позицию в массиве add ebx, 4h ; увеличиваем его на 4 invoke Permute, countSym, eax, ebx ; вызываем рекурсию с параметрами выше mov DWORD PTR [edi], esi ; копируем в текущую рекурсию нулевую позицию массива .elseif ; если еще не достигли окончания массива inc DWORD PTR [edi] ; увеличиваем на 1 текущий указатель на позицию массива .endif .endif exitTopLvl: mov eax, countSym ; в eax копируем количество элементов в массиве словаря dec eax ; уменьшаем eax на 1 .if recur > eax ; если глубина рекурсии стала больше чем количество элементов в массиве словаря mov recKey, -1h ; в recKey копируем -1, как флаг окончания перебора .endif ret Permute endp
Ну вот в принципе и все на сегодня, как обычно код можно найти на pastebin
И искходники с программой целиком на депозитфилес.
bearchik, а есть вообще возможность работать с видеокартой на асме? Слышал про CUDA, OpenCL, но хочется все таки низкоуровневого...
ОтветитьУдалитьНу на асме можно работать с чем угодно, был бы компилятор и возможность подлезть каким то образом.
ОтветитьУдалитьНо для начала необходимо получить даташыты и спеки того проца подо что пишешь, так как например в видяхах явно стоит не х86 процы и соответственно большинство команд от x86 не подойдут. У меня руки просто не доходят позаниматься видяшными GPU, народ весь как раз пишет для Nvidia на CUDA, а для AMD(ATI) на OpenCL, но они все используют готовые фреймворки на C++. Надо качнуть какойнить фреймворк да посмотреть, что там полезного можно нарыть.