i found an article about self modifying code and tried to do some examples, but i get always segmentation faults. As fas as i can understand, there is a violation in memory permissions. The code segment is (r)ead/e(x)ecute and so the attempt of writting results to this fault. Is there a way to test the program either by changing the memory permissions at runtime or before? I’m using linux and the example is written in GAS assembly.
.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:
so after modification suggested by osgx here is a working code.(Actually if you assemble&link&run it crashes but if you watch using gdb it does modifies its code!)
.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:
Advertisement
Answer
You should to change memory access permissions in runtime.
#include <sys/mman.h> 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 */ }