Сейчас на форуме: YDS, _MBK_, user99 (+9 невидимых)

 eXeL@B —› Основной форум —› Сравнивать не с одним числом, а с несколькими
Посл.ответ Сообщение

Ранг: 10.2 (новичок)
Активность: 0.010
Статус: Участник

Создано: 25 января 2006 19:48 · Поправил: Skyer
· Личное сообщение · #1

Редактирую компьютерную игру(Civ2 TOT)

Там в 20 местах есть один и тот же следующий код:

<код выяснения значения eax>
cmp eax,6
jnz XXXX

XXXX - всегда разный.

Я хочу сделать так, чтобы во всех этих местах eax сравнивался не 6, а с 6 и 9. Т.е. чтобы условие выполнялось(или как в данной программе - не выполнялось) в том случае, если eax равен 6 или 9. Я так понимаю, нужно использовать для этого свободную секцию кода, куда и перенаправлять программу в эту секцию в каждом из 20 случаев. Но как в этой свободной секции сделать сравнение с двумя числами, с учётом того, что прыжки затем после сравнения идут всё время в разные части кода?




Ранг: 199.6 (ветеран), 12thx
Активность: 0.10
Статус: Участник
www.uinc.ru

Создано: 25 января 2006 20:02
· Личное сообщение · #2

в этих 20 местах сделай call на свой новый код, в нем вытащи из стэка адрес возврата и по адресу возврата узнаешь из какого места идет прыжок, а дальше по табличке вытаскивай адрес куда нужно прыгнуть если условие сошлось.



Ранг: 10.2 (новичок)
Активность: 0.010
Статус: Участник

Создано: 25 января 2006 20:03 · Поправил: Skyer
· Личное сообщение · #3

Э, можно пример на коде? А то непонятно

Прежде всего

вытащи из стэка адрес возврата
и
дальше по табличке вытаскивай адрес куда нужно прыгнуть



Ранг: 495.3 (мудрец)
Активность: 0.30
Статус: Участник

Создано: 25 января 2006 20:35
· Личное сообщение · #4

Skyer пишет:
вытащи из стэка адрес возврата

pop EAX
Skyer пишет:
дальше по табличке вытаскивай адрес куда нужно прыгнуть

jmp [EAX+table]


-----
Всем привет, я вернулся





Ранг: 199.6 (ветеран), 12thx
Активность: 0.10
Статус: Участник
www.uinc.ru

Создано: 25 января 2006 21:35
· Личное сообщение · #5

cmp eax,6
jnz XXXX
это минимум 7 байт, то что надо.
на место этого кода пишем:
call new_handler
db 0 ;; номер сравнения, в следующих будет 1, 2, и т.д.
db 2 ;; сколько байт проскипать если условие не выполнилось, если jnz короткий, то 2. если длинный - 6

ну и новый обработчик в свободном месте:
new_handler:
push ecx
mov ecx, [esp+4] ;; ecx - первый db
cmp eax, 6
jz do_ret
cmp eax, 9
jz do_ret
;; условие не выполнилось, прыгаем туда кода должен был перейти огигинальный jnz
movzx ecx, byte [ecx] ;; ecx - номер оригинального сравнения
mov ecx, dword [ecx*4 + offset jnz_table]
mov [esp+4], ecx ;; подменили адрес возврата
pop ecx
retn ;; прыгаем туда, куда вел оригинальный jnz

do_ret:
;; условие выполнилось, пропускаем оригинальный jnz
movzx ecx, byte [ecx+1] ;; сколько байт проскипать
add dword [esp+4], ecx ;; поправили адрес возврата
pop ecx
retn

jnz_table: ;; ну а тут таблица с адресами куда ведут оригинальные jnz
dd 011111111h ;; для первого сравнения
dd 022222222h ;; для второго
...
dd 0XXXXXXXXh ;; для последнего



Ранг: 33.1 (посетитель)
Активность: 0.010
Статус: Участник

Создано: 25 января 2006 23:27
· Личное сообщение · #6

В конце <кода выяснения значения eax> вставь
if (eax==9) eax=6

;)


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


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