Изменение мнемонических изменений адреса
Я новичок в 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
разбирать с необработанным гексом, а также мнемонику.