Сейчас на форуме: 2nd, morgot, Rio, CDK123, zds, tyns777, tihiy_grom (+4 невидимых)

 eXeL@B —› Программирование —› Помогите понять код
Посл.ответ Сообщение


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

Создано: 21 марта 2009 14:52
· Личное сообщение · #1

Привет всем! Сто лет не был тут, рад присоединиться вновь!
Возник вопрос, пытаюсь понять, что делает функция приведённая ниже. Как я понял это что-то включаемое компилятором и этот код встречается в более чем сотне файлов из system32. Как мне показалось, функция выделяет остаток дробного числа после точки. Хотелось бы узнать точно.
Привожу то, что нашёл в гугле:

Code:
  1. SUB_1EB0:
  2.         PUSH    EBP
  3.         MOV     EBP, ESP
  4.         SUB     ESP, 20
  5.         AND     ESP, FFFFFFF0
  6.         FLD     ST
  7.         FST     DWORD PTR SS:[ESP+18]
  8.         FISTP   QWORD PTR SS:[ESP+10]
  9.         FILD    QWORD PTR SS:[ESP+10]
  10.         MOV     EDX, DWORD PTR SS:[ESP+18]
  11.         MOV     EAX, DWORD PTR SS:[ESP+10]
  12.         TEST    EAX, EAX
  13.         JE      SHORT STEP1F0F
  14. STEP1ED3:
  15.         FSUBP   ST(1), ST
  16.         TEST    EDX, EDX
  17.         JNS     SHORT STEP1EF7
  18.         FSTP    DWORD PTR SS:[ESP]
  19.         MOV     ECX, DWORD PTR SS:[ESP]
  20.         XOR     ECX, 80000000
  21.         ADD     ECX, 7FFFFFFF
  22.         ADC     EAX, 0
  23.         MOV     EDX, DWORD PTR SS:[ESP+14]
  24.         ADC     EDX, 0
  25.         JMP     SHORT STEP1F23
  26. STEP1EF7:
  27.         FSTP    DWORD PTR SS:[ESP]
  28.         MOV     ECX, DWORD PTR SS:[ESP]
  29.         ADD     ECX, 7FFFFFFF
  30.         SBB     EAX, 0
  31.         MOV     EDX, DWORD PTR SS:[ESP+14]
  32.         SBB     EDX, 0
  33.         JMP     SHORT STEP1F23
  34. STEP1F0F:
  35.         MOV     EDX, DWORD PTR SS:[ESP+14]
  36.         TEST    EDX, 7FFFFFFF
  37.         JNZ     SHORT STEP1ED3
  38.         FSTP    DWORD PTR SS:[ESP+18]
  39.         FSTP    DWORD PTR SS:[ESP+18]
  40. STEP1F23:
  41.         LEAVE
  42.         RETN


А вот как это представлено а страничке где нарыл код как у меня:

Code:
  1.          static void SUB_1EB0() {
  2.                  fpu.FLD_ST(0);
  3.                  float esp18 = fpu.FST_m32fp();
  4.                  long esp10 = fpu.FISTP_m64int();
  5.                  fpu.FILD_m64int(esp10);
  6.                  edx = Float.floatToRawIntBits(esp18);
  7.                  eax = (int)(esp10 & 0x00000000ffffffffL);
  8.                  if (eax == 0) {
  9.                         edx = (int)(esp10 >>> 32);
  10.                         if ((edx & 0x7fffffff) == 0) {
  11.                               fpu.FSTP_m32fp();
  12.                               fpu.FSTP_m32fp();
  13.                               return;
  14.                         }
  15.                  }
  16.                  fpu.FSUBP_ST_ST0(1);
  17.                  if (edx < 0) {
  18.                         int ecx = Float.floatToRawIntBits(fpu.FSTP_m32fp());
  19.                         long lecx = (long)ecx & 0x00000000ffffffffL;
  20.                         lecx ^= 0x0000000080000000L;
  21.                         lecx += 0x000000007fffffffL;
  22.                         boolean carryFlag = (lecx & 0xffffffff00000000L) != 0L;
  23.                         ecx = (int)(lecx & 0x00000000ffffffffL);
  24.                         long leax = (long)eax & 0x00000000ffffffffL;
  25.                         leax += carryFlag ? 1 : 0;
  26.                         carryFlag = (leax & 0xffffffff00000000L) != 0L;
  27.                         eax = (int)(leax & 0x00000000ffffffffL);
  28.                         edx = (int)(esp10 >>> 32);
  29.                         edx += carryFlag ? 1 : 0;
  30.                  } else {
  31.                         int ecx = Float.floatToRawIntBits(fpu.FSTP_m32fp());
  32.                         long lecx = (long)ecx & 0x00000000ffffffffL;
  33.                         lecx += 0x000000007fffffffL;
  34.                         boolean carryFlag = (lecx & 0xffffffff00000000L) != 0L;
  35.                         ecx = (int)(lecx & 0x00000000ffffffffL);
  36.                         long leax = (long)eax & 0x00000000ffffffffL;
  37.                         leax -= carryFlag ? 1 : 0;
  38.                         carryFlag = (leax & 0xffffffff00000000L) != 0L;
  39.                         eax = (int)(leax & 0x00000000ffffffffL);
  40.                         edx = (int)(esp10 >>> 32);
  41.                         edx -= carryFlag ? 1 : 0;
  42.                  }
  43.          }
  44. }


Источник на японском http://beu.sakura.ne.jp/mt-blog/2008/11/post-101.html




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 21 марта 2009 16:53
· Личное сообщение · #2

У меня, помнится, тоже была проблема по разбору кода математического сопроцессора, все эти fstp, fild, fld и прочее, а главное, преобразования с дробными числами в голове держать достаточно напряжно (ИМХО), а олька 1.10 числа с плавающей точкой неправильно декодирует, но вот вторая олька с этим справляется на ура, поэтому отличный выход - это компильнуть непонятные тебе инструкции под МАСМ, например, а потом под второй олькой смотреть, что с этими дробными числами происходит.

-----
Stuck to the plan, always think that we would stand up, never ran.





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

Создано: 21 марта 2009 16:56 · Поправил: ToBad
· Личное сообщение · #3

IDA показала, что это функция ftol2.
Поиск в гугле выдал: Функция __ftol2 предназначена для преобразования float -> int
Проверяю пока эту информацию. Если кто знает подробности работы этого преобразования - буду благодарен. Имею ввиду, после запятой выкидывается вообще, либо округляется или как?




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

Создано: 21 марта 2009 17:23
· Личное сообщение · #4

Всё, разобрался. Это преобразование числа из st0 в dword со знаком. Округление не происходит, только откидывается дробь.
ARCHANGEL - Спасибо за участие!


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


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