2014-12-28 1 views
1

Я хотел посмотреть, возможно ли самомодифицирующийся код в сборке, так как .text доступен только для чтения. Я думал, что могу поместить код в .data, я попробовал код ниже.Почему этот код сборки не модифицируется?

section  .text 
global  _start       ;must be declared for linker (ld) 

_start:          ;tell linker entry point 

    mov al,3 
    mov rbx,cont1        ;store label cont1 in rbx so we can continue there 
    mov cl,byte [dec_op]      ;put the opcode of the dec instruction in cl 
    mov byte [code],cl      ;replace the inc instruction with a dec instruction 
    jmp code         ;run the modified code 
cont1: 
    mov byte [dat1],al      ;store away the changed value 
    add byte [dat1],0x30      ;turn the internal numeric value into an ascii digit 
    mov eax,4         ;system call number (sys_write) 
    mov ebx,1         ;stdout 
    mov ecx,dat1        ;location of data 
    mov edx,2         ;length of data 
    int 0x80         ;call kernel 

    mov  eax,1        ;system call number (sys_exit) 
    int  0x80        ;call kernel 

section  .data 

dat1  db 0,0xa       ;location to store output 
dec_op  dec al       ;the dec instruction 
code  inc al       ;code to modify 
      jmp rbx 

Выход из выше

4 

В то время как я ожидал 2, так как после изменения себя, он должен иметь уменьшение инструкции вместо инструкции увеличения. Что я делаю не так?

Я бегу Debian Sid 64-бит, и я компиляции с:

nasm -f elf64 sm.s 
ld -s -o sm sm.o 
+0

http://en.wikipedia.org/wiki/Self-modifying_code#Interaction_of_cache_and_self-modifying_code –

+0

@HansPassant Это имеет смысл, у вас есть какие-либо ресурсы на инструкции, необходимые для синхронизации кэшей? –

+0

вы делаете самомодифицирующийся код в правильной форме, у вас есть jmp после изменения, это все, что необходимо для очистки предварительной выборки. – Jasen

ответ

4

это потому, что DEC AL занимает 2 байта

из "ListFile" производства NASM (столбцы слегка уплотненный) :

26 00000000 000A  dat1  db 0,0xa    ;location to store output 
27 00000002 FEC8  dec_op  dec al     ;the dec instruction 
28 00000004 FEC0  code  inc al     ;code to modify 
29 00000006 FFE3     jmp rbx 

Можно видеть, что первый байт обоих op-кодов идентичен, следовательно, путаница.

И это исправление.

mov cx,word [dec_op]      ;put the opcode of the dec instruction in cl 
    mov word [code],cx      ;replace the inc instruction with a dec instruction