Изменение мнемонических изменений адреса

Я новичок в GDB и сборке. Я пытаюсь изменить мнемоническую инструкцию от jg в jle, но всякий раз, когда я меняю мнемонику, он также меняет адрес назначения. Например,

Допустим, я пытаюсь изменить это:

4005a5 0f 8f 1e 01 00 00 jg 400c74 <Function_1>

Так я и сделал

$set *0x4005a5 = 0x7e

Затем происходит переключение 400c74 на произвольный адрес, например 400ae4. Я думал, что это может быть проблемой прыжка в длину и ближнего прыжка, поэтому я даже сделал = 0x0f8e= 0x74400c7e= 0x0f8e400c74 скоро.

Но они все меняют прыжок к месту.

Кто-нибудь может объяснить, почему это происходит, пожалуйста?

1 ответ

Решение

set *(unsigned short*)0x4005a5 = 0x8e0f


2 проблемы, я думаю:

  • set *0x4005a5 = 0x7e вероятно, по умолчанию используется хранилище dword, записывающее 4 байта вместо 1.
  • И вы получили неправильный код операции двумя разными способами: короткая и ближняя, а затем проблема порядка байтов для ближней.

Да, оригинальная инструкция использует кодировку Near ( jcc rel32 ), где код операции составляет 2 байта 0f 8f, Вы можете сказать, потому что полная инструкция имеет длину 6 байтов вместо 2 и начинается с 0f (так что это не однобайтовый код операции.)

Вы заменяете его 1-байтовым коротким jle rel8 поэтому второй байт кода операции становится rel8.

(Оригинал 8086 имеет только jcc rel8 для условных переходов, только с безусловными переходами типа jmp иметь кодировку rel8 и rel16; где-то между 186 и 386 jcc rel16/rel32 кодировка была добавлена.)


Ваша попытка установить 0x0f8e имеет проблему с порядком байтов. x86 имеет младший порядок, поэтому jle код операции 0F 8E как порядковый номер unsigned short имеет значение 0x8e0f ,

8E это код операции для mov Sreg, r/m16, так 0x0f8e (8E 0F) будет декодироваться как mov в сегмент reg, с 0F как байт ModR/M. Используйте GDB, чтобы разобрать инструкцию после ее изменения.

Используйте GDB disas /r разбирать с необработанным гексом, а также мнемонику.

Другие вопросы по тегам