Что произойдет, если система выполнит часть файла с нулями?

Я видел в некоторых сообщениях / видео / файлах, что они заполнены нулями, чтобы выглядеть больше, чем они, или соответствуют критериям "того же размера файла", которые некоторые утилиты файловой системы имеют для перемещения файлов, в основном это либо программы-шутки, либо вредоносные программы.,

Но я часто задавался вопросом, что произойдет, если файл будет поврежден и "загрузит" следующий набор "инструкций", которые находятся в большом заполненном нулями месте в конце файла?

Что-нибудь случится? Для чего нужна инструкция 0x0?

1 ответ

Решение

Расшифровка 0 байт полностью зависит от архитектуры процессора. На многих архитектурах инструкции имеют фиксированную длину (например, 32-разрядную), поэтому важная вещь 00 00 00 00 (с использованием шестнадцатеричной записи).

В большинстве дистрибутивов Linux clang/llvm поставляется со встроенной поддержкой нескольких целевых архитектур (clang -target а также llvm-objdump), в отличие от gcc / gas / binutils, поэтому я смог использовать это для проверки некоторых архитектур, для которых не установлен cross-gcc / binutils. использование llvm-objdump --version чтобы увидеть список поддерживаемых. (Но я не понял, как заставить его разбирать сырой двоичный файл, такой как binutils objdump -b binary, и мой Clang не будет создавать двоичные файлы SPARC самостоятельно.)


На х86, 00 00 (2 байта) декодирует ( http://ref.x86asm.net/coder32.html) как 8-битный add с назначением памяти. Первый байт - это код операции, 2-й байт - это ModR/M, который определяет операнды.

Это обычно segfaults сразу (если eax/rax не является допустимым указателем), или segfaults, когда выполнение падает с конца части с нулевым заполнением на не отображенную страницу. (Это происходит в реальной жизни из-за ошибок, таких как падение с конца _start без выполнения системного вызова exit), хотя в этих случаях следующие байты не всегда равны нулю. например, данные или метаданные ELF.)


64-битный режим x86: ndisasm -b64 /dev/zero | head:

address   machine code      disassembly
00000000  0000              add [rax],al

32-разрядный режим x86 (-b32):

00000000  0000              add [eax],al

16-битный режим x86:(-b16):

00000000  0000              add [bx+si],al

Режим ARrch32 ARM: cd /tmp && dd if=/dev/zero of=zero bs=16 count=1 && arm-none-eabi-objdump -z -D -b binary -marm zero, (Без -z, objdump пропускает большие блоки из нуля и показывает ...)

addr   machine code   disassembly
0:   00000000        andeq   r0, r0, r0

ARM Thumb / Thumb2: arm-none-eabi-objdump -z -D -b binary -marm --disassembler-options=force-thumb zero

0:   0000            movs    r0, r0
2:   0000            movs    r0, r0

AArch64: aarch64-linux-gnu-objdump -z -D -b binary -maarch64 zero

 0:   00000000        .inst   0x00000000 ; undefined

MIPS32: echo .long 0 > zero.S && clang -c -target mips zero.S && llvm-objdump -d zero.o

zero.o: file format ELF32-mips
Disassembly of section .text:
   0:       00 00 00 00     nop

PowerPC 32 и 64-битный: -target powerpc а также -target powerpc64, IDK, если какие-либо расширения PowerPC используют 00 00 00 00 кодирование команд для чего-либо, или, если это все еще недопустимая инструкция для современных чипов IBM POWER.

zero.o: file format ELF32-ppc   (or ELF64-ppc64)
Disassembly of section .text:
   0:       00 00 00 00  <unknown>

IBM S390: clang -c -target systemz zero.S

zero.o: file format ELF64-s390
Disassembly of section .text:
   0:       00 00  <unknown>
   2:       00 00  <unknown>
Другие вопросы по тегам