Сейчас на форуме: zds, UniSoft (+5 невидимых)

 eXeL@B —› Программирование —› Обратить функцию
Посл.ответ Сообщение


Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 02 декабря 2011 14:01 · Поправил: PE_Kill
· Личное сообщение · #1

Подскажите как обратить функцию дешифрования слова, чтобы можно было слово зашифровать:
Code:
  1. ;ax: Encrypted word
  2. ;dx: Decrypt key (word)
  3. DecryptWord       proc near
  4.                  test   ax, ax
  5.                  jbe    short buff_is_null
  6.                  test   dx, dx
  7.                  jbe    short key_is_null
  8.                  movzx  eax, ax
  9.                  movzx  edx, dx
  10.                  imul   edx
  11.                  mov    edx, eax
  12.                  and    dx, 0FFFFh
  13.                  shr    eax, 10h
  14.                  cmp    ax, dx
  15.                  setnbe cl
  16.                  and    ecx, 7Fh
  17.                  sub    dx, ax
  18.                  add    cx, dx
  19.                  mov    eax, ecx
  20.                  jmp    short locret_413D7C
  21.  
  22. key_is_null:
  23.                  mov    dx, 1
  24.                  sub    dx, ax
  25.                  mov    eax, edx
  26.                  retn
  27.  
  28. buff_is_null:
  29.                  mov    ax, 1
  30.                  sub    ax, dx
  31.  
  32. locret_413D7C:
  33.                  retn
  34. DecryptWord       endp


-----
Yann Tiersen best and do not fuck




Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 02 декабря 2011 15:33
· Личное сообщение · #2

Код какой-то странный, точно не компиляторный. Перевел на си.
Code:
  1. WORD DecryptWord(WORD data, WORD key)
  2. {
  3.          DWORD mul;
  4.  
  5.          if (data == 0) return 1-key;
  6.          if (key == 0) return 1-data;
  7.  
  8.          mul = data * key;
  9.          
  10.          return (LOWORD(mul) - HIWORD(mul)) + 
  11.                     (HIWORD(mul) >= LOWORD(mul));
  12.  
  13. }


-----
PGP key <0x1B6A24550F33E44A>


| Сообщение посчитали полезным: PE_Kill


Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 02 декабря 2011 16:33 · Поправил: PE_Kill
· Личное сообщение · #3

ntldr думаю, что код всё таки компиляторный, потому что делфи часто генерит test reg, reg/jbe при коде if (Param <= 0), даже если Param unsigned. А тут еще и древняя Delphi 3. Но за код на Си спасибо.

-----
Yann Tiersen best and do not fuck




Ранг: 51.8 (постоянный), 58thx
Активность: 0.03=0.03
Статус: Участник

Создано: 03 декабря 2011 15:51
· Личное сообщение · #4

Немного поэкспериментировал с различными значениями data и key. Думаю, что для прямого и обратного преобразований используется одна и та же функция, только с разными ключами. Если один ключ известен, то второй легко находится подбором, благо разрядность данных небольшая.
Наверняка есть формула получения одного ключа из другого, но с этим лучше к специалистам по криптографии, у меня знаний не хватило этот алгоритм опознать.




Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 03 декабря 2011 17:48 · Поправил: PE_Kill
· Личное сообщение · #5

По крипто, насколько я понимаю, ntldr шарит, но он тоже не увидел что то знакомое.

Prober пишет:
Если один ключ известен, то второй легко находится подбором

Data и Key постоянно меняются, это что то вроде RC4, где вместо
Code:
  1. ByteBuff[i]^= PRNG_GET_BYTE();

используется эта функция
Code:
  1. WordBuff[i] = DecryptWord(WordBuff[i], PRNG_GET_WORD());


Т.е. при бруте ключа шифрования скорость упадет в разы, а оно же как то шифруется, значит алгоритм дешифрования или генерации пары ключей обратим.

-----
Yann Tiersen best and do not fuck





Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 03 декабря 2011 17:59 · Поправил: reversecode
· Личное сообщение · #6

да это какая то работа с множествами аля дискретная математика

упростить до

Code:
  1.   struct {
  2.         union {
  3.             word mul[1];
  4.          };
  5.           dword mul;
  6.    };
  7.          mul = data * key;
  8.          
  9.          return (mul[0] - mul[1]) + (mul[1] >= mul[0]);


видно что первая разница и в зависимости от значений там либо +0 либо +1

да еще и вместе с
Code:
  1.          if (data == 0) return 1-key;
  2.          if (key == 0) return 1-data;


помнил бы матан помог бы)
по типу остатка отделения попадающий в диапазон



Ранг: 51.8 (постоянный), 58thx
Активность: 0.03=0.03
Статус: Участник

Создано: 03 декабря 2011 19:30
· Личное сообщение · #7

PE_Kill пишет:
Т.е. при бруте ключа шифрования скорость упадет в разы

Можно заранее пробрутить все варианты и держать наготове массив 64К вордов (индекс - прямой ключ, значение - обратный). Будет даже быстрее, чем по формуле считать (а ее еще найти надо). Кстати, несколько пар ключей, может, эти значения кого-нибудь наведут на мысль:
0000 0000
0001 0001
0002 8001
0003 5556
0004 C001
0005 6667
0006 2AAB
. . . .
FFFC 999A
FFFD 4000
FFFE AAAB
FFFF 8000




Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 03 декабря 2011 20:01
· Личное сообщение · #8

Prober пишет:
Будет даже быстрее, чем по формуле считать (а ее еще найти надо).

Это я знаю, но у меня к данной функции больше теоретический интерес, хочется всё же узнать что это.

-----
Yann Tiersen best and do not fuck




Ранг: 2.0 (гость), 1thx
Активность: 0=0
Статус: Участник

Создано: 03 декабря 2011 20:18
· Личное сообщение · #9

это умножение по модулю (2^16 +1) - используется в шифре IDEA, например

| Сообщение посчитали полезным: PE_Kill


Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 03 декабря 2011 21:32
· Личное сообщение · #10

agrep ты абсолютно прав! Это действительно IDEA, даже исходник нашел, который тут применялся:

Code:
  1.   function Mul(a,b: Word): Word;
  2.   var
  3.     p : LongWord;
  4.   begin
  5.    if (> 0) then
  6.    begin
  7.      if (> 0) then
  8.      begin
  9.        p := LongWord(a)*b;
  10.        b := p and $ffff;
  11.        a := p shr 16;
  12.        Result := ((- a) + Ord(< a));
  13.      end else Result := 1 - a;
  14.    end else Result := 1 - b;
  15.   end;


А ключи используются так:
Метод вычисления, использующийся для расшифровки текста по существу такой же, как и при его шифровании. Единственное отличие состоит в том, что для расшифровки используются другие подключи. В процессе расшифровки подключи должны использоваться в обратном порядке. Первый и четвёртый подключи i-го раунда расшифровки получаются из первого и четвёртого подключа (10-i)-го раунда шифрования мультипликативной инверсией. Для 1-го и 9-го раундов второй и третий подключи расшифровки получаются из второго и третьего подключей 9-го и 1-го раундов шифрования аддитивной инверсией. Для раундов со 2-го по 8-й второй и третий подключи расшифровки получаются из третьего и второго подключей с 8-го по 2-й раундов шифрования аддитивной инверсией. Последние два подключа i-го раунда расшифровки равны последним двум подключам (9-i)-го раунда шифрования.

-----
Yann Tiersen best and do not fuck





Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 05 декабря 2011 09:28
· Личное сообщение · #11

Посмотрел реализацию IDEA ключи действительно брутфорсятся оптимизированным алгоритмом:
Code:
  1. /*
  2.  * Compute inverse of x, modulo (2**16)+1, using Euclidean gcd algorithm
  3.  */
  4. static u_int16_t
  5. inv(u_int16_t x)
  6. {
  7.          u_int16_t t0, t1, q, y;
  8.  
  9.          if (<= 1)      /* Since zero and one are self inverse */
  10.                  return x;
  11.  
  12.          t1 = 0x10001L / x; /* Since x >= 2, the result is 16bit */
  13.          y = 0x10001L % x;
  14.          if (== 1)
  15.                  return ((1 - t1) & 0xFFFF);
  16.  
  17.          t0 = 1;
  18.          do
  19.          {
  20.                  q = x / y;
  21.                  x %= y;
  22.                  t0 += q * t1;
  23.                  if (== 1)
  24.                         return t0;
  25.                  q = y / x;
  26.                  y = y % x;
  27.                  t1 += q * t0;
  28.          } while (!= 1);
  29.  
  30.          return (1-t1);
  31. }


Спасибо всем за помощь.

-----
Yann Tiersen best and do not fuck



 eXeL@B —› Программирование —› Обратить функцию
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати