Добавлен BaHeK,
опубликован
Некоторое время назад задавали вопрос и я рекомендовал использовать функцию StringHash для сокрытия строковых констант(ника или пароля). И я решил проверить возможно ли подобрать строку, хеш которой равен наперед заданному числу.
Думал с чего бы начать и решил неплохо бы узнать алгоритм функции. Нашел я его быстро в Strom.dll по адресу 0x15034874, и перевёл на Python.
Думал с чего бы начать и решил неплохо бы узнать алгоритм функции. Нашел я его быстро в Strom.dll по адресу 0x15034874, и перевёл на Python.
def StringHash(s):
if s == "":
return 0
s = [i for i in s.encode("utf-8")]
for i in range(len(s)):
if 97 <= s[i] <= 122:
s[i] -= 32
elif s[i] == 47:
s[i] = 92
l = len(s)
a = 0
b = c = 0x9e3779b9
p = [0, 8, 16, 24, 0, 8, 16, 24, 8, 16, 24]
r = [-13, 8, -13, -12, 16, -5, -3, 10, -15]
while len(s) >= 12:
a += int.from_bytes(s[8:12], "little")
b += int.from_bytes(s[4:8], "little")
c += int.from_bytes(s[:4], "little")
for i in r:
a, b, c = (c - b - a) ^ (a << i if i > 0 else (a & 0xFFFFFFFF) >> -i), a, b & 0xFFFFFFFF
s = s[12:]
d = [c, b, a + l]
for i in range(len(s)):
d[i // 4] += s[i] << p[i]
c, b, a = d
for i in r:
a, b, c = (c - b - a) ^ (a << i if i > 0 else (a & 0xFFFFFFFF) >> -i), a, b & 0xFFFFFFFF
return (lambda e: e - (1 << 32) * (e >> 31))(a & 0xFFFFFFFF)
Как мы видим строка делится на части по 12 байт, а те в свою очередь на 3 части по 4. То есть чтобы восстановить строку нам нужно произвести вычисления в обратном порядке. Значение переменной a у на есть, осталось узнать значения b и c. Для это воспользуемся методом перебора, который я реализовал в функции.
def hash_breaker(h):
for b in range(100):
for c in range(100):
a = h
for i in [-15, 10, -3, -5, 16, -12, -13, 8, -13]:
a, b, c = b, c, ((a ^ (b << i if i > 0 else (b & 0xFFFFFFFF) >> -i)) + b + c) & 0xFFFFFFFF
l = a & 0xFF
if l != 11:
continue
a1 = ((a - l) >> 8 & 0xFFFFFFFF).to_bytes(3, "little")
b1 = ((b - 0x9e3779b9) & 0xFFFFFFFF).to_bytes(4, "little")
c1 = ((c - 0x9e3779b9) & 0xFFFFFFFF).to_bytes(4, "little")
s = c1 + b1 + a1
ex = False
for i in s:
if 97 <= i <= 122 or i == 47 or i == 0:
ex = True
break
if ex:
continue
return s
По сути подойдёт даже первая попавшая строка, главное, чтобы не было маленьких английских буквы (символы с кодами от 97 до 122 включительно), слэша(/) и нуля(\0), т.к. все строки null-terminated. В 12 байте хранится длина строки, во избежания лишних проверок я сделал её 11. В итоге эта функции возвращает искомую нами строку.
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
Inori
8 месяцев назад
0
"I can use the StringHash function instead of the hash_breaker function. Could you provide an example of the hash_breaker function? I hope someone can assist me."
Чтобы оставить комментарий, пожалуйста, войдите на сайт.