-
Автор темы
- #1
Решал крекмис и напоролся на то ли баг, то ли что, сам не знаю... Сижу уже 3-й день над одной строчкой...
В общем в ассемблерном коде четко сказано:
В общем все вроде бы логично и просто, я набросал за пару часиков функу на плюсах и пошел тестить... Но нет, алгоритм оказался не правильный и результат был абсолютно далек, от оригинала. Я просидел целый день и сдался, воспользовавшись псевдо кодом, отличий я не заметил, но переписал его в генераторе и проверил...
Ага, елда там плавал.. В общем опять не то генерит, я пошел гуглить CRC, нашел, запускаю, а он работает...
Вопрос такой, как так получается, что XOR в оригинале происходит при каждой итерации цикла "j", а в IDA отображается как выполняющийся однажды в цикле "i" перед циклом "j"? Где ошибка в псевдо коде?
В общем в ассемблерном коде четко сказано:
- Помещаем в EAX символ строки
- Перемещаем EAX в буферную переменную
- Записываем в EAX значение CRC
- Делаем EAX ^= буферная переменная (char)
Ассемблерный листинг:
mov eax, [ebp+name]
add eax, [ebp+i] ; name[i]
movsx ecx, byte ptr [eax]
mov [ebp+var_buff], ecx
mov eax, [ebp+crc]
xor eax, [ebp+var_buff]
mov [ebp+crc], eax
mov [ebp+j], 7
jmp short loc_438070
Псевдо код:
unsigned int __cdecl genNameHash(char *name)
{
unsigned int crc; // [esp+DCh] [ebp-2Ch]
int j; // [esp+F4h] [ebp-14h]
int i; // [esp+100h] [ebp-8h]
i = 0;
crc = -1;
while ( name[i] )
{
crc ^= name[i];
for ( j = 7; j >= 0; --j )
crc = -(crc & 1) & 0xEDB88320 ^ (crc >> 1);
++i;
}
return ~crc;
}
Оригинальный код на С++:
int32_t crc32(const char* s, size_t n) {
uint32_t crc = 0xFFFFFFFF;
for (size_t i = 0; i < n; i++)
{
char ch = s[i];
for (size_t j = 0; j < 8; j++)
{
uint32_t b = (ch ^ crc) & 1;
crc >>= 1;
if (b) crc = crc ^ 0xEDB88320;
ch >>= 1;
}
}
return ~crc;
}
Вопрос такой, как так получается, что XOR в оригинале происходит при каждой итерации цикла "j", а в IDA отображается как выполняющийся однажды в цикле "i" перед циклом "j"? Где ошибка в псевдо коде?
Последнее редактирование: