Código de auto modificación siempre fallas de segmentación en Linux

Encontré un artículo sobre el código de auto modificación e intenté hacer algunos ejemplos, pero siempre recibo fallas de segmentación. Hasta donde 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 bash de escribir da como resultado este error. ¿Hay alguna manera de probar el progtwig cambiando los permisos de memoria en tiempo de ejecución o antes? Estoy usando Linux y el ejemplo está escrito en 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 de trabajo. (En realidad, si lo ensamblas y lo vincula y lo ejecutas, ¡se bloquea pero si lo 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: 

Debe cambiar los permisos de acceso a la memoria en tiempo de ejecución.

 #include  void *addr = get_address_of_instruction_pointer(); int length = 4096; /* size of a page */ if (mprotect(addr, length, PROT_READ | PROT_WRITE | PROT_EXEC) == 0) { /* current code page is now writable and code from it is allowed for execution */ } 

Las CPU modernas tienen una característica llamada DEP que impide la ejecución del código en la stack. Anteriormente, esto era posible; ahora, no lo es. El binario se carga en la memoria de solo lectura de forma predeterminada.

Con eso fuera del camino, puede usar la llamada al sistema mprotect para marcar la ubicación de su binario en la memoria como ejecutable, MIENTRAS SU CÓDIGO NO ESTÉ PROTEGIDO. Así que no trates de poner el código y la stack y luego saltar a ella.

También puede desactivar la protección contra escritura para todo el progtwig pasando el interruptor -N al enlazador. Si está invocando el enlazador desde gcc, pase Wl,-N . Si invoca ld directamente, pase -N .

Intereting Posts