Что произойдет, если система выполнит часть файла с добавлением нуля? - PullRequest
0 голосов
/ 03 мая 2018

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

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

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

1 Ответ

0 голосов
/ 03 мая 2018

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

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


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

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


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

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

x86 32-битный режим (-b32):

00000000  0000              add [eax],al

x86 16-битный режим: (-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>
...