2015-04-23 4 views
1

Я столкнулся с довольно интересным article, который продемонстрировал, как удалить символы нулевого символа из shellcode. Среди используемых методик, инструкции по сборке shl и shr, казалось, занимали довольно важную роль в коде.Что сменяет инструкция по монтажу?

Я понимаю, что инструкции по сборке mov $0x3b, %rax и mov $59, %rax фактически генерируют инструкции машинного кода 48 c7 c0 3b 00 00 00. Чтобы справиться с этим, автор вместо этого использует mov $0x1111113b, %rax, чтобы заполнить регистр системным номером системы, который генерирует вместо этого машинный код 48 c7 c0 3b 11 11 11, который успешно удаляет нулевые байты.

К сожалению, код по-прежнему не выполняется, поскольку syscall обрабатывает 3b 11 11 11 как незаконную инструкцию, или это приводит к сбою кода. Так что автор тогда сделал сдвиг %rax назад и вперед 56 байт с командами

shl $0x38, %rax 
shr $0x38, %rax 

После этого сдвига, код выполняет отлично. Что я хочу знать, так это то, как инструкции по переносу исправляют проблему 48 c7 c0 3b 11 11 11, и как-то делает собственно и syscall'able. Я знаю, что shl/shr сдвигает биты влево и вправо, что означает, что сдвиг влево перемещает биты в более высокие биты, а смещение вправо заставляет их снова опускаться, потому что двоичный код читается справа налево. Но как это вообще меняет код и делает его исполняемым? Не перемещается ли взад и вперед по существу ничего не меняет, переставляя сдвинутые биты точно туда, где они были в начале?

Моя единственная теория заключается в том, что смещение битов оставляет за собой нули. Но я до сих пор не вижу, как смещение %rax вперед, а затем назад исправляет решение, потому что не приведет ли он обратно в раздел 11 11 11?

В любом случае, я думал, что это было интересно, поскольку я до сих пор не видел сдвиговых операндов. Заранее спасибо.

ответ

1

Смещение - операция с потерями - если биты сдвинуты за пределы регистра, они просто исчезают. (Иногда один из них хранится в флагом переноса, но это не важно здесь.) См. http://en.wikibooks.org/wiki/X86_Assembly/Shift_and_Rotate#Logical_Shift_Instructions.

Сдвиг влево (З) операция делает это:

< < 0x000000001111113b 0x38 = 0x3b00000000000000

0x111111 часть занял бы немного 64, 65, 66 и т.д., но% Rax является 64- бит, поэтому эти биты исчезают. Затем, логический сдвиг вправо (SHR) операция делает это:

0x3b00000000000000 >> 0x38 = 0x000000000000003b

Давать вам номер, который вы хотите. И это все, что нужно.

Смежные вопросы