Assembly mov指令中的分段错误
rdi包含一段代码的地址。我正在尝试对该代码实施XOR编码。当我运行该代码时,mov指令会导致分段错误。有人能帮忙吗Assembly mov指令中的分段错误,assembly,x86-64,Assembly,X86 64,rdi包含一段代码的地址。我正在尝试对该代码实施XOR编码。当我运行该代码时,mov指令会导致分段错误。有人能帮忙吗 mov byte al,[rdi]; No errors xor al,0x7f mov byte [rdi],al; Causes segmeation fault 完整代码: section .text global _start _start: call encrypt code: xor rax,rax
mov byte al,[rdi]; No errors
xor al,0x7f
mov byte [rdi],al; Causes segmeation fault
完整代码:
section .text
global _start
_start:
call encrypt
code:
xor rax,rax
xor rdx,rdx
xor rcx,rcx
xor rdx,rdx
mov rdi,0x636e2f6e69622f2f
shr rdi,0x8
push rdi
mov rdi,rsp
mov rsi,0x6c2dffffffffffff
shr rsi,0x30
push rsi
mov rsi,rsp
mov rbx,0x702dffffffffffff
shr rbx,0x30
push rbx
mov rbx,rsp
mov rcx,0x30393039ffffffff
shr rcx,0x20
push rcx
mov rcx,rsp
mov rdx,0x652dffffffffffff
shr rdx,0x20
push rdx
mov rdx,rsp
xor r8,r8
mov r8,0x68732f6e69622f2f
shr r8,0x8
push r8
mov r8,rsp
push r8
push rdx
push rcx
push rbx
push rsi
push rdi
mov rsi,rsp
mov al,59
syscall
encrypt:
pop rdi
mov cl,0x8a
mov bl,0
loo:
dec cl
mov byte al,[rdi]
xor al,0x7f
mov byte [rdi],al ;segfault occurs here
inc rdi
jne loo
jmp code
rdi包含一段代码的地址
许多系统通过主动防止写入代码区域(a)来提供恶意代码保护。例如,代码选择器可能指向标记为只读的内存块(除非您运行的代码试图以某种形式的特权模式修改它)
在这种情况下,您几乎肯定会遇到这种保护机制。您如何解决它(假设它是允许的)将取决于您的环境中比您当前提供的更多的细节(例如操作系统)
例如,在Linux下,您可以使用更改虚拟内存空间中某些地址范围的保护
(a) 有些还阻止您像执行代码一样执行数据,这意味着,即使您将代码移动到可以编写的地方,也可能无法执行它 rdi包含一段代码的地址 许多系统通过主动防止写入代码区域(a)来提供恶意代码保护。例如,代码选择器可能指向标记为只读的内存块(除非您运行的代码试图以某种形式的特权模式修改它) 在这种情况下,您几乎肯定会遇到这种保护机制。您如何解决它(假设它是允许的)将取决于您的环境中比您当前提供的更多的细节(例如操作系统) 例如,在Linux下,您可以使用更改虚拟内存空间中某些地址范围的保护
(a) 有些还阻止您将数据当作代码来执行,这意味着,即使您将代码移动到可以编写的地方,您也可能无法执行它。rdi指出您可能无法编写的地方,请发布完整的代码好吗?如果不知道rdi的点在哪里,就很难说到底出了什么问题。你是为什么操作系统编程的?Debian linux…rdi点可能在某个地方重复,你可能写不出来,可以发布完整的代码吗?如果看不到rdi的指向,很难说到底哪里出了问题。你是为什么操作系统编程的?Debian linux…可能是重复的,有没有其他方法写入该位置?@John没有足够的数据来说明。但可能不是。约翰:不是从你的用户空间进程内部。您可以制作代码的修改副本,并从其他地方执行它,例如,如果您分配了具有R+W+X权限的内存页。IDK为什么一次只对一个字节进行异或运算,而不是4或8(或SSE2为16)。也不知道为什么你显然在源代码中硬编码代码的绝对地址,尽管我猜如果你想要一个XORed版本的地址,你不能让链接器为你这样做。但它不能与库或PIE可执行文件中的代码ASLR一起工作。我使用mprotect syscall将该页上的内存保护更改为可写。现在它工作得很好。是否有其他方法可以写入该位置?@John没有足够的数据说。但可能不是。约翰:不是从你的用户空间进程内部。您可以制作代码的修改副本,并从其他地方执行它,例如,如果您分配了具有R+W+X权限的内存页。IDK为什么一次只对一个字节进行异或运算,而不是4或8(或SSE2为16)。也不知道为什么你显然在源代码中硬编码代码的绝对地址,尽管我猜如果你想要一个XORed版本的地址,你不能让链接器为你这样做。但它不能与库或PIE可执行文件中的代码ASLR一起工作。我使用mprotect syscall将该页上的内存保护更改为可写。现在它工作得很好