Почему между операторами jmp может быть ассемблерный код? - PullRequest
1 голос
/ 04 августа 2020

Иногда я вижу код, который никогда не должен быть достигнут из-за оператора jmp.

пример:

0004036F call program.48391
00040374 jmp program.40440
00040376 lea rdx,qword ptr ds:[stringaddress]
....
....
.... //code that does something else
....
....
00040440 mov ebx,0

Что здесь происходит, почему здесь код и как он вообще достигли?

1 Ответ

3 голосов
/ 05 августа 2020

Мой x86 супер ржавый, но, будучи набором инструкций переменной длины, его очень сложно дизассемблировать, и следует ожидать, что некоторый процент вывода дизассемблера будет (полностью) неверным навсегда или в течение определенного периода времени (количество инструкций в линейном порядке). Единственный правильный способ дизассемблирования - это делать это в порядке выполнения, а не в линейном порядке памяти, но тогда это оставит пробелы в том, что может быть настоящим кодом. В любом случае, если мой код не содержит ошибок функционально, он все равно демонстрирует, как можно использовать прыжок.

mov 0x4,%eax
jmp over
under:
  dec %eax
over:
  test %eax,%eax
  jne under

Disassembly of section .text:

0000000000000000 <.text>:
   0:   8b 04 25 04 00 00 00    mov    0x4,%eax
   7:   eb 02                   jmp    0xb
   9:   ff c8                   dec    %eax
   b:   85 c0                   test   %eax,%eax
   d:   75 fa                   jne    0x9

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

mov 0x4,%eax
jmp over
.byte 0x22
under:
  dec %eax
over:
  test %eax,%eax
  jne under

0000000000000000 <.text>:
   0:   8b 04 25 04 00 00 00    mov    0x4,%eax
   7:   eb 03                   jmp    0xc
   9:   22 ff                   and    %bh,%bh
   b:   c8 85 c0 75             enterq $0xc085,$0x75
   f:   fa                      cli 

Нет даже точки приземления для 0xc; поскольку они показали мне однобайтовую инструкцию, я просто воспользуюсь этим: дизассемблер был испорчен, потому что он дизассемблировал в порядке памяти, а не в порядке выполнения, чрезвычайно распространенный подход дизассемблера (с частично допустимыми причинами). оставьте себе хлебные крошки за пределами машинного кода в двоичном коде, чтобы сделать это немного более успешным, но вы все равно можете запутать дизассемблер, если вложите в него больше работы (я прекратил попытки с таким простым примером).

Похоже, они используют метки для сброса дизассемблера.

mov 0x4,%eax
jmp over
.byte 0x22
/*under:*/
  dec %eax
over:
  test %eax,%eax
  .byte 0x75,0xFA /* jne under*/

0000000000000000 <over-0xc>:
   0:   8b 04 25 04 00 00 00    mov    0x4,%eax
   7:   eb 03                   jmp    c <over>
   9:   22 ff                   and    %bh,%bh
   b:   c8                      .byte 0xc8

000000000000000c <over>:
   c:   85 c0                   test   %eax,%eax
   e:   75 fa                   jne    a <over-0x2>

В любом случае, надеюсь, комментарий Маргарет имеет больше смысла.

...