Я пытался следовать этому руководству (https://paraschetal.in/writing-your-own-shellcode) о том, как написать собственный шеллкод. На 99% это имеет для меня смысл, но у меня есть только два непрекращающихся сомнения - это относится к написанию шеллкода в целом.
Во-первых, я думаю, что понимаю, почему мы хотим избежать нулевого байта, но как использование следующего позволяет избежать нулевых байтов?
xor eax, eax
Разве eax
теперь не содержит точно нулевые байты? Или он содержит 0s? Когда мы выполняем операцию XOR с самим собой, она возвращает False, верно?
Во-вторых, в инструкции сказано:
Наконец, мы загрузим номер системного вызова (11 или 0xb) в регистр eax. Однако, если мы используем eax в нашей инструкции, результирующий шеллкод будет содержать несколько байтов NULL(\x00), а нам это не нужно. Наш регистр eax уже имеет значение NULL. Поэтому мы просто загрузим номер системного вызова в регистр al вместо всего регистра eax.
mov byte al, 0x0b
Теперь я понимаю, что здесь происходит, число 11 (для execve
) загружается в первые 8 бит регистра eax
(то есть al
). Но остальная часть eax
по-прежнему содержит нулевые байты, так что же именно здесь достигается?
Обратите внимание, я пришел сюда в крайнем случае, проведя большую часть дня, пытаясь понять это, поэтому, пожалуйста, будьте со мной полегче :)
mov eax, 0
, в полезной нагрузке будет ноль.xor eax, eax
имеет машинный код, который не включает нулевой байт, но во время выполнения он создаст ноль по мере необходимости. Просто создайте полезную нагрузку для двух версий и наблюдайте за нулевыми байтами. - person Jester   schedule 29.12.2018