Столкнулся с проблемой: ссылка Чтобы Crackme заработал, нужен файл key.file, размером 19 байт. Проверка содержимого этого файла на корректность производится в процедуре, находящейся по адресу 4010F6 Сама процедура: Code: @crackme0_004010F6: ;<= Procedure Start PUSH EBP MOV EBP,ESP PUSH ESI PUSH EDI XOR EAX,EAX MOV EDI,[ARG.1] MOV ESI,EDI ADD ESI,[ARG.2] JMP @crackme0_00401113 @crackme0_00401107: MOVZX ECX,BYTE PTR DS:[EDI] ADD EAX,ECX ROR EAX,8 XOR EAX,07Bh INC EDI @crackme0_00401113: CMP EDI,ESI JNZ @crackme0_00401107 POP EDI POP ESI LEAVE RETN 8 ;<= Procedure End где ARG.1 - Строка из файла ARG.2 - ее длина Делал следующее (в обратном порядке) Например, строка в файле "aaaaaaaaaaaaaaaaaaa": Для нее вычисленный хеш равен 0DECC6F7Dh 1. 0DECC6F7Dh ------> xor 7B ------>0DECC6F06h 2. 0DECC6F06h ------> ROL 8 ------> 0CC6F06DEh 3. Из числа 0CC6F06DEh нужно получить число 0CC6F067Dh : 0CC6F06DEh-61h=0CC6F067Dh (т.к. код буквы "a" равен 61h) В крэкми проверяется значение хеша, оно должно быть равным 0AAE23242h Вопрос Возможно ли отреверсить строку, или тут кроме брута ничего не сделаешь? Буду рад помощи, а то окончательно запутался, ибо брутить 19 символов - бред PS патчить НЕЛЬЗЯ
Результат 4-байтовый, т. е. в среднем на каждые ~ 4 млрд. случайных строк одна дает нужный итог. Не важно, что сами строки д. б. 19-символьные. Брут - оптимальное решение.
Брутить можно лет 300-400. Решение здесь, 2005 год: Ссылка Смысл там в том, что каждые 8 нулевых байт дают в EAX 0. Следовательно, важны только последние 4 из 19 байт
Может, и дольше, если хочешь все валидные ключи найти. А если 5-10, то достаточно нескольких минут. Вот результат ~ 20-ти минут брута, входные байты брались с ГСЧ: Code: 8A 88 2C 0F EA 3F A8 63 3E 8C 8A 1A E9 D7 5D 08 36 68 7F 99 AA 7A 0B 6F 75 95 3E 18 CA E8 60 69 4E 02 5E 53 B6 66 57 8C 08 EC A5 90 30 7F 95 E2 E3 E8 CC 6F 23 8E AE FA A1 7A 31 C5 BB 1F 2B 26 6C D6 7F DD 28 76 34 00 A6 6F 28 B2 D5 00 3F 5C BB 39 9E FD DE EC 13 98 D7 06 3E 30 19 C0 C2 83 A0 11 DD CA A8 94 75 EE A4 91 4C 11 EE 09 E5 9B CA 2A 2D 10 3C 5D 13 1F 1C E8 9F 91 2A A3 46 14 7C 4A C8 F9 6A DE FD FE B8 52 F0 58 9F ED F3 6E 15 15 CB A6 66 C6 24 C2 C7 F9 F4 BA 41 A8 0E C6 87 C2 85 24 9A 52 F0 50 C0 B7 B5 B9 65 07 F9 F4 FC 25 9C 1D EC 6A 3F 9D 7F C0 CF E4 88 9A Твое решение 2005 года имеет 1 недостаток: надо досконально анализировать логику кода. Иногда без этого не обойтись, но в данном случае перебор 4 млрд. комбинаций и проще, и быстрее.
головой побрутьте хоть немного) вот хешфункция Code: // // decompiled to sourcecode level // DWORD __stdcall get_hash(LPBYTE pBuffer, DWORD dwLen) // keydata, 19 bytes length { DWORD rc; LPBYTE i; DWORD tmp; rc = 0; for ( i = pBuffer; i != &pBuffer[dwLen]; i++ ) { tmp = ROR((DWORD)*i + rc, 8); rc = tmp ^ 0x7B; } return rc; // == 0xAAE23242, well known } xor арифметику вспомните, нуже нуже ))