{"id":18530606,"url":"https://github.com/gsingh93/linux-exploit-dev-env","last_synced_at":"2025-04-09T12:32:57.079Z","repository":{"id":65340640,"uuid":"578982502","full_name":"gsingh93/linux-exploit-dev-env","owner":"gsingh93","description":"Everything you need to build and run Linux and Android kernels for exploit development","archived":false,"fork":false,"pushed_at":"2024-04-09T19:04:39.000Z","size":9355,"stargazers_count":57,"open_issues_count":5,"forks_count":12,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-24T06:11:27.317Z","etag":null,"topics":["kernel","linux"],"latest_commit_sha":null,"homepage":"","language":"Makefile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gsingh93.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-12-16T11:11:46.000Z","updated_at":"2025-03-21T20:56:53.000Z","dependencies_parsed_at":"2024-02-15T07:29:08.097Z","dependency_job_id":"1037abda-2d1c-435d-b75d-0f7ebb4fa6dd","html_url":"https://github.com/gsingh93/linux-exploit-dev-env","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsingh93%2Flinux-exploit-dev-env","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsingh93%2Flinux-exploit-dev-env/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsingh93%2Flinux-exploit-dev-env/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsingh93%2Flinux-exploit-dev-env/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gsingh93","download_url":"https://codeload.github.com/gsingh93/linux-exploit-dev-env/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248040867,"owners_count":21037956,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kernel","linux"],"created_at":"2024-11-06T18:01:33.293Z","updated_at":"2025-04-09T12:32:52.070Z","avatar_url":"https://github.com/gsingh93.png","language":"Makefile","readme":"# Linux Exploit Development Environment\n\n## Quickstart\n\nThe only supported host OS is Ubuntu 22.04, things may or may not work on any other system.\n\nFirst install the dependencies and clone the project:\n```bash\nsudo apt update\nsudo apt install -y bc bison build-essential flex git libelf-dev libssl-dev ncurses-dev gdb gdb-multiarch qemu qemu-system-x86 qemu-system-arm qemu-user-static binfmt-support llvm clang clang-tools lld lz4 binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu pahole dwarves\ngit clone --recursive https://github.com/gsingh93/linux-exploit-dev-env\ncd linux-exploit-dev-env\n```\n\nThis will clone the Linux kernel and Android Common Kernel (ACK) submodules. You can checkout any version of the kernel you want, i.e.\n```bash\nVERSION=5.10.107 make linux_checkout # Checkout a specific version\nVERSION=5.10.y make linux_checkout # Checkout the latest version of an LTS kernel\n```\n\nCreate the default rootfs images:\n```bash\nmake rootfs-init\n```\n\nBuild and run the Linux kernel:\n```bash\nmake\nmake run\n```\n\nTo exit QEMU, use `ctrl+a x` (`ctrl-c` will not work).\n\nTo attach with GDB, set the `GDB` environment variable before running:\n```bash\nGDB=1 make run\n```\n\nAnd then in another terminal, attach with:\n```bash\nscripts/gdb.sh\n```\n\nThe default architecture is x86_64, but arm64 is also supported:\n```bash\nARCH=arm64 make rootfs-init\nARCH=arm64 make run\n```\n\n## All Targets and Options\n\n```\n$ make help\nGeneral Environment Variables:\n   ARCH                             - Specify one of the supported architectures: x86_64, i386, arm64 (default: x86_64)\n   ACK                              - Set to 1 to build ACK instead of the Linux kernel. Does not need to be set for `ack` and `run-ack` targets (default: 0)\n   VERBOSE                          - Set to 1 to enable verbose output (default: 0)\n\nBuild/Config:\n   Targets:\n      linux (default)               - Build the Linux kernel\n      linux_defconfig               - Run `make defconfig`\n      linux_menuconfig              - Run `make menuconfig`\n      linux_modules                 - Build the Linux kernel modules\n      linux_debpkg                  - Creates a Debian package for the kernel\n      ack                           - Build the Android Common Kernel\n      tools-vm                      - Build linux/tools/vm\n\n   Environment Variables:\n      LINUX_DEFCONFIG               - The defconfig to use when building the kernel (default: defconfig, ACK default: gki_defconfig)\n      LINUX_SRC                     - The path to the kernel source directory (default: linux, ACK default: ack/common)\n      LINUX_OUT                     - The path where the kernel build output should be stored (default: out/linux/$ARCH, ACK default: out/ack/common/$ARCH)\n      LINUX_CONFIG_FRAGMENT         - A kernel config fragment to merge with the defconfig (default: config/config.fragment)\n\nClean:\n   Targets:\n      clean                         - Clean output from default build targets\n      \u003ctarget\u003e_clean                - Clean output for \u003ctarget\u003e, where \u003ctarget\u003e is one of: ack, linux, tools-vm, rootfs\n\nRun/Debug:\n   Targets:\n      run                           - Run QEMU with the built kernel and rootfs image\n      run-ack                       - Same as `run` but runs ACK instead\n\n   Environment Variables:\n      GDB                           - Set to 1 to start a gdbserver and wait for GDB when running QEMU (default: 0)\n      CPU                           - The number of CPUs to use when running QEMU (default: 4)\n      MEM                           - The memory size in MB to use when running QEMU (default: 1024)\n      QEMU_EXTRA_ARGS               - Additional arguments to pass to QEMU (default: \"\")\n      QEMU_EXTRA_KERNEL_CMDLINE     - Additional arguments to pass to the kernel (default: \"\")\n      QEMU_KERNEL_IMAGE             - The path to the kernel image to run (x86_64/i386 default: $LINUX_OUT/arch/$ARCH/boot/bzImage, arm64 default: $LINUX_OUT/arch/$ARCH/boot/Image)\n      ROOTFS                        - The path to the rootfs image file (default: rootfs/alpine-$ARCH.img)\n      ROOTFS_FORMAT                 - The format of the rootfs image file: raw, qcow2 (default: qcow2)\n      INITRD                        - Set to 1 to use the $CPIO_FILE initramfs instead of the $ROOTFS image as the rootfs, or specify the path to an alternative CPIO file (default: \"\")\n      RDINIT                        - The value of the `rdinit` kernel command line parameter (default: \"\", default if INITRD is set: /sbin/init)\n      ECHR                          - The value of the QEMU `-echr` flag (default: 1)\n      ROOT                          - The value of the `root` kernel command line parameter (default: /dev/vda)\n      RW                            - Whether to mount the rootfs as read-write or read-only: ro, rw (default: rw)\n      KASLR                         - Set to 1 to enable KASLR (default: 0)\n\nrootfs:\n   Targets:\n      rootfs-init                   - Extract the Alpine Linux rootfs to $ROOTFS_DIR and then run the `rootfs-overlay` target\n      rootfs-overlay                - Apply arch-specific changes to $ROOTFS_DIR and run the `rootfs` target\n      rootfs                        - Run the `ext4` and `cpio` targets\n      ext4                          - Build a $ROOTFS $ROOTFS_FORMAT (default qcow2) image with an ext4 filesystem from $ROOTFS_DIR\n      cpio                          - Build a $CPIO_FILE gzipped initramfs CPIO file from $ROOTFS_DIR\n      initramfs                     - An alias for the `cpio` target\n      uncpio                        - Extract $CPIO_FILE to $ROOTFS_DIR\n      rootfs-mount                  - Mount $ROOTFS image at /tmp/rootfs\n      rootfs-unmount                - Unmount rootfs image from /tmp/rootfs\n      chroot                        - chroot into $ROOTFS_DIR\n\n   Environment Variables:\n      EXT4_SIZE                     - The disk size of the rootfs image to build\n      ROOTFS_DIR                    - The directory to create the ext4 rootfs image and initramfs CPIO from (default: rootfs/alpine-$ARCH)\n      ROOTFS                        - The path to the rootfs image file (default: rootfs/alpine-$ARCH.img)\n      ROOTFS_FORMAT                 - The format of the rootfs image file: raw, qcow2 (default: qcow2)\n      CPIO_FILE                     - The path to the CPIO file to create (default: rootfs/alpine-$ARCH.cpio.gz)\n\nMiscellaneous:\n   Targets:\n      linux_download                - Downloads an archive of the Linux kernel source for the version specified in $VERSION\n      linux_checkout                - Checks out the version specified by $VERSION of the linux kernel in $LINUX_SRC\n\n   Environment Variables:\n      VERSION                       - The version to download or checkout. For checkout only, if the third number in the version string is a 'y', the latest version of the kernel with that major and minor version is used. Examples: 5.10, 5.10.107, v5.10, 5.10.y, linux-5.10.y\n```\n\n## Building\n\nYou can customize the path to the linux source and output directories with the `LINUX_SRC` and `LINUX_OUT` environment variables:\n```bash\nLINUX_SRC=/path/to/src LINUX_OUT=/path/to/out make linux\n```\n\nNote that the default output directory is `out/$KERNEL_DIR/$ARCH`, which means that switching between architecture or kernel types (i.e. ACK or Linux) will not overwrite builds of another architecture or kernel type.\n\n### Android Common Kernel (ACK)\n\nInstead of the Linux kernel, you can set the `ACK` variable to build the Android Common Kernel:\n```bash\nACK=1 make linux\nACK=1 make run\n```\n\n### defconfig\n\nTo generate the default kernel config with the default `defconfig`, run:\n```bash\nmake linux_defconfig\n```\n\nThe `ARCH` and `ACK` variables can also be used here:\n```bash\nACK=1 ARCH=arm64 make linux_defconfig\n```\n\nIf `ACK` is set `gki_defconfig` is used instead of `defconfig`. By default, `config/config.fragment` is merged into the generated config to create the final kernel config. This can be customized by setting `LINUX_CONFIG_FRAGMENT`.\n\n## rootfs\n\nThe default rootfs is based on [Alpine Linux's](https://alpinelinux.org/downloads/) mini root filesystem. `make rootfs-init` will automatically extract the file system to `rootfs/alpine-$ARCH` and create the filesystem image at `rootfs/rootfs-$ARCH.img`. You can modify the file system by modifying the files in `rootfs/alpine-$ARCH` and then running `make rootfs` to regenerate the image. If you have another directory where you keep your rootfs, or you'd like to customize where the output image is stored, you can use the `ROOTFS_DIR` and `ROOTFS` variables:\n```bash\nROOTFS_DIR=/path/to/rootfs/dir ROOTFS=/path/to/output/rootfs.img ROOTFS_FORMAT=qcow2 make rootfs\n```\n\nIf you'd like to use an initramfs instead of a disk image, you can use `make cpio`, which will create `rootfs/alpine-$ARCH.cpio.gz` by default. To build an initramfs from a different directory, use the `INITRAMFS_DIR` variable:\n```bash\nINITRAMFS_DIR=/path/to/initramfs/dir make cpio\n```\n\nRemember to set the correct `ARCH` variable for these commands if you are working with an architecture other than x86_64.\n\n## Running\n\nWhen running a kernel, you can specify an alternative rootfs or initramfs (but not both) with the `ROOTFS` and `INITRD` variables:\n```bash\nROOTFS=/path/to/rootfs-qcow2.img make run\nROOTFS=/path/to/rootfs-raw.img ROOTFS_FORMAT=raw make run\nINITRD=/path/to/initramfs.cpio.gz make run\n```\n\nThe number of CPUs and the amount of memory can be configured with the `CPU` and `MEM` variables. You can pass additional arguments to QEMU or the kernel command line with `QEMU_EXTRA_ARGS` and `QEMU_EXTRA_KERNEL_CMDLINE`, respectively:\n```bash\nCPU=4 MEM=2048M QEMU_EXTRA_KERNEL_CMDLINE=\"nokaslr\" QEMU_EXTRA_ARGS=\"-S -s\" make run\n```\n\nAs shown earlier, `GDB=1` can be used instead of `QEMU_EXTRA_ARGS=\"-S -s\"`.\n\n## Miscellaneous Commands\n\n`make linux_download` (which downloads a source archive) and `make linux_checkout` can be used to more easily switch between kernel versions. The kernel version to download or checkout must be specified with the `VERSION` environment variable:\n```bash\nVERSION=5.10.107 make linux_download\nVERSION=5.10.107 make linux_checkout\n```\n\nThe version string can be specified as `5.10.107` or `v5.10.107` (the name of the version tag in the Linux git repo). You can additionally set the last number to `y` to checkout or download the latest version of that kernel:\n```bash\nVERSION=5.10.y make linux_download\nVERSION=5.10.y make linux_checkout\n```\n\nThe `LINUX_SRC` variable can be used to customize the source directory for `linux_checkout`.\n\nThese `make` targets are just wrappers around the `./scripts/download_linux.sh` and `./scripts/checkout_linux.sh` scripts, so if you prefer those can be used instead.\n\n## Miscellaneous Features\n\nIf a `.env` file exists in root of the repository, it will be sourced at the beginning of the Makefile. If you are often passing in the same environment variables on every invocation (i.e. `ARCH=arm64`), you can add this into `.env` instead of passing it on the command line. If you want to put your most commonly used defaults in `.env` but still use other values for some invocations of `make`, you can override any variables by putting them after the `make` invocation. For example, if `.env` contains `ARCH=arm64`, then `make linux ARCH=x86_64` would set this variable to `x86_64` when building. Setting the variable before the `make` invocation (i.e. `ARCH=x86_64 make linux`) will not override the values defined in `.env`.\n\nIf the `TERMINAL_CMD` environment variable is defined when executing `make run`, it will be used to execute `scripts/gdb.sh` automatically before starting QEMU. You can use this to open GDB in a new window or frame. For example, when running `make run` in a `tmux` session, setting `TERMINAL_CMD=\"tmux splitw -h\"` will launch GDB in a new `tmux` pane.\n\nYou can add your own `make` targets without modifying the core `makefile`. See the README in the [external](./external) directory for more information and [this project](https://github.com/gsingh93/linux-exploit-dev-env-art-kt) for an example.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgsingh93%2Flinux-exploit-dev-env","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgsingh93%2Flinux-exploit-dev-env","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgsingh93%2Flinux-exploit-dev-env/lists"}