-
Apex Legends external cheat for Linux.
-
As of Season 23, for QEMU/KVM (formerly for Proton).
+----------+ +----------+ +------------+ +--------------+
| Linux PC | -> | QEMU/KVM | -> | Windows VM | -> | Apex Legends |
+----------+ +----------+ +------------+ +--------------+- The goal of this project is to have a working Linux cheat that can run alongside Apex Legends on my i5-6600K 4c/4t Linux PC.
- Stable CR3 shuffle for Windows 10 20H1
- Overlay based ESP for players and items
- Press 5 / 6 / 7 / 8 / 9 / 0 to cycle LIGHT / ENERGY / SHOTGUN / HEAVY / SNIPER / GEAR items
- Map radar
- Spectators list
- Humanized aimbot
- Inside FOV circle, hold RMB (Right Mouse Button) to aimbot skynade (even behind cover)
- Hold SHIFT to lock on target or show item names
- Toggle aimbot strength with CURSOR_LEFT; "<" symbol in the upper left corner of the screen
- Toggle ADS locking with CURSOR_RIGHT; ">" symbol in the upper left corner of the screen
- Toggle triggerbot auto fire with CURSOR_UP; "^" symbol in the upper left corner of the screen
- Toggle hitbox with CURSOR_DOWN;
body/neck/headtext in the upper left corner of the screen - Hold CAPS_LOCK to superglide
- Press F8 to dump r5apex and scan for offsets
- Press F9 twice to terminate cheat
-
This guide is for PCs that you can actually plug your monitor into iGPU (internal GPU in CPU), leaving your dGPU exclusively for the VM.
-
A single GPU guide is available at: ThisIsFair/Nika-Read-Only-SGPU
-
Enter BIOS and enable Virtualization Technology:
- VT-d for Intel (VMX)
- AMD-Vi for AMD (SVM)
- Enable "IOMMU"
- Disable "Above 4G Decoding"
-
Nested Virtualization for Intel:
sudo su
echo "options kvm_intel nested=0" > /etc/modprobe.d/kvm.conf- Nested Virtualization for AMD:
sudo su
echo "options kvm_amd nested=0" > /etc/modprobe.d/kvm.conf- Preload
vfio-pcimodule so it can bind to PCI IDs:
sudo su
echo "softdep nvidia pre: vfio-pci" >> /etc/modprobe.d/kvm.conf
echo "softdep nouveau pre: vfio-pci" >> /etc/modprobe.d/kvm.conf- Update initramfs:
<Fedora> sudo dracut --force
<Debian> sudo update-initramfs -c -k $(uname -r)Install on Fedora Linux (Fedora 42 KDE):
sudo dnf install @virtualization
Install on Debian Linux (Debian 13 KDE):
sudo apt update
sudo apt install virt-manager
- Edit
/etc/libvirt/qemu.confand uncomment (needed for audio):
#user = "libvirt-qemu"
user = "1000"- Edit
/etc/libvirt/libvirtd.confand uncomment:
unix_sock_group = "libvirt"
unix_sock_rw_perms = "0770"- Join libvirt group and enable libvirt daemon:
test $UID = 0 && exit
sudo usermod -aG libvirt $USER
sudo systemctl enable libvirtd.service-
Restart Linux PC.
-
Start default virtual network:
sudo virsh net-autostart default
sudo virsh net-start default-
Virtual Machine Manager >> Edit >> Preferences >> General >> check [x] Enable XML editing >> [Close]
-
Virtual Machine Manager >> Edit >> Preferences >> New VM >> Storage format: Raw >> [Close]
-
Virtual Machine Manager >> File >> New Virtual Machine
-
Local install media (ISO image or CDROM) >>
Windows10.iso>> Choose Memory and CPU settings >> uncheck [ ] Enable storage for this virtual machine >> check [x] Customize configuration before install >> [Finish]- Overview >> Chipset: Q35, Firmware: OVMF_CODE_4M.secboot >> [Apply]
- [Add Hardware] >> Storage >> Device type: Disk device >> Bus type: SATA >> Create a disk image for the virtual machine: 240 GiB >> Advanced options >> Serial: B4NN3D53R14L >> [Finish]
- [Begin Installation] >> Virtual Machine >> Shut Down >> Force Off
-
Virtual Machine Manager >> [Open] >> View >> Details >> Video QXL >> Model: VGA >> [Apply]
-
Virtual Machine Manager >> [Open] >> View >> Details >> NIC :xx:xx:xx >> [Remove]
- Network topology for a virtual NIC is typically obvious.
- Add a removable NIC instead.
-
Virtual Machine Manager >> [Open] >> View >> Details >> SATA Disk 1 >> XML
-
Replace
<driver name="qemu" type="raw"/>and [Apply]:Spoiler
<driver name="qemu" type="raw" cache="none" discard="ignore"/>
-
Virtual Machine Manager >> [Open] >> View >> Details >> Overview >> XML
-
Replace
<domain type="kvm">and [Apply]:Spoiler (do NOT use this example, instead modify it with your own SMBIOS data; sudo dmidecode)
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0"> <qemu:commandline> <qemu:arg value="-smbios"/> <qemu:arg value="type=1,manufacturer=HP,product=HP Laptop 14s-dq2xxx,version=23.41,serial=D3E4F56789"/> <qemu:arg value="-smbios"/> <qemu:arg value="type=2,manufacturer=HP,product=87FD,version=34.12,serial=B1C2D3E4F56789"/> <qemu:arg value="-smbios"/> <qemu:arg value="type=3,manufacturer=HP,version=23.41,serial=D3E4F56789"/> <qemu:arg value="-smbios"/> <qemu:arg value="type=4,sock_pfx=U3E1,manufacturer=Intel(R) Corporation,version=11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz,processor-id=0xBFEBFBFF000806C1"/> <qemu:arg value="-smbios"/> <qemu:arg value="type=17,manufacturer=Samsung,part=M471A5244CB0-CWE,speed=3200,serial=D3E4F5"/> <qemu:arg value="-smbios"/> <qemu:arg value="type=8,internal_reference=J1A1,external_reference=Keyboard,connector_type=0x0F,port_type=0x0D"/> <qemu:arg value="-smbios"/> <qemu:arg value="type=8,internal_reference=J1A1,external_reference=Mouse,connector_type=0x0F,port_type=0x0E"/> <qemu:arg value="-smbios"/> <qemu:arg value="type=9,slot_designation=J6C1,slot_type=0xAA,slot_data_bus_width=0x0D,current_usage=0x04,slot_length=0x04,slot_id=0x01,slot_characteristics1=0x04,slot_characteristics2=0x03"/> </qemu:commandline>
- VM created by QEMU is Intel, do not use AMD data.
-
Replace
</metadata>and [Apply]:Spoiler
<vmware xmlns="http://www.vmware.com/schema/vmware.config"> <config> <entry name="hypervisor.cpuid.v0" value="FALSE"/> </config> </vmware> </metadata>
-
Replace from
<memory unit="KiB">4194304</memory>to<vcpu placement="static">2</vcpu>and [Apply]:Spoiler (use a commercial memory size like 8, 16, or 24 GiB; vcpu example for 8 threads host CPU)
<memory unit="GiB">24</memory> <currentMemory unit="GiB">24</currentMemory> <vcpu placement="static">8</vcpu>
-
Replace from
<features>to</clock>and [Apply]:Spoiler (example for 4 cores 8 threads host CPU)
<features> <acpi/> <apic/> <hyperv mode="custom"> <relaxed state="off"/> <vapic state="off"/> <spinlocks state="off"/> <vpindex state="off"/> <runtime state="off"/> <synic state="off"/> <stimer state="off"/> <reset state="off"/> <vendor_id state="off"/> <frequencies state="off"/> <reenlightenment state="off"/> <tlbflush state="off"/> <ipi state="off"/> <evmcs state="off"/> <avic state="off"/> </hyperv> <kvm> <hidden state="on"/> </kvm> <pmu state="on"/> <vmport state="off"/> <smm state="on"/> <ioapic driver="kvm"/> <msrs unknown="fault"/> </features> <cpu mode="host-passthrough" check="none" migratable="off"> <topology sockets="1" cores="4" threads="2"/> <feature policy="disable" name="aes"/> <feature policy="disable" name="hypervisor"/> <feature policy="require" name="svm"/> <feature policy="require" name="vmx"/> <feature policy="disable" name="x2apic"/> <feature policy="require" name="topoext"/> <feature policy="require" name="invtsc"/> <feature policy="disable" name="amd-ssbd"/> <feature policy="disable" name="ssbd"/> <feature policy="disable" name="virt-ssbd"/> <feature policy="disable" name="rdpid"/> <feature policy="disable" name="rdtscp"/> </cpu> <clock offset="localtime"> <timer name="tsc" present="yes" tickpolicy="discard" mode="native"/> <timer name="hpet" present="yes"/> <timer name="rtc" present="no"/> <timer name="pit" present="no"/> <timer name="kvmclock" present="no"/> <timer name="hypervclock" present="no"/> </clock>
-
Replace from
<memballoon model="virtio">to</memballoon>and [Apply]:Spoiler
<memballoon model="none"/>
-
Replace
<audio id="1" type="spice"/>and [Apply]:Spoiler (for pipewire sound, not required)
<audio id="1" type="pipewire" runtimeDir="/run/user/1000"> <input name="qemuinput"/> <output name="qemuoutput"/> </audio>
-
Virtual Machine Manager >> [Open] >> View >> Details >> Tablet >> [Remove]
-
Virtual Machine Manager >> [Open] >> View >> Details >> Serial 1 >> [Remove]
-
Virtual Machine Manager >> [Open] >> View >> Details >> Channel (spice) >> [Remove]
-
Virtual Machine Manager >> [Open] >> View >> Details >> Controller VirtIO Serial 0 >> [Remove]
- Virtual Machine Manager >> [Open] >> View >> Details >> Boot Options >> Boot device order:
- SATA Disk 1 >> [Apply]
- Find GPU location with:
lspci -v | grep -i VGA
00:02.0 VGA compatible controller: Intel Corporation HD Graphics 530 (rev 06) (prog-if 00 [VGA controller])
02:00.0 VGA compatible controller: NVIDIA Corporation TU106 [GeForce RTX 2070] (rev a1) (prog-if 00 [VGA controller])- GeForce RTX 2070 has 4 PCI IDs:
lspci -v | grep -i NVIDIA
02:00.0 VGA compatible controller: NVIDIA Corporation TU106 [GeForce RTX 2070] (rev a1) (prog-if 00 [VGA controller])
Subsystem: NVIDIA Corporation TU106 [GeForce RTX 2070]
02:00.1 Audio device: NVIDIA Corporation TU106 High Definition Audio Controller (rev a1)
Subsystem: NVIDIA Corporation Device 1f02
02:00.2 USB controller: NVIDIA Corporation TU106 USB 3.1 Host Controller (rev a1) (prog-if 30 [XHCI])
Subsystem: NVIDIA Corporation Device 1f02
02:00.3 Serial bus controller: NVIDIA Corporation TU106 USB Type-C UCSI Controller (rev a1)
Subsystem: NVIDIA Corporation Device 1f02- Find PCI IDs with:
lspci -n -s 02:00
02:00.0 0300: 10de:1f02 (rev a1)
02:00.1 0403: 10de:10f9 (rev a1)
02:00.2 0c03: 10de:1ada (rev a1)
02:00.3 0c80: 10de:1adb (rev a1)- Edit
/etc/default/grub, use either intel_iommu=on or amd_iommu=on:
GRUB_CMDLINE_LINUX="module_blacklist=nvidia,nouveau vfio-pci.ids=10de:1f02,10de:10f9,10de:1ada,10de:1adb intel_iommu=on iommu=pt"- Update GRUB and restart Linux PC:
<Fedora> sudo grub2-mkconfig -o /boot/grub2/grub.cfg
<Debian> sudo grub-mkconfig -o /boot/grub/grub.cfg- Inspect IOMMU enabled with:
if compgen -G "/sys/kernel/iommu_groups/*/devices/*" > /dev/null; then echo "IOMMU enabled."; fi- Inspect kernel driver in use with:
lspci -k -s 02:00
02:00.0 VGA compatible controller: NVIDIA Corporation TU106 [GeForce RTX 2070] (rev a1)
Subsystem: NVIDIA Corporation TU106 [GeForce RTX 2070]
Kernel driver in use: vfio-pci
Kernel modules: nouveau
02:00.1 Audio device: NVIDIA Corporation TU106 High Definition Audio Controller (rev a1)
Subsystem: NVIDIA Corporation Device 1f02
Kernel driver in use: vfio-pci
Kernel modules: snd_hda_intel
02:00.2 USB controller: NVIDIA Corporation TU106 USB 3.1 Host Controller (rev a1)
Subsystem: NVIDIA Corporation Device 1f02
Kernel driver in use: xhci_hcd
02:00.3 Serial bus controller: NVIDIA Corporation TU106 USB Type-C UCSI Controller (rev a1)
Subsystem: NVIDIA Corporation Device 1f02
Kernel driver in use: vfio-pci
Kernel modules: i2c_nvidia_gpu- Not loaded as a module,
xhci_hcdwill be managed by libvirt.
-
Virtual Machine Manager >> [Open] >> View >> Details >> [Add Hardware] >> PCI Host Device:
- 02:00.0 NVIDIA Corporation TU106 [GeForce RTX 2070] >> [Finish]
- 02:00.1 NVIDIA Corporation TU106 High Definition Audio Controller >> [Finish]
- 02:00.2 NVIDIA Corporation TU106 USB 3.1 Host Controller >> [Finish]
- 02:00.3 NVIDIA Corporation TU106 USB Type-C UCSI Controller >> [Finish]
-
Install GPU drivers on Windows VM.
- Find your mouse and keyboard with:
ls -l /dev/input/by-id/
usb-COMPANY_USB_Device-event-if02 -> ../event7
usb-COMPANY_USB_Device-event-kbd -> ../event4
usb-COMPANY_USB_Device-if01-event-mouse -> ../event5
usb-COMPANY_USB_Device-if01-mouse -> ../mouse0
usb-COMPANY_USB_Device-if02-event-kbd -> ../event6
usb-SONiX_USB_DEVICE-event-if01 -> ../event9
usb-SONiX_USB_DEVICE-event-kbd -> ../event8-
By symlink
../mouse0you find thatusb-COMPANY_USB_Deviceis your mouse. -
You are looking for
event-mouseandevent-kbd:usb-COMPANY_USB_Device-if01-event-mouse -> ../event5is your mouse.usb-SONiX_USB_DEVICE-event-kbd -> ../event8is your keyboard.
-
Edit
/etc/libvirt/qemu.confand uncomment:
cgroup_device_acl = [
"/dev/null", "/dev/full", "/dev/zero",
"/dev/random", "/dev/urandom",
"/dev/ptmx", "/dev/kvm", "/dev/kqemu",
"/dev/rtc", "/dev/hpet",
"/dev/input/by-id/usb-COMPANY_USB_Device-if01-event-mouse",
"/dev/input/by-id/usb-SONiX_USB_DEVICE-event-kbd",
"/dev/input/event5",
"/dev/input/event8",
"/dev/userfaultfd"
]-
Include
cgroup_device_aclas above, replacingevent-kbd,event-mouse, and the path to each symlink/dev/input/eventX. -
Restart libvirtd:
sudo systemctl restart libvirtd- Toggle input with LEFT_CTRL + RIGHT_CTRL when needed.
-
Virtual Machine Manager >> [Open] >> View >> Details >> Overview >> XML
-
Replace
</qemu:commandline>and [Apply]:Spoiler
<qemu:arg value="-object"/> <qemu:arg value="input-linux,id=kbd1,evdev=/dev/input/by-id/usb-SONiX_USB_DEVICE-event-kbd,grab_all=on,repeat=on"/> <qemu:arg value="-object"/> <qemu:arg value="input-linux,id=mouse1,evdev=/dev/input/by-id/usb-COMPANY_USB_Device-if01-event-mouse"/> </qemu:commandline>
-
Join input group:
test $UID = 0 && exit
sudo usermod -aG input $USERManually stop `SELinux` every reboot on Fedora Linux:
sudo setenforce 0
Permanently disable `AppArmor` on Debian Linux:
sudo systemctl stop apparmor
sudo systemctl disable apparmor
- Restart Linux PC.
-
For window settings, open; System Settings >> Window Management >> Window Rules >> Import... >> GLFW.kwinrule
- Also check; System Settings >> Display & Monitor >> Scale: 100%
-
Virtual Machine Manager >> [Open] >> View >> Details >> Video VGA >> Model: None >> [Apply]
-
You will be using video output from passthrough GPU instead of VGA virtual GPU.
| Method | Latency | ESP | Cons |
|---|---|---|---|
| Cable | 0 ms | Glow | Overlay on 2nd monitor |
| Capture card | 30-300 ms | Overlay+Glow | Investment for faster device |
| Steam Remote Play | 10 ms | Overlay+Glow | Encoded video |
- Plug monitor into passthrough GPU.
Install `gstreamer1.0-tools` on Debian Linux:
sudo apt install gstreamer1.0-tools
-
Plug capture card into passthrough GPU.
-
Open capture card raw feed with:
gst-launch-1.0 -v v4l2src device=/dev/video0 ! video/x-raw,width=1920,height=1080,framerate=60/1 ! videoconvert ! autovideosink- Install:
cd path/to/extracted/repository
chmod +x nika- Run:
cd path/to/extracted/repository
sudo -E ./nika-
This script is based on: Scrut1ny/Hypervisor-Phantom
Build on Fedora Linux:
sudo dnf builddep qemu sudo dnf install acpica-tools
Build on Debian Linux:
sudo apt build-dep qemu sudo apt install acpica-tools
-
Run
qemupatch.shto clone, patch, and build QEMU with generated data. -
Virtual Machine Manager >> [Open] >> View >> Details >> Overview >> XML
-
Replace from
<pm>to</emulator>and [Apply]:Spoiler
<pm> <suspend-to-mem enabled="yes"/> <suspend-to-disk enabled="no"/> </pm> <devices> <emulator>/usr/local/bin/qemu-system-x86_64</emulator>
-
Replace
</qemu:commandline>and [Apply]:Spoiler (not required, ignore this)
<qemu:arg value="-acpitable"/> <qemu:arg value="file=/usr/local/bin/ssdt1.aml"/> </qemu:commandline>
-
This script is based on: Scrut1ny/Hypervisor-Phantom
Build on Fedora Linux:
sudo dnf install g++ sudo dnf install nasm sudo dnf install python3-virt-firmware
Build on Debian Linux:
sudo apt install g++ sudo apt install nasm sudo apt install python3-virt-firmware
-
Run
edk2patch.shto clone, patch, and build OVMF with generated data. -
Virtual Machine Manager >> [Open] >> View >> Details >> Overview >> XML
-
Replace from
<os firmware="efi">to</os>and [Apply]:Spoiler
<os> <type arch="x86_64" machine="pc-q35-9.2">hvm</type> <loader readonly="yes" secure="yes" type="pflash" format="qcow2">/usr/share/edk2/ovmf/OVMF_CODE_4M.patched.qcow2</loader> <nvram format="qcow2">/usr/share/edk2/ovmf/OVMF_VARS_4M.patched.qcow2</nvram> <bootmenu enable="yes"/> </os>
-
This step and below requires Windows with passthrough GPU drivers installed.
-
Virtual Machine Manager >> [Open] >> View >> Details >> CPUs >> uncheck [ ] Copy host CPU configuration >> Model:
-
Choose one from:
Nehalem,Westmere,SandyBridge,IvyBridge.- CPU model for each architecture was randomly set at
qemupatch.shruntime.
- CPU model for each architecture was randomly set at
-
Set cores and threads to match guest CPU.
- If guest CPU has 8 threads, use 4 cores 2 threads.
-
Finally [Apply].
-
-
Reverting to
host-passthroughwill clear most XML settings from<features>to</clock>previously set for CPU.
-
This step and below requires Windows with passthrough GPU drivers installed.
Build on Fedora Linux:
sudo dnf install util-linux-script
-
Run
kernelpatch.shto clone, patch, and build Linux with CPUID + RDTSC patch. -
Removing
rhgb quietfrom/etc/default/grubwill automatically display GRUB menu at boot:
Fedora Linux (6.16.12_tkg_eevdf+) 42 (KDE Plasma Desktop Edition)
Fedora Linux (6.14.0-63.fc42.x86_64) 42 (KDE Plasma Desktop Edition)
Windows Boot Manager (on /dev/sdb1)-
You should start VM as soon as possible.
-
300 seconds after selecting
6.14.11_tkg_eevdf+your guest CPU manufacturer will change:
C:\>wmic cpu get manufacturer
Manufacturer
AuthenticAMD
C:\>wmic cpu get manufacturer
Manufacturer
GenuineIntel-
Disable ROM BAR for each PCI Host Device:
- Virtual Machine Manager >> [Open] >> View >> Details >> PCI 0000:xx:xx.x >> ROM BAR: [ ] uncheck >> [Apply]
-
Check old UUID with
nvidia-smi -L. -
Run the cheat BEFORE the game at least once.
-
Check new UUID with
nvidia-smi -L.
Install dkms on Fedora Linux:
sudo dnf install kernel-devel-$(uname -r)
sudo dnf install kernel-devel-matched-$(uname -r)
sudo dnf install dkms
Install dkms on Debian Linux:
sudo apt install linux-headers-amd64=6.12.38-1
sudo apt install dkms
-
Download
memflow-0.2.1-source-only.dkms.tar.gzfrom: https://github.com/memflow/memflow-kvm/releases -
Install:
sudo dkms install --archive=memflow-0.2.1-source-only.dkms.tar.gz- Run:
sudo modprobe memflow
cd path/to/extracted/repository
sudo -E ./nika