# nx

Nx is short-hand for Non-Executable stack. What this means is that the stack region of memory is not executable. So if there is perfectly valid code there, you can't execute it due to it's permissions.

For more on this, let's take a look at the memory mappings for a binary that was compiled without this mitigation:

Here it is with `NX` enabled:

```
gef➤  vmmap
Start              End                Offset             Perm Path
0x[PII_REDACTED]400000 0x[PII_REDACTED]401000 0x[PII_REDACTED]000000 r-- /tmp/tryc
0x[PII_REDACTED]401000 0x[PII_REDACTED]402000 0x[PII_REDACTED]001000 r-x /tmp/tryc
0x[PII_REDACTED]402000 0x[PII_REDACTED]403000 0x[PII_REDACTED]002000 r-- /tmp/tryc
0x[PII_REDACTED]403000 0x[PII_REDACTED]404000 0x[PII_REDACTED]002000 r-- /tmp/tryc
0x[PII_REDACTED]404000 0x[PII_REDACTED]405000 0x[PII_REDACTED]003000 rw- /tmp/tryc
0x00007ffff7dcb000 0x00007ffff7df0000 0x[PII_REDACTED]000000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7df0000 0x00007ffff7f63000 0x[PII_REDACTED]025000 r-x /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7f63000 0x00007ffff7fac000 0x[PII_REDACTED]198000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fac000 0x00007ffff7faf000 0x[PII_REDACTED]1e0000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7faf000 0x00007ffff7fb2000 0x[PII_REDACTED]1e3000 rw- /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fb2000 0x00007ffff7fb8000 0x[PII_REDACTED]000000 rw-
0x00007ffff7fce000 0x00007ffff7fd1000 0x[PII_REDACTED]000000 r-- [vvar]
0x00007ffff7fd1000 0x00007ffff7fd2000 0x[PII_REDACTED]000000 r-x [vdso]
0x00007ffff7fd2000 0x00007ffff7fd3000 0x[PII_REDACTED]000000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7fd3000 0x00007ffff7ff4000 0x[PII_REDACTED]001000 r-x /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ff4000 0x00007ffff7ffc000 0x[PII_REDACTED]022000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffc000 0x00007ffff7ffd000 0x[PII_REDACTED]029000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffd000 0x00007ffff7ffe000 0x[PII_REDACTED]02a000 rw- /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffe000 0x00007ffff7fff000 0x[PII_REDACTED]000000 rw-
0x00007ffffffde000 0x00007ffffffff000 0x[PII_REDACTED]000000 rw- [stack]
0xffffffffff600000 0xffffffffff601000 0x[PII_REDACTED]000000 r-x [vsyscall]
```

Here is is with `NX` disabled:

```
gef➤  vmmap
Start              End                Offset             Perm Path
0x[PII_REDACTED]400000 0x[PII_REDACTED]403000 0x[PII_REDACTED]000000 r-x /tmp/try
0x[PII_REDACTED]403000 0x[PII_REDACTED]404000 0x[PII_REDACTED]002000 r-x /tmp/try
0x[PII_REDACTED]404000 0x[PII_REDACTED]405000 0x[PII_REDACTED]003000 rwx /tmp/try
0x00007ffff7dcb000 0x00007ffff7fac000 0x[PII_REDACTED]000000 r-x /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fac000 0x00007ffff7faf000 0x[PII_REDACTED]1e0000 r-x /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7faf000 0x00007ffff7fb2000 0x[PII_REDACTED]1e3000 rwx /usr/lib/x86_64-linux-gnu/libc-2.29.so
0x00007ffff7fb2000 0x00007ffff7fb8000 0x[PII_REDACTED]000000 rwx
0x00007ffff7fce000 0x00007ffff7fd1000 0x[PII_REDACTED]000000 r-- [vvar]
0x00007ffff7fd1000 0x00007ffff7fd2000 0x[PII_REDACTED]000000 r-x [vdso]
0x00007ffff7fd2000 0x00007ffff7ffc000 0x[PII_REDACTED]000000 r-x /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffc000 0x00007ffff7ffd000 0x[PII_REDACTED]029000 r-x /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffd000 0x00007ffff7ffe000 0x[PII_REDACTED]02a000 rwx /usr/lib/x86_64-linux-gnu/ld-2.29.so
0x00007ffff7ffe000 0x00007ffff7fff000 0x[PII_REDACTED]000000 rwx
0x00007ffffffde000 0x00007ffffffff000 0x[PII_REDACTED]000000 rwx [stack]
0xffffffffff600000 0xffffffffff601000 0x[PII_REDACTED]000000 r-x [vsyscall]
```

So we can see that for when `NX` is enabled, the stack has the memory permissions `rw`. When `NX` hasn't been enabled, the stack has the memory permissions `rwx`. So when `NX` is enabled we can read and write to it, however when `NX` isn't enabled we can read / write / and execute code. Let's see what happens when we try to jump to somewhere in the stack (essentially executing data in the stack as code) while `NX` is enabled:

```
gef➤  j *0x00007ffffffde000
Continuing at 0x7ffffffde000.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffffffde000 in ?? ()
[ Legend: Modified register | Code | Heap | Stack | String ]
────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0xfffffffffffffe00
$rbx   : 0x00007ffff7fafa00  →  0x00000000fbad2288
$rcx   : 0x00007ffff7ed7f81  →  0x5777fffff0003d48 ("H="?)
$rdx   : 0x400             
$rsp   : 0x00007fffffffdee8  →  0x00007ffff7e5ae50  →  <_IO_file_underflow+336> test rax, rax
$rbp   : 0xd68             
$rsi   : 0x[PII_REDACTED]559260  →  0x[PII_REDACTED]000000
$rdi   : 0x0               
$rip   : 0x00007ffffffde000  →  0x[PII_REDACTED]000000
$r8    : 0x00007ffff7fb2580  →  0x[PII_REDACTED]000000
$r9    : 0x00007ffff7fb7500  →  0x00007ffff7fb7500  →  [loop detected]
$r10   : 0x00007ffff7fafca0  →  0x[PII_REDACTED]559660  →  0x[PII_REDACTED]000000
$r11   : 0x246             
$r12   : 0x00007ffff7fb0960  →  0x[PII_REDACTED]000000
$r13   : 0x00007ffff7fb1560  →  0x[PII_REDACTED]000000
$r14   : 0x00007ffff7fb0848  →  0x00007ffff7fb0760  →  0x00000000fbad2084
$r15   : 0x00007ffff7fafa00  →  0x00000000fbad2288
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffdee8│+0x0000: 0x00007ffff7e5ae50  →  <_IO_file_underflow+336> test rax, rax     ← $rsp
0x00007fffffffdef0│+0x0008: 0x00007ffff7f7a447  →  "__vdso_getcpu"
0x00007fffffffdef8│+0x0010: 0x00007ffff7fafa00  →  0x00000000fbad2288
0x00007fffffffdf00│+0x0018: 0x00007ffff7fb1560  →  0x[PII_REDACTED]000000
0x00007fffffffdf08│+0x0020: 0x[PII_REDACTED]00000a
0x00007fffffffdf10│+0x0028: 0x[PII_REDACTED]000000
0x00007fffffffdf18│+0x0030: 0x[PII_REDACTED]000008
0x00007fffffffdf20│+0x0038: 0x00007ffff7fafa00  →  0x00000000fbad2288
──────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0x7ffffffddffa                  add    BYTE PTR [rax], al
   0x7ffffffddffc                  add    BYTE PTR [rax], al
   0x7ffffffddffe                  add    BYTE PTR [rax], al
 → 0x7ffffffde000                  add    BYTE PTR [rax], al
   0x7ffffffde002                  add    BYTE PTR [rax], al
   0x7ffffffde004                  add    BYTE PTR [rax], al
   0x7ffffffde006                  add    BYTE PTR [rax], al
   0x7ffffffde008                  add    BYTE PTR [rax], al
   0x7ffffffde00a                  add    BYTE PTR [rax], al
──────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "tryc", stopped, reason: SIGSEGV
────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7ffffffde000 → add BYTE PTR [rax], al
[#1] 0x7ffff7e5ae50 → _IO_new_file_underflow(fp=0x7ffff7fafa00 <_IO_2_1_stdin_>)
[#2] 0x7ffff7e5c182 → __GI__IO_default_uflow(fp=0x