自修改代码总是在 Linux 上出现分段错误 [英] Self modifying code always segmentation faults on Linux
问题描述
我找到了一篇关于自我修改代码的文章并尝试做一些示例,但我总是遇到分段错误.据我所知,内存权限存在违规行为.代码段是(r)ead/e(x)ecute,因此尝试将结果写入此故障.有没有办法通过在运行时或之前更改内存权限来测试程序?我使用的是 linux,示例是用 GAS 程序集编写的.
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:
所以在 osgx 建议的修改之后,这里是一个工作代码.(实际上,如果你组装&link&run 它会崩溃,但如果你使用 gdb 观看它确实会修改它的代码!)
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:
推荐答案
您应该在运行时更改内存访问权限.
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 */
}
这篇关于自修改代码总是在 Linux 上出现分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!