Решил ещё один крякми, в этом крякми две части, это жёстко забитый серийник и динамически генерирующийся, я пока парюсь с жёстко забитыми, т.к. кейгены пока писать не умею, но если до этого дойду, то напишу в следующий статьях:
Посмотреть вложение 52194
Решаем первое задание «HardCoded», тут немножко по сложнее, т.к. серийник сравнивается побайтно, т.е. если в прошлом крякми это делала специальная апи, то здесь автор сам написал такую программу, которая сравнивает всё побайтно в цикле…
Вообще рекомендую скачать версию олле 2.01 эта последняя версия, но там интерфейс малость поменялся, зато не будет ключить на x64, итак что-бы не разводить писанину, сразу приступим к решению:
Посмотреть вложение 52195
Находим АПИ GetWindowTextA и ставим там точку останова, именно в этой апи идёт считывание что мы введём и как следствие что идёт после этой функи будет уже обработка, проверка на правильность и т.д.
К сожаленю что-бы поставить точку останова на процедуре, в 2.01 поменялось немногу, нужно выделить нужную АПИ далее правой кнопкой и Find refences
Посмотреть вложение 52196
Далее там уже правой кнопкой и можно поставить точку останова:
Посмотреть вложение 52197
Кстати видно что функа фызывается аж три раза, причём два раза с MaxCount =32 и один MaxCount=11, кстати 11 – это и есть длинна нашего пароля… :)
В общем запускаем крякми в олле, вводим всякую дребедень, нажимаем “CheckHardxoded”, всё программа зависла по точке останова, прям на нужном нам месте, гы-гы:
Посмотреть вложение 52202
В общем-то пароль уже виден в коде, но скучно давайте анализировать дальше код:
Нажимаем F7, НО после этого незабудим:
Посмотреть вложение 52199
Далее опять F7.
Иначе олле нетуда залезет, а конкретно залезет в саму функу, нам это не нужно…
Короче нажимаем F7 и топаем по коду:
Посмотреть вложение 52200
Что-бы не делать куча скринов выделю код, который нас интересует:
Comments
CALL <JMP.&USER32.GetWindowTextA> ; \USER32.GetWindowTextA
LEA EAX,[401353] ; ASCII "HardCoded"
LEA EBX,[403215] ; ASCII "aS"
CMP BYTE PTR DS:[EAX],0
JE SHORT 0040138C
MOV CL,BYTE PTR DS:[EAX]
MOV DL,BYTE PTR DS:[EBX]
CMP CL,DL
JNE SHORT 004013D2
INC EAX
INC EBX
JMP SHORT 0040137B
Это по сути цикл, в начале в регистры заносится EAX и EBX, то-что у нас в памяти по адресам [401353] – это на кстати пароль, гы-гы, и [403215] – это то-что мы ввели, но это я думаю понятно, что происходит далее…
CMP BYTE PTR DS:[EAX],0 сравниваем, если регистр EAX=0, если да то JE SHORT 0040138C, переход на адрес 0040138C там и будет наша окошко, которое скажет что мы молодцы, гы-гы…
Если-же EAX не ноль то перехода не будет, а в специальные регистры CL и DL, заносится содержимое регистров EAX и EBX, причём если из описания, то регистр DL– это регистр данных, а CL-это счётчик, но вот заносится будут байты, а не всё значение целиком, это и есть побайтная проверка, в Олле это кстати видно хорошо (Смотреть в самом низу):
Посмотреть вложение 52203
Используется цикл Loopи обращения к индексам, как-то так:
CMP CL,DL
JNE SHORT 004013D2
Если байты CL и DL не равны, то JNE SHORT 004013D2 то переходим по адресу 004013D2, там нас обругают что-мы валенки и несмогли решить крякми…
Далее если равно, то уменьшаем регистры EAX и EBX: INC EAX, INC EBX и переходим в начало цикла JMP SHORT 0040137B и так делаем пока EAX не станет нулём ! :)