El código de auto modificación siempre falla en la segmentación en Linux
Encontré un artículo sobre el código auto modificable e intenté hacer algunos ejemplos, pero siempre tengo fallas de segmentación. Tan rápido como puedo entender, hay una violación en los permisos de memoria. El segmento de código es (r) ead / e (x) ecute y, por lo tanto, el intento de escribir los resultados de esta falla. ¿Hay alguna forma de probar el programa cambiando los permisos de memoria en tiempo de ejecución o antes? Estoy usando Linux y el ejemplo está escrito en el ensamblaje GAS.
.extern memcpy
.section .data
string:
.asciz "whatever"
string_end:
.section .bss
.lcomm buf, string_end-string
.section .text
.globl main
main:
call changer
mov $string, %edx
label:
push string_end-string
push $buf
push $string
call memcpy
changer:
mov $offset_to_write, %esi
mov $label, %edi
mov $0xb, %ecx
loop1:
lodsb
stosb
loop loop1
ret
offset_to_write:
push 0
call exit
end:
así que después de la modificación sugerida por osgx, aquí hay un código que funciona. (En realidad, si ensamblas, enlazas y ejecutas, se bloquea, pero si ves usando gdb, ¡modifica su código!)
.extern memcpy
.section .data
string:
.asciz "Giorgos"
string_end:
.section .bss
.lcomm buf, string_end-string
.section .text
.globl main
main:
lea (main), %esi # get the start of memory region to
# change its permissions (smc-enabled)
andl $0xFFFFF000, %esi # align to start of a pagesize
pushl $7 # permissions==r|w|x
pushl $4096 # page size
pushl %esi # computed start address
call mprotect
call changer # function that does smc
mov $string, %edx
label:
push string_end-string # this code will be overridden
push $buf # and never be executed!
push $string
call memcpy
changer:
mov $offset_to_write, %esi # simple copy bytes algorithm
mov $label, %edi
mov $0xb, %ecx
loop1:
lodsb
stosb
loop loop1
ret
offset_to_write: # these instructions will be
push $0 # executed eventually
call exit
end: