> For the complete documentation index, see [llms.txt](https://breakpoint-journal.gitbook.io/breakpoint/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://breakpoint-journal.gitbook.io/breakpoint/binary-exploitation/x86-64-pwning-on-apple-silicon.md).

# x86-64 Pwning on Apple Silicon

When I switched to an M4 Mac, I had issues with setting up x86-64 heap exploitation challenges given that Apple Silicon runs ARM64. I needed a lightweight VM, given that a real virtual machine would take too much memory and the latency was dog\*\*\*\*.  Docker's Rosetta translation layer seemed like the obvious choice... until it wasn't.

Ultimately, I was able to get docker up and running with the following configs below, but then couldn't actually debug any of the binaries in GDB without running into faults or loss of symbol resolution.

{% hint style="warning" %}
See <https://stackoverflow.com/questions/77124810/gdb-crashes-debugging-x86-binary-under-rosetta-2-apple-virtualization-framewor>
{% endhint %}

<details>

<summary>Dockerfile.amd</summary>

{% code title="" %}

```docker
FROM --platform=linux/amd64 ubuntu:20.04
RUN apt-get update && apt-get install -y build-essential binutils git make vim gcc patchelf python-is-python3 python3-pip wget zstd tmux
RUN pip3 install requests pwntools
RUN wget --https-only --secure-protocol=TLSv1_2 -qO- 'https://install.pwndbg.re' | sh -s -- -t pwndbg-gdb
RUN git config --global --add safe.directory "*"

WORKDIR /root
CMD ["bash"]
```

{% endcode %}

</details>

<details>

<summary>Dockerfile.arm</summary>

{% code title="" %}

```docker
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y \
    build-essential binutils git make vim gcc patchelf python-is-python3 python3-pip wget zstd tmux\
    && rm -rf /var/lib/apt/lists/*
RUN pip3 install requests pwntools
RUN wget --https-only --secure-protocol=TLSv1_2 -qO- 'https://install.pwndbg.re' | sh -s -- -t pwndbg-gdb
RUN git config --global --add safe.directory "*"

WORKDIR /root
```

{% endcode %}

</details>

After hitting too many Rosetta edge cases and workarounds, I discovered **Lima**, and it's been a game-changer for my pwn work.

## The Problem: Docker + Rosetta Isn't Enough

Docker Desktop on Apple Silicon uses Rosetta 2, a binary translator that converts x86-64 instructions to ARM64 at runtime. Programs seemingly ran alright, however, being unable to utilize GDB for exploit development was a nightmare.

<figure><img src="https://2618442973-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmGhYQRY1OEeL4zywZ9zS%2Fuploads%2FyOnVbIZAtKd0JOE4abLi%2Fhit-punch.gif?alt=media&amp;token=d3e78af7-4e6a-4794-b1cb-a2fee9928ef3" alt=""><figcaption></figcaption></figure>

Rosetta has known limitations with:

* Low-level system calls that don't translate cleanly
* ptrace operations needed for debugging
* Memory layout assumptions that differ between x86-64 and ARM64
* Performance consistency issues when testing heap exploits

## LFTW (Lima For The Win)

**Lima** (Linux Machine) is a lightweight VM framework for macOS that uses QEMU under the hood. Pretty much exactly like docker, but it doesn't rely on Rosetta and actually worked for my use case!

<figure><img src="https://2618442973-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmGhYQRY1OEeL4zywZ9zS%2Fuploads%2FPYB7gg17esdxbrSsHolG%2Fimage.png?alt=media&amp;token=372f3c57-b280-4b1e-b7b8-5908527189c2" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
More Lima documentation at <https://lima-vm.io/>
{% endhint %}

## Setting It Up

{% hint style="success" %}
For a Lima'd version of how2heap check out <https://github.com/jgbby/how2heap>
{% endhint %}

{% stepper %}
{% step %}

### Installation

```bash
brew install lima
```

{% endstep %}

{% step %}

### Create the VM

I created a Lima config for exploit development, containing binutils, pwndbg, etc:

<details>

<summary>pwn.yaml</summary>

```yaml
# Lima VM config for x86-64 CTF / pwn work
# Usage:
#   First time:  limactl start --name=pwn pwn.yaml
#   Shell:       limactl shell pwn
#   Stop:        limactl stop pwn
#   Delete:      limactl delete pwn

vmType: qemu
arch: x86_64
os: Linux

images:
  - location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img"
    arch: x86_64

cpus: 4
memory: "4GiB"
disk: "20GiB"

mountType: 9p
mounts:
  - location: "/Users/john.smith"
    mountPoint: "/home/lima.guest"
    writable: true
    exec: true
    9p:
      securityModel: mapped-xattr
      cache: mmap

provision:
  - mode: system
    script: |
      #!/bin/bash
      set -e
      apt-get update && apt-get install -y \
        build-essential binutils git make vim gcc \
        patchelf python-is-python3 python3-pip \
        wget zstd tmux

  - mode: system
    script: |
      #!/bin/bash
      set -e
      pip3 install requests pwntools

  - mode: system
    script: |
      #!/bin/bash
      set -e
      wget --https-only --secure-protocol=TLSv1_2 -qO- 'https://install.pwndbg.re' | sh -s -- -t pwndbg-gdb

  - mode: system
    script: |
      #!/bin/bash
      set -e
      git config --global --add safe.directory "*"

  - mode: system
    script: |
      #!/bin/bash
      set -e
      echo 'kernel.yama.ptrace_scope = 0' >> /etc/sysctl.d/99-ptrace.conf
      sysctl -p /etc/sysctl.d/99-ptrace.conf
```

</details>

Then start it:

```bash
limactl start --name=pwn pwn.yaml
```

The first boot takes a few minutes as it downloads the Ubuntu image and installs tools.
{% endstep %}

{% step %}

### Use the VM

```bash
# Enter the VM
limactl shell pwn

# Compile and run x86-64 binaries
gcc -o exploit exploit.c -m64
./exploit

# Use pwntools and pwndbg for development
python3 exploit.py
gdb -x pwndbg_commands.gdb ./binary
```

Your local `~/` is mounted inside the VM at `/home/lima.guest`, so you can edit on the host and run on the VM.
{% endstep %}
{% endstepper %}

### What Gets Installed

The config automatically provisions everything you need for exploit work:

* **Compilers & build tools**: gcc, make, binutils, build-essential
* **Exploit frameworks**: pwntools (Python library for writing exploits)
* **Debugging**: pwndbg (GDB plugin purpose-built for exploit development)
* **System tools**: tmux, git, python3, pip3, wget, zstd, vim

It also configures ptrace (needed for GDB) to work without privilege restrictions, and marks git as safe in any directory.

## Verdict

If you're doing binary exploitation research on Apple Silicon and Docker's Rosetta has let you down, Lima is worth the 10-20 minute setup. You get a real x86-64 Linux environment that's easy to manage and performant enough for serious work.
