gpt4 book ai didi

assembly - x86_64 程序集 - 尝试在 x64 程序集中编辑数组内的字节时出现段错误

转载 作者:行者123 更新时间:2023-12-02 09:18:09 25 4
gpt4 key购买 nike

我正在学习的教程是针对 x86 的,并且是使用 32 位汇编语言编写的,我尝试在学习 x64 汇编语言的过程中进行学习。直到本课为止,一切都进展顺利,我有以下简单的程序,它只是尝试修改字符串中的单个字符;它编译得很好,但运行时出现段错误。

section .text

global _start ; Declare global entry oint for ld
_start:

jmp short message ; Jump to where or message is at so we can do a call to push the address onto the stack

code:
xor rax, rax ; Clean up the registers
xor rbx, rbx
xor rcx, rcx
xor rdx, rdx

; Try to change the N to a space
pop rsi ; Get address from stack
mov al, 0x20 ; Load 0x20 into RAX
mov [rsi], al; Why segfault?
xor rax, rax; Clear again

; write(rdi, rsi, rdx) = write(file_descriptor, buffer, length)
mov al, 0x01 ; write the command for 64bit Syscall Write (0x01) into the lower 8 bits of RAX
mov rdi, rax ; First Paramter, RDI = 0x01 which is STDOUT, we move rax to ensure the upper 56 bits of RDI are zero
;pop rsi ; Second Parameter, RSI = Popped address of message from stack
mov dl, 25 ; Third Parameter, RDX = Length of message
syscall ; Call Write

; exit(rdi) = exit(return value)
xor rax, rax ; write returns # of bytes written in rax, need to clean it up again
add rax, 0x3C ; 64bit syscall exit is 0x3C
xor rdi, rdi ; Return value is in rdi (First parameter), zero it to return 0
syscall ; Call Exit

message:
call code ; Pushes the address of the string onto the stack
db 'AAAABBBNAAAAAAAABBBBBBBB',0x0A

罪魁祸首是这一行:

mov [rsi], al; Why segfault?

如果我把它注释掉,那么程序运行正常,输出消息'AAAABBBNAAAAAAAAAABBBBBBBB',为什么我不能修改字符串?

作者代码如下:

global _start


_start:
jmp short ender

starter:

pop ebx ;get the address of the string
xor eax, eax

mov al, 0x20
mov [ebx+7], al ;put a NULL where the N is in the string

mov al, 4 ;syscall write
mov bl, 1 ;stdout is 1
pop ecx ;get the address of the string from the stack
mov dl, 25 ;length of the string
int 0x80

xor eax, eax
mov al, 1 ;exit the shellcode
xor ebx,ebx
int 0x80

ender:
call starter
db 'AAAABBBNAAAAAAAABBBBBBBB'0x0A

我已经使用以下方法编译了它:

nasm -f elf <infile> -o <outfile>
ld -m elf_i386 <infile> -o <outfile>

但即使这会导致段错误,页面上的图像显示它工作正常并将 N 更改为空格,但是我似乎陷入了段错误领域:( Google 在这种情况下并没有真正提供帮助,所以我转向你 stackoverflow,任何指针(没有双关语意图!)将不胜感激

最佳答案

我认为这是因为您正在尝试访问 .text 部分中的数据。通常出于安全考虑,您不允许写入代码段。可修改的数据应位于 .data 部分。 (如果零初始化,则为 .bss。)

对于实际的 shellcode,如果您不想使用单独的部分,请参阅 Segfault when writing to string allocated by db [assembly] 以获取替代解决方法。


此外,我绝不会建议使用 call 将其后面的地址插入堆栈来获取指向其后面数据的指针的副作用,shellcode 除外。

这是 shellcode 中的常见技巧(必须与位置无关); 32位模式需要以某种方式调用来获取EIP。 call 必须具有向后位移以避免机器代码中的 00 字节,因此将调用放在创建您特别想要的“返回”地址的位置可以节省 添加lea

即使在可以进行 RIP 相对寻址的 64 位代码中,jmp/call/pop 也与跳过具有负位移的 RIP 相对 LEA 的字符串一样紧凑。

在 shellcode/受限机器代码用例之外,这是一个糟糕的主意,您应该像普通人一样 lea reg, [rel buf] .data 中的数据和 .text 中的代码。 (或者 .rodata 中的只读数据。)这样您就不会尝试在数据旁边执行代码,或者将数据放在代码旁边。

(允许 shellcode 的代码注入(inject)漏洞已经暗示存在具有写入和执行权限的页面,但是现代工具链中的正常进程没有任何 W+X 页面,除非您采取措施来实现这一点。W^X 是因此,这是一个很好的安全功能,因此必须击败正常的工具链安全功能/默认值才能测试 shellcode。)

关于assembly - x86_64 程序集 - 尝试在 x64 程序集中编辑数组内的字节时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45005078/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com