提问人:T-series 提问时间:10/3/2023 最后编辑:T-series 更新时间:10/4/2023 访问量:71
在循环中显示堆栈值时出现问题
Problem with displaying stack values in a loop
问:
改写了问题
在迭代和显示堆栈值(为简单起见,2 次迭代)后,在最后一次 printf 之后立即出现分段错误。
只是尝试在循环中在堆栈上显示十六进制值。尝试将堆栈与步骤对齐(愚蠢的我),这意味着向堆栈添加 8 个字节以达到对齐状态,这没有产生任何东西。sub rsp, 8
另一个更新
发现将堆栈扩展 120 字节可以完成对齐堆栈的工作。 有人可以解释为什么是 120..?我的意思是我在 Loop 之前和循环中有 3 个 CALL 和 3 个 PUSH,每个都需要 8 个字节的额外堆栈(据我所知)。
法典:
global _start
extern printf
section .data
;format db "value at esp: %llx", 10, 0x00
format db "%012llX", 10, 0x00
section .text
_start:
mov rax, 0xa284ee5c7cde4bd7
push rax
mov rax, 0x935add110510849a
push rax
mov rax, 0x10b29a9dab697500
push rax
mov rax, 0x200ce3eb0d96459a
push rax
mov rax, 0xe64c30e305108462
push rax
mov rax, 0x69cd355c7c3e0c51
push rax
mov rax, 0x65659a2584a185d6
push rax
mov rax, 0x69ff00506c6c5000
push rax
mov rax, 0x3127e434aa505681
push rax
mov rax, 0x6af2a5571e69ff48
push rax
mov rax, 0x6d179aaff20709e6
push rax
mov rax, 0x9ae3f152315bf1c9
push rax
mov rax, 0x373ab4bb0900179a
push rax
mov rax, 0x69751244059aa2a3
push rax
;---
mov rbx, 0x2144d2144d2144d2 ;!!
;---
xor rcx, rcx ; initialize rcx to 0
mov rcx, 2 ; initialize rcx to 14 loops
mov r15, rsp ; initialize the pointer to rsp right after pushing all of RAX
call Loop
call Exit ; Exit the program
Loop:
xor rax, rax
mov r14, [r15] ;have rax as temp holder of valu at rdx not to overwrite
;xor r14, rbx ;rdx while xoring at the next line
push rcx
push r14
push r15
call printMessage
pop r15
pop r14
pop rcx
add r15, 8 ;move up the stack
loop Loop
printMessage:
mov rdi, format ; set 1st argument (Print Format)
mov rsi, r14 ; set 2nd argument (message)
call printf ; printf(outFormat, message)
ret
Exit:
mov rax, 60
mov rdi, 0
syscall
分段故障前最后一步的 GDB:
gef➤ r
Starting program: /home/kali/Desktop/assembly/exercise 1/Final/final1
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
69751244059AA2A3
373AB4BB0900179A
Program received signal SIGSEGV, Segmentation fault.
**0x00007ffff7e1db44 in __printf (format=0x403008 "%012llX\n") at ./stdio-common/printf.c:28
28 ./stdio-common/printf.c: No such file or directory.**
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x11
$rbx : 0x2144d2144d2144d2
$rcx : 0x0
$rdx : 0x0
$rsp : 0x00007fffffffdd48 → 0x0000000000000000
$rbp : 0x0
$rsi : 0x373ab4bb0900179a
$rdi : 0x0000000000403008 → "%012llX\n"
$rip : 0x00007ffff7e1db44 → <printf+36> movaps XMMWORD PTR [rsp+0x50], xmm0
$r8 : 0x58
$r9 : 0x0
$r10 : 0x0
$r11 : 0x202
$r12 : 0x0000000000401020 → <_start+0> movabs rax, 0xa284ee5c7cde4bd7
$r13 : 0x00007fffffffdea0 → 0x0000000000000001
$r14 : 0x373ab4bb0900179a
$r15 : 0x00007fffffffde40 → 0x9ae3f152315bf1c9
$eflags: [zero carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x33 $ss: 0x2b $ds: 0x00 $es: 0x00 $fs: 0x00 $gs: 0x00
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffdd48│+0x0000: 0x0000000000000000 ← $rsp
0x00007fffffffdd50│+0x0008: 0x373ab4bb0900179a
0x00007fffffffdd58│+0x0010: 0x0000000000000000
0x00007fffffffdd60│+0x0018: 0x0000000000000001
0x00007fffffffdd68│+0x0020: 0x0000000000000400
0x00007fffffffdd70│+0x0028: 0x373ab4bb0900179a
0x00007fffffffdd78│+0x0030: 0x0000000000000000
0x00007fffffffdd80│+0x0038: 0x0000000000000000
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x7ffff7e1db3b <printf+27> mov QWORD PTR [rsp+0x48], r9
0x7ffff7e1db40 <printf+32> test al, al
0x7ffff7e1db42 <printf+34> je 0x7ffff7e1db7b <__printf+91>
→ 0x7ffff7e1db44 <printf+36> movaps XMMWORD PTR [rsp+0x50], xmm0
0x7ffff7e1db49 <printf+41> movaps XMMWORD PTR [rsp+0x60], xmm1
0x7ffff7e1db4e <printf+46> movaps XMMWORD PTR [rsp+0x70], xmm2
0x7ffff7e1db53 <printf+51> movaps XMMWORD PTR [rsp+0x80], xmm3
0x7ffff7e1db5b <printf+59> movaps XMMWORD PTR [rsp+0x90], xmm4
0x7ffff7e1db63 <printf+67> movaps XMMWORD PTR [rsp+0xa0], xmm5
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "final1", stopped 0x7ffff7e1db44 in __printf (), reason: SIGSEGV
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7ffff7e1db44 → __printf(format=0x403008 "%012llX\n")
[#1] 0x401106 → printMessage()
[#2] 0x4010d4 → _start()
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤
gef➤ si
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
答: 暂无答案
评论
mov rsi, r9 ; rsi: pointer to message
当然,它不是一个指针,而是一个值。此外,它是 8 个字节而不是 20 个字节。r9
write
push r9
/mov rsi, rsp
/pop r9
将该值保留在 RSP 下方,该值将被下一个 .但是在叶子函数中很好,尽管当然/会更有效和更简单。(是的,将内容放在 RSP 以下是安全的,因为 x86-64 System V ABI 有一个红色区域。另请参阅在 Assembly 中为 64 位 Linux 的 x86_64编写 putchar?,其中显示了一个示例。call
lea rsi, [rsp-8]
mov [rsi], r9