Я занимался реверс-инжинирингом 32- и 64-битной версии Windows Mathematica 10.4 для Windows, и вот что я нашел:
32 BIT
Используется Хеш-функция Фаулера-Нолла-Во (FNV-1, с умножением до) с 16777619 в качестве простого числа FNV и 84696351 в качестве смещения.Эта функция применяется к Murmur3-32 хэшированным значениям адреса данных выражения (MMA использует указатель для сохранения одного экземпляра каждого из данных).Адрес в конечном итоге преобразуется в значение - для простых целых чисел машины значение является немедленным, для других - немного хитрее.Реализующая функция Murmur3-32 фактически содержит дополнительный параметр (по умолчанию 4, особый случай, ведущий себя как в Википедии), который выбирает, сколько битов выбрать из структуры выражения во входных данных.Поскольку нормальное выражение внутренне представлено в виде массива указателей, можно взять первый, второй и т. Д. Путем многократного добавления 4 (байт = 32 бита) к базовому указателю выражения.Таким образом, передача 8 в функцию даст второй указатель, 12 третий и так далее.Поскольку внутренние структуры (большие целые числа, целые числа машин, вещественные числа, большие числа и т. Д.) Имеют разные переменные-члены (например, целое число машины имеет только указатель на int, сложные 2 указателя на числа и т. Д.), Для каждой структуры выраженияесть «обертка», которая объединяет свои внутренние члены в один 32-битный хэш (в основном с раундами FNV-1).Самым простым выражением для хэша является целое число.
Функция murmur3_32()
имеет начальное значение 1131470165, n = 0 и другие параметры, как в Википедии.
Итак, мы имеем:
hash_of_number = 16777619 * (84696351 ^ murmur3_32( &number ))
со значением «^»XOR.Я действительно не пробовал - указатели кодируются с использованием WINAPI EncodePointer()
, поэтому они не могут быть использованы во время выполнения.(Может быть, стоит запустить в Linux под Wine с измененной версией EncodePonter
?)
64 BIT
Используется 64-битный FNV-1хеш-функция с 0xAF63BD4C8601B7DF в качестве основы смещения и 0x100000001B3 в качестве простого FNV, вместе с хешем SIP64-24 ( здесь '- ссылочный код) с первым 64-битным битом 0x0AE3F68FE7126BBF76F0214 как BFF76F021F7последние 64 бита как k1.Функция применяется к базовому указателю выражения и разрешается внутри.Как и в 32-битном murmur3, есть дополнительный параметр (по умолчанию 8) для выбора количества указателей для выбора из структуры входного выражения.Для каждого типа выражения есть оболочка для конденсации членов структуры в один хеш с помощью 64-битных циклов FNV-1.
Для целого числа машины у нас есть:
hash_number_64bit = 0x100000001B3 * (0xAF63BD4C8601B7DF ^ SIP64_24( &number ))
Опять же, я действительно не пробовал.Кто-нибудь может попробовать?
Не для слабонервных
Если вы посмотрите на их заметки о внутренней реализации , онискажем, что «Каждое выражение содержит особую форму хеш-кода, которая используется как при сопоставлении с образцом, так и при оценке».
Хеш-код, на который они ссылаются, это тот, который генерируется этими функциями - в какой-то момент вВ функции-обертке нормального выражения есть присваивание, которое помещает вычисленный хеш в саму структуру выражения.
Было бы здорово понять, КАК они могут использовать эти хеши для сопоставления с образцом.Поэтому я попытался запустить оболочку bigInteger, чтобы посмотреть, что произойдет - это простейшее составное выражение.Он начинает проверять что-то, что возвращает 1 - не знаю, что.Таким образом, он выполняет
var1 = 16777619 * (67918732 ^ hashMachineInteger(1));
с помощью hashMachineInteger (), о чем мы говорили ранее, включая значения.
Затем он считывает длину в байтах bigInt из структуры (bignum_length
) изапуски
result = 16777619 * (v10 ^ murmur3_32(v6, 4 * v4));
Обратите внимание, что murmur3_32()
вызывается, если 4 * bignum_length
больше 8 (может быть связано с максимальным значением целых чисел машины $MaxMachineNumber
2^32^32
и, наоборот, с значением bigIntдолжен быть).
Итак, окончательный код:
if (bignum_length > 8){
result = 16777619 * (16777619 * (67918732 ^ ( 16777619 * (84696351 ^ murmur3_32( 1, 4 )))) ^ murmur3_32( &bignum, 4 * bignum_length ));
}
I 'Мы сделали несколько предположений о свойствах этой конструкции.Наличие множества XOR и тот факт, что 16777619 + 67918732 = 84696351
может заставить задуматься о том, что какая-то циклическая структура используется для проверки шаблонов - то есть вычитание смещения и деление на простое число, или что-то в этом роде.Программное обеспечение Cassandra использует алгоритм хеширования Murmur для генерации токенов - см. эти изображения , что я имею в виду под «циклической структурой».Может быть, для каждого выражения используются разные простые числа - все равно нужно проверить.
Надеюсь, это поможет