mirror of
https://github.com/Gallopsled/pwntools.git
synced 2026-11-08 08:06:05 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bc6f6cd2b | ||
|
|
455c8c02c3 | ||
|
|
dbc618de0d | ||
|
|
34b8345d1d | ||
|
|
771c7f81ac | ||
|
|
8d69dc6142 | ||
|
|
3911a6a12e | ||
|
|
a5f3873194 | ||
|
|
481704bfd8 | ||
|
|
5196a1a0f0 | ||
|
|
be705326a7 | ||
|
|
c7e6ef37c8 | ||
|
|
210faac75b | ||
|
|
8e0e4c6c90 | ||
|
|
bbac6660b2 | ||
|
|
2a986f12c1 | ||
|
|
b60ed9928d | ||
|
|
b1391984d1 | ||
|
|
dd747e1062 | ||
|
|
78fccc055f | ||
|
|
4f50b45586 | ||
|
|
a1c7d07db8 | ||
|
|
6691e8476a | ||
|
|
a8bcdf6f8d | ||
|
|
bf5e4df220 | ||
|
|
68b5bbf16b | ||
|
|
9a7e197754 | ||
|
|
96c3ede156 | ||
|
|
f2eba7c8fd | ||
|
|
1c7d917432 | ||
|
|
1553670f9d | ||
|
|
8f67b7b7b5 | ||
|
|
459dfd7e35 | ||
|
|
d8d47977ac | ||
|
|
3daf28b6be | ||
|
|
f4b3e6e1c4 | ||
|
|
2b39684912 | ||
|
|
7e5e79d00f | ||
|
|
e551b4ae56 | ||
|
|
43ef1b494c | ||
|
|
be92aa1b4c | ||
|
|
07f3caadc4 | ||
|
|
3ad86ec5ad | ||
|
|
b5076d9262 | ||
|
|
77b4f06b07 | ||
|
|
4968499d11 | ||
|
|
f38991bc02 | ||
|
|
d0e6ee4b37 | ||
|
|
48ea09b27f | ||
|
|
9f22a2f202 | ||
|
|
7413a3da31 | ||
|
|
95aac6e367 | ||
|
|
9ed93a5281 | ||
|
|
3579fb1384 | ||
|
|
485bf0a0b7 | ||
|
|
b133b76b4e | ||
|
|
ffc46d277a | ||
|
|
dd3a5f6974 | ||
|
|
9a275b2db0 | ||
|
|
1c28222fe6 | ||
|
|
b93c5ace10 | ||
|
|
da9797c1c2 | ||
|
|
6dfe8b6f72 | ||
|
|
425221fb30 | ||
|
|
004a6dab88 | ||
|
|
6098f28bfa | ||
|
|
1205b1aaa3 | ||
|
|
ce6d2ca847 | ||
|
|
9e0ca3a415 | ||
|
|
b60b2e897f | ||
|
|
2c3e783f96 | ||
|
|
15bdd4a766 | ||
|
|
7c95e838f4 | ||
|
|
92aa64ce01 | ||
|
|
ae4bb08c3e | ||
|
|
6739525ebe | ||
|
|
d10b7aee4c | ||
|
|
aeb4c26bf0 | ||
|
|
ec6b8cd87c | ||
|
|
b2345f214e | ||
|
|
e9d9bd9ddb | ||
|
|
d7a7376eca | ||
|
|
9472ec1e93 | ||
|
|
e4b939dc1a | ||
|
|
c02190b5d4 | ||
|
|
e341e238ca | ||
|
|
7741a187ea | ||
|
|
4ef3c16d09 | ||
|
|
fb2ee19b90 | ||
|
|
74a300db6c | ||
|
|
57b9eb9107 | ||
|
|
b2d56fa37c | ||
|
|
a0ddbf5e16 | ||
|
|
1be8ad7770 | ||
|
|
24d217cfbd | ||
|
|
ec262d8d01 | ||
|
|
55ac6e11fc | ||
|
|
96d98cf192 | ||
|
|
6f0793eebc | ||
|
|
51cbdb465d | ||
|
|
61804b169b | ||
|
|
04e90bc754 | ||
|
|
8926a3a2bc | ||
|
|
bb7a85c8df | ||
|
|
3303ea949d | ||
|
|
cef48f4085 | ||
|
|
2ce27dab0d | ||
|
|
fa14663243 | ||
|
|
d2253110bd | ||
|
|
a3b22b748d | ||
|
|
584eccaa33 | ||
|
|
7dceeddca8 | ||
|
|
34da249779 | ||
|
|
c68c00c316 | ||
|
|
2e86d8afe2 | ||
|
|
f28d3ebb6c | ||
|
|
cfc021d88e | ||
|
|
9f92ed04fc | ||
|
|
b08f4b7bc8 | ||
|
|
d664bb49d4 | ||
|
|
c0d6e07f1c | ||
|
|
fa5a288a69 | ||
|
|
69ab2054e8 | ||
|
|
907e921043 | ||
|
|
a3f14df14d | ||
|
|
78dd777735 | ||
|
|
ee63072930 | ||
|
|
824d67d8f4 | ||
|
|
785ed9fdda | ||
|
|
5c1fb1d11b | ||
|
|
cdfd64f6de | ||
|
|
3727c93859 | ||
|
|
bc453b46c3 | ||
|
|
f47e417e4e | ||
|
|
7c79c73a5f | ||
|
|
3e9849f0ca | ||
|
|
149ebe0c47 | ||
|
|
d7817a7eac | ||
|
|
df620d7449 | ||
|
|
67678c2e1c | ||
|
|
734cb3bf82 | ||
|
|
adaa6abc08 | ||
|
|
3e21808da9 | ||
|
|
405357c075 | ||
|
|
248f4510c6 | ||
|
|
de67c86432 | ||
|
|
101f9bc76b | ||
|
|
4879590a37 | ||
|
|
7194ced044 | ||
|
|
6a9deffbfb | ||
|
|
26e72f2b3e | ||
|
|
00663aa1bf | ||
|
|
18c8bfba3d | ||
|
|
4284c3fcdf | ||
|
|
a366e91038 | ||
|
|
736cf9d112 | ||
|
|
4dc8d60b9e | ||
|
|
d5fffb6769 | ||
|
|
51e8eb09ee | ||
|
|
e92a30bbf7 | ||
|
|
fcec11784a | ||
|
|
fe560c9835 | ||
|
|
27366fdeb8 | ||
|
|
f2f55f3e1c | ||
|
|
7ac5a34a59 | ||
|
|
eec3321ae9 | ||
|
|
d2a02a7b37 | ||
|
|
c1ce1897df | ||
|
|
5981c7290d | ||
|
|
cb540857cc | ||
|
|
8ba1bdf0b6 | ||
|
|
4ac98cd11a | ||
|
|
75cc3c3d5c | ||
|
|
a2acdf9bd9 | ||
|
|
14c0d73f89 | ||
|
|
3b4b261b5a | ||
|
|
000c31c155 | ||
|
|
197f00806e | ||
|
|
e1770a3045 |
No files matched your search
@@ -39,7 +39,7 @@ You should see `[DEBUG]` statements that show what's happening behind the scenes
|
||||
|
||||
## Verify on Ubuntu
|
||||
|
||||
If possible, please verify that your issue occurs on 64-bit Ubuntu 18.04. We provide a Dockerfile based on Ubuntu 18.04 via `docker.io` to make this super simple, no VM required!
|
||||
If possible, please verify that your issue occurs on 64-bit Ubuntu 22.04. We provide a Dockerfile based on Ubuntu 22.04 via `docker.io` to make this super simple, no VM required!
|
||||
|
||||
```sh
|
||||
# Download the Docker image
|
||||
|
||||
@@ -6,24 +6,21 @@ jobs:
|
||||
android-test:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.8]
|
||||
python-version: ['3.10']
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Cache for pip
|
||||
uses: actions/cache@v4
|
||||
id: cache-pip
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ matrix.os }}-cache-pip
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: |
|
||||
**/pyproject.toml
|
||||
**/requirements*.txt
|
||||
|
||||
- name: Install Linux dependencies
|
||||
run: |
|
||||
@@ -35,6 +32,19 @@ jobs:
|
||||
binutils-arm-linux-gnueabihf \
|
||||
libc6-dbg
|
||||
|
||||
- name: Cache for avd
|
||||
uses: actions/cache@v4
|
||||
id: cache-avd
|
||||
with:
|
||||
path: |
|
||||
~/.android
|
||||
/usr/local/lib/android/sdk/emulator
|
||||
/usr/local/lib/android/sdk/platform-tools
|
||||
/usr/local/lib/android/sdk/system-images
|
||||
key: ${{ matrix.os }}-cache-avd-${{ hashFiles('travis/setup_avd*.sh') }}
|
||||
restore-keys: |
|
||||
${{ matrix.os }}-cache-avd-
|
||||
|
||||
- name: Install Android AVD
|
||||
run: |
|
||||
sudo usermod -aG kvm $USER
|
||||
|
||||
@@ -5,10 +5,29 @@ jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
python_version: ['2.7', '3.10']
|
||||
python_version: ['3.10', '3.12', '3.13', '3.14', '3.15']
|
||||
os: [ubuntu-latest]
|
||||
include:
|
||||
- python_version: '2.7'
|
||||
os: ubuntu-22.04
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
services:
|
||||
libcdb-cache:
|
||||
image: nginx
|
||||
volumes:
|
||||
- /home/runner/libcdb-cache:/var/cache/nginx
|
||||
ports:
|
||||
- 3000:3000 # https://debuginfod.elfutils.org proxy cache
|
||||
- 3001:3001 # https://libc.rip/ proxy cache
|
||||
- 3002:3002 # http://archive.ubuntu.com/ proxy cache
|
||||
- 3003:3003 # https://gitlab.com/ proxy cache
|
||||
- 3004:3004 # https://debuginfod.ubuntu.com/ proxy cache
|
||||
env:
|
||||
DEBUGINFOD_URLS: "http://localhost:3000/ http://localhost:3004/"
|
||||
PWN_LIBCRIP_URL: http://localhost:3001/
|
||||
PWN_UBUNTU_ARCHIVE_URL: http://localhost:3002/
|
||||
PWN_GITLAB_LIBCDB_URL: http://localhost:3003/
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -18,26 +37,54 @@ jobs:
|
||||
run: |
|
||||
git fetch origin
|
||||
git log --oneline --graph -10
|
||||
|
||||
- name: Fix libcdb-cache permissions
|
||||
id: fix-perms
|
||||
run: |
|
||||
sudo chown -R runner:runner /home/runner/libcdb-cache
|
||||
echo "date=$(/bin/date -u "+%Y%m%d%H%M%S")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache for libcdb requests
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/libcdb-cache
|
||||
key: libcdb-python${{ matrix.python_version }}-${{ steps.fix-perms.outputs.date }}
|
||||
restore-keys: |
|
||||
libcdb-python${{ matrix.python_version }}-
|
||||
libcdb-
|
||||
|
||||
- name: Install libcdb-cache service config
|
||||
run: |
|
||||
sudo chown -R 101:101 /home/runner/libcdb-cache
|
||||
container_id=$(docker ps --all --filter volume=/home/runner/libcdb-cache --no-trunc --format "{{.ID}}")
|
||||
docker cp ./travis/libcdb_nginx_cache.conf $container_id:/etc/nginx/nginx.conf
|
||||
docker restart $container_id
|
||||
|
||||
- name: Install RPyC for gdb
|
||||
run: |
|
||||
# The version packaged in python3-rpyc is too old on Ubuntu 22.04
|
||||
# The version packaged in python3-rpyc is too old on Ubuntu 24.04
|
||||
# We use ^6.0 from pip.
|
||||
sudo apt-get update && sudo apt-get install -y python3-pip gdb gdbserver
|
||||
/usr/bin/python -m pip install rpyc
|
||||
/usr/bin/python -m pip install --break-system-packages rpyc || /usr/bin/python -m pip install rpyc
|
||||
gdb --batch --quiet --nx --nh --ex 'py import rpyc; print(rpyc.version.version)'
|
||||
|
||||
|
||||
- name: Cache for pip
|
||||
uses: actions/cache@v4
|
||||
id: cache-pip
|
||||
if: matrix.python_version == '2.7'
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ matrix.os }}-cache-pip
|
||||
key: ${{ matrix.os }}-${{ matrix.python_version }}-cache-pip-${{ hashFiles('**/pyproject.toml', '**/requirements*.txt') }}
|
||||
restore-keys: ${{ matrix.os }}-${{ matrix.python_version }}-cache-pip-
|
||||
|
||||
- name: Set up Python ${{ matrix.python_version }}
|
||||
if: matrix.python_version != '2.7'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python_version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: |
|
||||
**/pyproject.toml
|
||||
**/requirements*.txt
|
||||
|
||||
- name: Set up Python 2.7
|
||||
if: matrix.python_version == '2.7'
|
||||
@@ -74,10 +121,12 @@ jobs:
|
||||
binutils-aarch64-linux-gnu \
|
||||
binutils-arm-linux-gnueabihf \
|
||||
binutils-mips-linux-gnu \
|
||||
binutils-mipsel-linux-gnu \
|
||||
binutils-msp430 \
|
||||
binutils-powerpc-linux-gnu \
|
||||
binutils-s390x-linux-gnu \
|
||||
binutils-sparc64-linux-gnu \
|
||||
binutils-riscv64-linux-gnu \
|
||||
gcc-multilib \
|
||||
libc6-dbg \
|
||||
elfutils \
|
||||
@@ -101,6 +150,8 @@ jobs:
|
||||
pip install --upgrade wheel build
|
||||
pip install --upgrade flake8 appdirs
|
||||
pip install --upgrade --editable .
|
||||
# Pin to known working version until 2.1.5 is out. https://github.com/unicorn-engine/unicorn/issues/2134
|
||||
pip install 'unicorn==2.1.2'
|
||||
|
||||
- name: Sanity checks
|
||||
run: PWNLIB_NOTERM=1 python -bb -c 'from pwn import *; print(pwnlib.term.term_mode)'
|
||||
@@ -149,11 +200,18 @@ jobs:
|
||||
pwn shellcraft --list |tail
|
||||
pwn shellcraft -l --syscalls |tail
|
||||
pwn shellcraft -l execve
|
||||
pwn shellcraft -l execve + exit
|
||||
pwn shellcraft --show i386.linux.loader_append
|
||||
pwn shellcraft --show i386.linux.loader_append + i386.linux.sh
|
||||
pwn shellcraft -f asm --color amd64.linux.sh
|
||||
pwn shellcraft -f asm --color amd64.linux.setreuid + amd64.linux.cat /etc/passwd
|
||||
pwn shellcraft -f asm --color amd64.linux.setreuid = amd64.linux.cat /key+secret --delim =
|
||||
pwn shellcraft -f elf amd64.linux.syscalls.exit 0 </dev/null |pwn hex
|
||||
pwn shellcraft -f elf amd64.linux.cat /etc/passwd + amd64.linux.syscalls.exit 0 </dev/null |pwn hex
|
||||
pwn shellcraft -f i --color amd64.linux.cat /etc/passwd </dev/null
|
||||
pwn shellcraft -f i --color amd64.linux.cat /etc/passwd + amd64.linux.sh </dev/null
|
||||
pwn shellcraft -f c amd64.linux.syscalls.exit 0 </dev/null
|
||||
pwn shellcraft -f c amd64.linux.cat /etc/passwd + amd64.linux.syscalls.exit 0 </dev/null
|
||||
pwn shellcraft -f str aarch64.linux.sh </dev/null
|
||||
pwn shellcraft -abr -f elf -o /dev/null amd64.linux.cat /etc/passwd </dev/null
|
||||
pwn shellcraft -nzr thumb.linux.syscalls.execve /bin/cat '["/bin/cat", "/etc/os-release"]' </dev/null
|
||||
@@ -195,16 +253,45 @@ jobs:
|
||||
python -m build
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: matrix.python_version != '2.7'
|
||||
if: matrix.python_version == '3.10'
|
||||
with:
|
||||
name: packages
|
||||
path: dist/
|
||||
include-hidden-files: true
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-${{ matrix.python_version }}
|
||||
path: .coverage*
|
||||
include-hidden-files: true
|
||||
|
||||
- name: Fix libcdb-cache permissions
|
||||
run: |
|
||||
container_id=$(docker ps --filter volume=/home/runner/libcdb-cache --no-trunc --format "{{.ID}}")
|
||||
docker stop $container_id
|
||||
sudo chown -R runner:runner /home/runner/libcdb-cache
|
||||
|
||||
windows-test:
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 30
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install --upgrade --editable .
|
||||
|
||||
- name: Sanity checks
|
||||
run: |
|
||||
python -bb -c 'from pwn import *'
|
||||
python -bb examples/text.py
|
||||
|
||||
upload-coverage:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -221,7 +308,7 @@ jobs:
|
||||
|
||||
- name: Install coveralls
|
||||
run: |
|
||||
pip install tomli coveralls
|
||||
pip install --break-system-packages tomli coveralls || pip install tomli coveralls
|
||||
|
||||
- name: Upload coverage to coveralls.io
|
||||
run: |
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Build and push base image
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
with:
|
||||
context: "{{defaultContext}}:extra/docker/base"
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
tags: pwntools/pwntools:base
|
||||
|
||||
- name: Build and push stable image
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/stable')
|
||||
with:
|
||||
context: "{{defaultContext}}:extra/docker/stable"
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
tags: pwntools/pwntools:stable
|
||||
|
||||
- name: Build and push beta image
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/beta')
|
||||
with:
|
||||
context: "{{defaultContext}}:extra/docker/beta"
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
tags: pwntools/pwntools:beta
|
||||
|
||||
- name: Build and push dev image
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/dev')
|
||||
with:
|
||||
context: "{{defaultContext}}:extra/docker/dev"
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
pwntools/pwntools:latest
|
||||
|
||||
- name: Build and push ci image
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/dev')
|
||||
with:
|
||||
context: "{{defaultContext}}:travis/docker"
|
||||
|
||||
@@ -5,23 +5,21 @@ jobs:
|
||||
lint:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.8]
|
||||
python-version: ['3.10']
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Cache for pip
|
||||
uses: actions/cache@v4
|
||||
id: cache-pip
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ matrix.os }}-cache-pip
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: |
|
||||
**/pyproject.toml
|
||||
**/requirements*.txt
|
||||
|
||||
- name: Critical lint
|
||||
run: |
|
||||
|
||||
@@ -5,33 +5,32 @@ jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.8]
|
||||
python-version: ['3.10']
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Cache for pip
|
||||
uses: actions/cache@v4
|
||||
id: cache-pip
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ matrix.os }}-cache-pip
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: |
|
||||
**/pyproject.toml
|
||||
**/requirements*.txt
|
||||
|
||||
- name: PyLint
|
||||
run: |
|
||||
set -x
|
||||
pip install pylint
|
||||
pip install 'pylint<4'
|
||||
pip install --upgrade -e .
|
||||
pylint --exit-zero --errors-only pwnlib -f parseable | cut -d ' ' -f2- > current.txt
|
||||
run_pylint() { pylint --exit-zero --errors-only pwnlib -f parseable | cut -d ' ' -f2- | sed 's/line [0-9]\+/line XXXX/g'; }
|
||||
run_pylint > current.txt
|
||||
git fetch origin
|
||||
git checkout origin/"$GITHUB_BASE_REF"
|
||||
pylint --exit-zero --errors-only pwnlib -f parseable | cut -d ' ' -f2- > base.txt
|
||||
run_pylint > base.txt
|
||||
if diff base.txt current.txt | grep '>'; then
|
||||
false
|
||||
fi
|
||||
+1
-1
@@ -5,7 +5,7 @@ version: 2
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3"
|
||||
python: "3.12"
|
||||
|
||||
sphinx:
|
||||
configuration: docs/source/conf.py
|
||||
|
||||
+205
-9
@@ -9,9 +9,12 @@ The table below shows which release corresponds to each branch, and what date th
|
||||
|
||||
| Version | Branch | Release Date |
|
||||
| ---------------- | -------- | ---------------------- |
|
||||
| [4.15.0](#4150-dev) | `dev` |
|
||||
| [4.14.0](#4140-beta) | `beta` |
|
||||
| [4.13.0](#4130-stable) | `stable` | Aug 12, 2024
|
||||
| [5.0.0](#500-dev) | `dev` |
|
||||
| [4.15.0](#4150-stable) | `stable` | Oct 12, 2025
|
||||
| [4.14.1](#4141) | | Mar 24, 2025
|
||||
| [4.14.0](#4140) | | Jan 15, 2025
|
||||
| [4.13.1](#4131) | | Sep 29, 2024
|
||||
| [4.13.0](#4130) | | Aug 12, 2024
|
||||
| [4.12.0](#4120) | | Feb 22, 2024
|
||||
| [4.11.1](#4111) | | Nov 14, 2023
|
||||
| [4.11.0](#4110) | | Sep 15, 2023
|
||||
@@ -70,11 +73,189 @@ The table below shows which release corresponds to each branch, and what date th
|
||||
| [3.0.0](#300) | | Aug 20, 2016
|
||||
| [2.2.0](#220) | | Jan 5, 2015
|
||||
|
||||
## 4.15.0 (`dev`)
|
||||
## 5.0.0 (`dev`)
|
||||
|
||||
- [#2419][2419] riscv: avoid compressed instructions (if you need compressed, use .option rvc)
|
||||
- [#2551][2551] Detect when kitty is being used as terminal
|
||||
- [#2519][2519] Drop Python 2.7 support / Require Python 3.10
|
||||
- [#2507][2507] Add `+LINUX` and `+WINDOWS` doctest options and start proper testing on Windows
|
||||
- [#2522][2522] Support starting a kitty debugging window with the 'kitten' command
|
||||
- [#2526][2526] Properly make use of extra arguments in `packing` utilities. `sign` parameter requires keyword syntax to specify it.
|
||||
- [#2517][2517] Allow to passthru kwargs on `ssh.__getattr__` convenience function to fix SSH motd problems
|
||||
- [#2529][2529] Add LoongArch64 support
|
||||
- [#2504][2504] doc: add example case for `tuple` (host, port pair) in `gdb.attach`
|
||||
- [#2546][2546] ssh: Allow passing disabled_algorithms keyword argument from ssh to paramiko
|
||||
- [#2538][2538] Add `ssh -L` / `ssh.connect_remote()` workaround when `AllowTcpForwarding` is disabled
|
||||
- [#2574][2574] Allow creating an ELF from in-memory bytes
|
||||
- [#2575][2575] Detect when Terminator is being used as terminal
|
||||
- [#2578][2578] Add gnome-terminal, Alacritty, Ttilix for run_in_new_terminal
|
||||
- [#2590][2590] Add support for finding corefiles under WSL2
|
||||
- [#2496][2496] Add linux ko file search support
|
||||
- [#2542][2542] Decode `_IO_*` flags in `FileStructure` member
|
||||
- [#2608][2608] Abort on `libcdb file libc.so --unstrip` if eu-unstrip is not installed
|
||||
- [#2611][2611] Cleanup `pwnlib.lexer` exports and imports
|
||||
- [#2615][2615] tube/process: Fix redirecting stderr to stdout on Windows
|
||||
|
||||
[2419]: https://github.com/Gallopsled/pwntools/pull/2419
|
||||
[2551]: https://github.com/Gallopsled/pwntools/pull/2551
|
||||
[2519]: https://github.com/Gallopsled/pwntools/pull/2519
|
||||
[2507]: https://github.com/Gallopsled/pwntools/pull/2507
|
||||
[2522]: https://github.com/Gallopsled/pwntools/pull/2522
|
||||
[2526]: https://github.com/Gallopsled/pwntools/pull/2526
|
||||
[2517]: https://github.com/Gallopsled/pwntools/pull/2517
|
||||
[2529]: https://github.com/Gallopsled/pwntools/pull/2529
|
||||
[2504]: https://github.com/Gallopsled/pwntools/pull/2504
|
||||
[2546]: https://github.com/Gallopsled/pwntools/pull/2546
|
||||
[2538]: https://github.com/Gallopsled/pwntools/pull/2538
|
||||
[2574]: https://github.com/Gallopsled/pwntools/pull/2574
|
||||
[2575]: https://github.com/Gallopsled/pwntools/pull/2575
|
||||
[2578]: https://github.com/Gallopsled/pwntools/pull/2578
|
||||
[2590]: https://github.com/Gallopsled/pwntools/pull/2590
|
||||
[2496]: https://github.com/Gallopsled/pwntools/pull/2496
|
||||
[2542]: https://github.com/Gallopsled/pwntools/pull/2542
|
||||
[2608]: https://github.com/Gallopsled/pwntools/pull/2608
|
||||
[2611]: https://github.com/Gallopsled/pwntools/pull/2611
|
||||
[2615]: https://github.com/Gallopsled/pwntools/pull/2615
|
||||
|
||||
## 4.14.0 (`beta`)
|
||||
## 4.15.1
|
||||
|
||||
- [#2694][2694] fix: pad bytes fields to correct field size in FileStructure
|
||||
- [#2701][2701] Fix `adb._build_date()` crash on devices with non-standard locale date strings
|
||||
- [#2721][2721] Allow running with Unicorn 2.1.[34] but throw when emulating MIPS
|
||||
- [#2773][2773] Disable debuginfod doctests in libcdb.unstrip_libc
|
||||
- [#2772][2772] fix(packing): `dd()` no longer crashes on a `bytearray` destination
|
||||
- [#2787][2787] gdb.corefile: Run gdb directly to prevent detach race
|
||||
- [#2795][2795] regsort: Fix self-assignment detection through register aliases
|
||||
- [#2524][2524] Raise EOFError during `process.recv` when stdout closes on Windows
|
||||
- [#2530][2530] Do NOT error when passing directory arguments in `checksec` commandline tool.
|
||||
- [#2506][2506] ROP: fix `ROP(ELF(exe)).leave` is `None` in some ELF
|
||||
- [#2592][2592] pwnlib.config: Fix customization of `context.timeout`
|
||||
- [#2598][2598] aarch64: Fix ABI definition
|
||||
- [#2610][2610] Fix `log.progress` ignoring `context.log_console`
|
||||
- [#2627][2627] Remove `pwnlib.util.iters.lookahead` (broken anyway, fails on Python 3.14+)
|
||||
- [#2653][2653] Add aarch64_be qemu mapping
|
||||
- [#2642][2642] Remove `pip` as explicit dependency
|
||||
- [#2646][2646] fix(libcdb-cli): return early if no matched libc found
|
||||
- [#2669][2669] asm: try native binutils before fallback architectures
|
||||
- [#2677][2677] refactor: replace unsafe eval with safeeval.const in ROP cache loading
|
||||
- [#2699][2699] Fix `tty` and `raw` arguments in `ssh.process()`
|
||||
- [#2688][2688] Close SSH client connection when authentication failed
|
||||
- [#2704][2704] ssh: Fix distro lookup on Ubuntu 24.04+
|
||||
- [#2762][2762] fix(srop): correct amd64 SigreturnFrame `uc_sigmask` offset
|
||||
- [#2767][2767] Support paginated libc.rip API requests to include all search results
|
||||
- [#2739][2739] shellcraft: migrate lazy importer to find_spec for Python 3.12+
|
||||
- [#2792][2792] Fix deprecation warning for not using `RLIM_INFINITY` in `resource.setrlimit` (Python 3.15)
|
||||
|
||||
[2694]: https://github.com/Gallopsled/pwntools/pull/2694
|
||||
[2701]: https://github.com/Gallopsled/pwntools/pull/2701
|
||||
[2721]: https://github.com/Gallopsled/pwntools/pull/2721
|
||||
[2773]: https://github.com/Gallopsled/pwntools/pull/2773
|
||||
[2772]: https://github.com/Gallopsled/pwntools/pull/2772
|
||||
[2787]: https://github.com/Gallopsled/pwntools/pull/2787
|
||||
[2795]: https://github.com/Gallopsled/pwntools/pull/2795
|
||||
[2524]: https://github.com/Gallopsled/pwntools/pull/2524
|
||||
[2530]: https://github.com/Gallopsled/pwntools/pull/2530
|
||||
[2506]: https://github.com/Gallopsled/pwntools/pull/2506
|
||||
[2592]: https://github.com/Gallopsled/pwntools/pull/2592
|
||||
[2598]: https://github.com/Gallopsled/pwntools/pull/2598
|
||||
[2610]: https://github.com/Gallopsled/pwntools/pull/2610
|
||||
[2627]: https://github.com/Gallopsled/pwntools/pull/2627
|
||||
[2653]: https://github.com/Gallopsled/pwntools/pull/2653
|
||||
[2642]: https://github.com/Gallopsled/pwntools/pull/2642
|
||||
[2646]: https://github.com/Gallopsled/pwntools/pull/2646
|
||||
[2669]: https://github.com/Gallopsled/pwntools/pull/2669
|
||||
[2677]: https://github.com/Gallopsled/pwntools/pull/2677
|
||||
[2699]: https://github.com/Gallopsled/pwntools/pull/2699
|
||||
[2688]: https://github.com/Gallopsled/pwntools/pull/2688
|
||||
[2704]: https://github.com/Gallopsled/pwntools/pull/2704
|
||||
[2762]: https://github.com/Gallopsled/pwntools/pull/2762
|
||||
[2767]: https://github.com/Gallopsled/pwntools/pull/2767
|
||||
[2739]: https://github.com/Gallopsled/pwntools/pull/2739
|
||||
[2792]: https://github.com/Gallopsled/pwntools/pull/2792
|
||||
|
||||
## 4.15.0 (`stable`)
|
||||
|
||||
- [#2508][2508] Ignore a warning when compiling with asm on nix
|
||||
- [#2471][2471] Properly close spawned kitty window
|
||||
- [#2358][2358] Cache output of `asm()`
|
||||
- [#2457][2457] Catch exception of non-ELF files in checksec.
|
||||
- [#2444][2444] Add `ELF.close()` to release resources
|
||||
- [#2413][2413] libcdb: improve the search speed of `search_by_symbol_offsets` in local libc-database
|
||||
- [#2470][2470] Fix waiting for gdb under WSL2
|
||||
- [#2479][2479] Support extracting libraries from Docker image in `pwn template`
|
||||
- [#2483][2483] Only print `checksec` output of `ELF.libc` when it was printed for the `ELF` already
|
||||
- [#2482][2482] Throw error when using `sni` and setting `server_hostname` manually in `remote`
|
||||
- [#2478][2478] libcdb-cli: add `--offline-only`, refactor unstrip and add fetch parser for download libc-database
|
||||
- [#2484][2484] Allow to disable caching
|
||||
- [#2291][2291] Fix attaching to a gdbserver with tuple `gdb.attach(('0.0.0.0',12345))`
|
||||
- [#2410][2410] Add `tube.upload_manually` to upload files in chunks
|
||||
- [#2502][2502] Fix loading ELF files without valid .dynamic section
|
||||
- [#2476][2476] Deprecate 'keepends' argument in favor of 'drop' in `tube.recvline*`
|
||||
- [#2364][2364] Deprecate direct commandline scripts invocation and exclude nonsense ones
|
||||
- [#2570][2570] Fix `pwn template` to skip Docker library extraction for statically linked binaries
|
||||
- [#2545][2545] SSH: fix download/upload with -1 exit status
|
||||
- [#2567][2567] Fix mistakenly parsing of ld-linux error messages.
|
||||
- [#2576][2576] regsort: respect register aliases
|
||||
- [#2595][2595] libcdb: Add Ubuntu and Debian debuginfod servers to default list
|
||||
- [#2593][2593] Use unicorn on macOS w/ SIP enabled
|
||||
- [#2587][2587] Support longer function names in Windows `getexport` shellcode
|
||||
- [#2596][2596] Ignore `colored_traceback` error when TERM envvar is unset
|
||||
- [#2579][2579] Fix poll error in `process.libs()` and clean up maps parsing
|
||||
- [#2602][2602] Allow setting debugger path via context.gdb_binary
|
||||
- [#2609][2609] Fix log level of child remotes of `server` tube
|
||||
- [#2612][2612] Fix lookup of binutils for `mipsel` architecture
|
||||
- [#2624][2624] Fix regression: gdbserver can't handle command-line argument containing whitespace
|
||||
|
||||
[2508]: https://github.com/Gallopsled/pwntools/pull/2508
|
||||
[2471]: https://github.com/Gallopsled/pwntools/pull/2471
|
||||
[2358]: https://github.com/Gallopsled/pwntools/pull/2358
|
||||
[2457]: https://github.com/Gallopsled/pwntools/pull/2457
|
||||
[2444]: https://github.com/Gallopsled/pwntools/pull/2444
|
||||
[2413]: https://github.com/Gallopsled/pwntools/pull/2413
|
||||
[2470]: https://github.com/Gallopsled/pwntools/pull/2470
|
||||
[2479]: https://github.com/Gallopsled/pwntools/pull/2479
|
||||
[2483]: https://github.com/Gallopsled/pwntools/pull/2483
|
||||
[2482]: https://github.com/Gallopsled/pwntools/pull/2482
|
||||
[2478]: https://github.com/Gallopsled/pwntools/pull/2478
|
||||
[2484]: https://github.com/Gallopsled/pwntools/pull/2484
|
||||
[2291]: https://github.com/Gallopsled/pwntools/pull/2291
|
||||
[2410]: https://github.com/Gallopsled/pwntools/pull/2410
|
||||
[2502]: https://github.com/Gallopsled/pwntools/pull/2502
|
||||
[2476]: https://github.com/Gallopsled/pwntools/pull/2476
|
||||
[2364]: https://github.com/Gallopsled/pwntools/pull/2364
|
||||
[2570]: https://github.com/Gallopsled/pwntools/pull/2570
|
||||
[2545]: https://github.com/Gallopsled/pwntools/pull/2545
|
||||
[2567]: https://github.com/Gallopsled/pwntools/pull/2567
|
||||
[2576]: https://github.com/Gallopsled/pwntools/pull/2576
|
||||
[2595]: https://github.com/Gallopsled/pwntools/pull/2595
|
||||
[2593]: https://github.com/Gallopsled/pwntools/pull/2593
|
||||
[2587]: https://github.com/Gallopsled/pwntools/pull/2587
|
||||
[2596]: https://github.com/Gallopsled/pwntools/pull/2596
|
||||
[2579]: https://github.com/Gallopsled/pwntools/pull/2579
|
||||
[2602]: https://github.com/Gallopsled/pwntools/pull/2602
|
||||
[2609]: https://github.com/Gallopsled/pwntools/pull/2609
|
||||
[2612]: https://github.com/Gallopsled/pwntools/pull/2612
|
||||
[2624]: https://github.com/Gallopsled/pwntools/pull/2624
|
||||
|
||||
## 4.14.1
|
||||
|
||||
- [#2451][2451] Show symbols defined to value 0 (start of file)
|
||||
- [#2533][2533] Fix installation on Python 3.5 and lower
|
||||
- [#2518][2518] fix: update apport coredump path handling for CorefileFinder
|
||||
- [#2552][2552] Fix memcpy shellcraft template off-by-one
|
||||
- [#2559][2559] Fix parsing corefile with missing auxv
|
||||
- [#2562][2562] Fix syntax highlighting of multiline comments in ASM
|
||||
- [#2565][2565] Exclude broken Unicorn
|
||||
|
||||
[2451]: https://github.com/Gallopsled/pwntools/pull/2451
|
||||
[2533]: https://github.com/Gallopsled/pwntools/pull/2533
|
||||
[2518]: https://github.com/Gallopsled/pwntools/pull/2518
|
||||
[2552]: https://github.com/Gallopsled/pwntools/pull/2552
|
||||
[2559]: https://github.com/Gallopsled/pwntools/pull/2559
|
||||
[2562]: https://github.com/Gallopsled/pwntools/pull/2562
|
||||
[2565]: https://github.com/Gallopsled/pwntools/pull/2565
|
||||
|
||||
## 4.14.0
|
||||
|
||||
- [#2356][2356] Add local libc database provider for libcdb
|
||||
- [#2360][2360] Add offline parameter for `search_by_hash` series function
|
||||
@@ -96,6 +277,7 @@ The table below shows which release corresponds to each branch, and what date th
|
||||
- [#2382][2382] added optional port, gdb_args and gdbserver_args parameters to gdb.debug()
|
||||
- [#2435][2435] Speed up gdbserver handshake in gdb.debug()
|
||||
- [#2436][2436] Add resolution_addr parameter to Ret2dlresolvePayload
|
||||
- [#2497][2497] Fix remote.fromsocket() to handle AF_INET6 socket
|
||||
|
||||
[2436]: https://github.com/Gallopsled/pwntools/pull/2436
|
||||
[2371]: https://github.com/Gallopsled/pwntools/pull/2371
|
||||
@@ -117,8 +299,22 @@ The table below shows which release corresponds to each branch, and what date th
|
||||
[2382]: https://github.com/Gallopsled/pwntools/pull/2382
|
||||
[2435]: https://github.com/Gallopsled/pwntools/pull/2435
|
||||
[2437]: https://github.com/Gallopsled/pwntools/pull/2437
|
||||
[2497]: https://github.com/Gallopsled/pwntools/pull/2497
|
||||
|
||||
## 4.13.0 (`stable`)
|
||||
## 4.13.1
|
||||
|
||||
- [#2445][2445] Fix parsing the PLT on Windows
|
||||
- [#2466][2466] Fix PLT emulation with Unicorn 2.1.0
|
||||
- [#2466][2466] Switch to PyPi Simple API for update checks
|
||||
- [#2467][2467] Fix loading at all on Windows
|
||||
- [#2469][2469] GDB 15+ rpyc detection
|
||||
|
||||
[2445]: https://github.com/Gallopsled/pwntools/pull/2445
|
||||
[2466]: https://github.com/Gallopsled/pwntools/pull/2466
|
||||
[2467]: https://github.com/Gallopsled/pwntools/pull/2467
|
||||
[2469]: https://github.com/Gallopsled/pwntools/pull/2469
|
||||
|
||||
## 4.13.0
|
||||
|
||||
- [#2242][2242] Term module revamp: activating special handling of terminal only when necessary
|
||||
- [#2277][2277] elf: Resolve more relocations into GOT entries
|
||||
@@ -130,7 +326,7 @@ The table below shows which release corresponds to each branch, and what date th
|
||||
- [#2308][2308] Fix WinExec shellcraft to make sure it's 16 byte aligned
|
||||
- [#2279][2279] Make `pwn template` always set context.binary
|
||||
- [#2310][2310] Add support to start a process on Windows
|
||||
- [#2335][2335] Add lookup optimizations in DynELF
|
||||
- [#2335][2335] Add lookup optimizations in DynELF
|
||||
- [#2334][2334] Speed up disasm commandline tool with colored output
|
||||
- [#2328][2328] Lookup using $PATHEXT file extensions in `which` on Windows
|
||||
- [#2189][2189] Explicitly define p64/u64 functions for IDE support
|
||||
@@ -217,7 +413,7 @@ The table below shows which release corresponds to each branch, and what date th
|
||||
|
||||
## 4.11.0
|
||||
|
||||
- [#2185][2185] make fmtstr module able to create payload without $ notation
|
||||
- [#2185][2185] make fmtstr module able to create payload without $ notation
|
||||
- [#2103][2103] Add search for libc binary by leaked function addresses `libcdb.search_by_symbol_offsets()`
|
||||
- [#2177][2177] Support for RISC-V 64-bit architecture
|
||||
- [#2186][2186] Enhance `ELF.nx` and `ELF.execstack`
|
||||
@@ -492,7 +688,7 @@ In memoriam — [Zach Riggle][zach] — long time contributor and maintainer of
|
||||
[fecf9f]: http://github.com/Gallopsled/pwntools/commit/fecf9f
|
||||
[1454]: https://github.com/Gallopsled/pwntools/pull/1454
|
||||
|
||||
## 4.1.7 (`stable`)
|
||||
## 4.1.7
|
||||
|
||||
- [#1615][1615] Fix aarch64 pushstr and pushstr_array
|
||||
|
||||
|
||||
@@ -32,13 +32,13 @@ To get you started, we've provided some example solutions for past CTF challenge
|
||||
|
||||
# Installation
|
||||
|
||||
Pwntools is best supported on 64-bit Ubuntu LTS releases (14.04, 16.04, 18.04, and 20.04). Most functionality should work on any Posix-like distribution (Debian, Arch, FreeBSD, OSX, etc.).
|
||||
Pwntools is best supported on 64-bit Ubuntu LTS releases (18.04, 20.04, 22.04, and 24.04). Most functionality should work on any Posix-like distribution (Debian, Arch, FreeBSD, OSX, etc.).
|
||||
|
||||
Python3 is suggested, but Pwntools still works with Python 2.7. Most of the functionality of pwntools is self-contained and Python-only. You should be able to get running quickly with
|
||||
|
||||
```sh
|
||||
apt-get update
|
||||
apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
|
||||
sudo apt-get update
|
||||
sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install --upgrade pwntools
|
||||
```
|
||||
|
||||
@@ -2,13 +2,14 @@ capstone
|
||||
coverage[toml]
|
||||
python-dateutil
|
||||
doc2dash
|
||||
docutils<0.18
|
||||
docutils<0.18; python_version<'3'
|
||||
docutils>=0.18; python_version>='3'
|
||||
intervaltree
|
||||
isort
|
||||
mako>=1.0.0
|
||||
paramiko>=1.15.2
|
||||
pip>=6.0.8
|
||||
pyelftools>=0.2.3
|
||||
pyelftools>=0.29, <0.30; python_version<'3'
|
||||
pyelftools>=0.29; python_version>='3'
|
||||
pygments>=2.0
|
||||
pypandoc
|
||||
pyserial>=2.7
|
||||
@@ -17,6 +18,6 @@ psutil
|
||||
requests>=2.5.1
|
||||
ropgadget>=5.3
|
||||
sphinx==1.8.6; python_version<'3'
|
||||
sphinx>=4.5.0; python_version>='3'
|
||||
sphinx>=8.1.3, <9; python_version>='3'
|
||||
sphinx_rtd_theme
|
||||
sphinxcontrib-autoprogram<=0.1.5
|
||||
@@ -360,6 +360,9 @@ def linkcode_resolve(domain, info):
|
||||
else:
|
||||
filename = info['module'].replace('.', '/') + '.py'
|
||||
|
||||
if isinstance(val, property):
|
||||
val = val.fget
|
||||
|
||||
if isinstance(val, (types.ModuleType, types.MethodType, types.FunctionType, types.TracebackType, types.FrameType, types.CodeType) + six.class_types):
|
||||
try:
|
||||
lines, first = inspect.getsourcelines(val)
|
||||
|
||||
@@ -77,6 +77,7 @@ Each of the ``pwntools`` modules is documented here.
|
||||
update
|
||||
useragents
|
||||
util/*
|
||||
windbg
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
@@ -15,6 +15,9 @@ following system libraries installed.
|
||||
|
||||
install/*
|
||||
|
||||
|
||||
Note: For Mac OS X you will need to have cmake ``brew install cmake`` and pkg-config ``brew install pkg-config`` installed.
|
||||
|
||||
Released Version
|
||||
-----------------
|
||||
|
||||
@@ -25,8 +28,8 @@ Python3
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ apt-get update
|
||||
$ apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
|
||||
$ python3 -m pip install --upgrade pip
|
||||
$ python3 -m pip install --upgrade pwntools
|
||||
|
||||
@@ -40,8 +43,8 @@ Additionally, due to `pip` dropping support for Python2, a specfic version of `p
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ apt-get update
|
||||
$ apt-get install python python-pip python-dev git libssl-dev libffi-dev build-essential
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install python python-pip python-dev git libssl-dev libffi-dev build-essential
|
||||
$ python2 -m pip install --upgrade pip==20.3.4
|
||||
$ python2 -m pip install --upgrade pwntools
|
||||
|
||||
|
||||
@@ -18,28 +18,35 @@ Ubuntu Xenial (16.04) has official packages for most architectures, and does not
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ apt-get install software-properties-common
|
||||
$ apt-add-repository ppa:pwntools/binutils
|
||||
$ apt-get update
|
||||
$ sudo apt-get install software-properties-common
|
||||
$ sudo apt-add-repository ppa:pwntools/binutils
|
||||
$ sudo apt-get update
|
||||
|
||||
Then, install the binutils for your architecture.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ apt-get install binutils-$ARCH-linux-gnu
|
||||
$ sudo apt-get install binutils-$ARCH-linux-gnu
|
||||
|
||||
Mac OS X
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Mac OS X is just as easy, but requires building binutils from source.
|
||||
However, we've made ``homebrew`` recipes to make this a single command.
|
||||
However, we've made ``homebrew`` recipes to make this just two commands.
|
||||
After installing `brew <https://brew.sh>`__, grab the appropriate
|
||||
recipe from our `binutils
|
||||
repo <https://github.com/Gallopsled/pwntools-binutils/>`__.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ brew install https://raw.githubusercontent.com/Gallopsled/pwntools-binutils/master/macos/binutils-$ARCH.rb
|
||||
$ wget https://raw.githubusercontent.com/Gallopsled/pwntools-binutils/master/macos/binutils-$ARCH.rb
|
||||
$ brew install ./binutils-$ARCH.rb
|
||||
|
||||
Windows
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Windows support is experimental. You can try installing a prebuilt version of binutils
|
||||
for your desired architecture from the `GNU Toolchains <https://gnutoolchains.com/>`__ project.
|
||||
|
||||
Alternate OSes
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -10,7 +10,7 @@ Ubuntu
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ apt-get install python-dev
|
||||
$ sudo apt-get install python-dev
|
||||
|
||||
Mac OS X
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -34,6 +34,8 @@ This exposes a standard interface to talk to processes, sockets, serial ports,
|
||||
and all manner of things, along with some nifty helpers for common tasks.
|
||||
For example, remote connections via :mod:`pwnlib.tubes.remote`.
|
||||
|
||||
::
|
||||
|
||||
>>> conn = remote('ftp.ubuntu.com',21)
|
||||
>>> conn.recvline() # doctest: +ELLIPSIS
|
||||
b'220 ...'
|
||||
|
||||
@@ -1 +1,10 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
|
||||
|
||||
:mod:`pwnlib.protocols.adb` --- Protocol implementations
|
||||
========================================================
|
||||
|
||||
.. automodule:: pwnlib.protocols.adb
|
||||
:members:
|
||||
@@ -0,0 +1,19 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
context.clear(arch='riscv64')
|
||||
|
||||
:mod:`pwnlib.shellcraft.riscv64` --- Shellcode for RISCV64
|
||||
==========================================================
|
||||
|
||||
:mod:`pwnlib.shellcraft.riscv64`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: pwnlib.shellcraft.riscv64
|
||||
:members:
|
||||
|
||||
:mod:`pwnlib.shellcraft.riscv64.linux`
|
||||
--------------------------------------
|
||||
|
||||
.. automodule:: pwnlib.shellcraft.riscv64.linux
|
||||
:members:
|
||||
@@ -0,0 +1,9 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
|
||||
:mod:`pwnlib.windbg` --- Working with WinDbg
|
||||
============================================
|
||||
|
||||
.. automodule:: pwnlib.windbg
|
||||
:members:
|
||||
@@ -32,18 +32,20 @@ RUN apt-get update \
|
||||
binutils-aarch64-linux-gnu \
|
||||
binutils-mips-linux-gnu \
|
||||
binutils-mipsel-linux-gnu \
|
||||
binutils-msp430 \
|
||||
binutils-powerpc-linux-gnu \
|
||||
binutils-powerpc64-linux-gnu \
|
||||
binutils-s390x-linux-gnu \
|
||||
binutils-sparc64-linux-gnu \
|
||||
binutils-riscv64-linux-gnu \
|
||||
tmux \
|
||||
patchelf \
|
||||
&& locale-gen en_US.UTF-8 \
|
||||
&& update-locale LANG=en_US.UTF-8 \
|
||||
&& PYTHONPATH=`echo /usr/share/python-wheels/pip-*.whl` python2.7 -m pip install --upgrade pip setuptools wheel \
|
||||
&& python2.7 -m pip install --upgrade pwntools \
|
||||
&& python3 -m pip install --upgrade pip \
|
||||
&& python3 -m pip install --upgrade pwntools \
|
||||
&& PYTHONPATH=`echo /usr/share/python-wheels/pip-*.whl` python2.7 -m pip install --no-cache-dir --upgrade pip setuptools wheel \
|
||||
&& python2.7 -m pip install --no-cache-dir --upgrade pwntools \
|
||||
&& python3 -m pip install --no-cache-dir --upgrade pip \
|
||||
&& python3 -m pip install --no-cache-dir --upgrade pwntools \
|
||||
&& PWNLIB_NOTERM=1 pwn update \
|
||||
&& useradd -m pwntools \
|
||||
&& passwd --delete --unlock pwntools \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM pwntools/pwntools:stable
|
||||
|
||||
USER root
|
||||
RUN python2.7 -m pip install --upgrade git+https://github.com/Gallopsled/pwntools@beta \
|
||||
&& python3 -m pip install --force-reinstall --upgrade git+https://github.com/Gallopsled/pwntools@beta
|
||||
RUN python2.7 -m pip install --no-cache-dir --upgrade git+https://github.com/Gallopsled/pwntools@beta \
|
||||
&& python3 -m pip install --no-cache-dir --force-reinstall --upgrade git+https://github.com/Gallopsled/pwntools@beta
|
||||
RUN PWNLIB_NOTERM=1 pwn update
|
||||
USER pwntools
|
||||
@@ -5,4 +5,4 @@ RUN apt-get -y dist-upgrade
|
||||
RUN apt-get -y install python3 python3-pip
|
||||
RUN apt-get -y install git wget unzip
|
||||
|
||||
RUN pip3 install --upgrade git+https://github.com/Gallopsled/pwntools@dev
|
||||
RUN pip3 install --no-cache-dir --upgrade git+https://github.com/Gallopsled/pwntools@dev
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM pwntools/pwntools:base
|
||||
|
||||
USER root
|
||||
RUN python2.7 -m pip install --upgrade git+https://github.com/Gallopsled/pwntools@stable \
|
||||
&& python3 -m pip install --force-reinstall --upgrade git+https://github.com/Gallopsled/pwntools@stable
|
||||
RUN python2.7 -m pip install --no-cache-dir --upgrade git+https://github.com/Gallopsled/pwntools@stable \
|
||||
&& python3 -m pip install --no-cache-dir --force-reinstall --upgrade git+https://github.com/Gallopsled/pwntools@stable
|
||||
RUN PWNLIB_NOTERM=1 pwn update
|
||||
USER pwntools
|
||||
+9
-1
@@ -89,7 +89,15 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
colored_traceback.add_hook()
|
||||
try:
|
||||
colored_traceback.add_hook()
|
||||
except Exception:
|
||||
# Exception: curses.error
|
||||
# colored_traceback (curses.setupterm()) fails if TERM is unset.
|
||||
# This is not critical, so we just ignore it.
|
||||
# We cannot import `curses` for `curses.error` because it is not
|
||||
# available on all platforms (e.g. Windows).
|
||||
pass
|
||||
|
||||
# Equivalence with the default behavior of "from import *"
|
||||
# __all__ = [x for x in tuple(globals()) if not x.startswith('_')]
|
||||
@@ -36,6 +36,7 @@ __all__ = [
|
||||
'util',
|
||||
'update',
|
||||
'version',
|
||||
'windbg',
|
||||
]
|
||||
|
||||
from . import args
|
||||
+1
-1
@@ -142,7 +142,7 @@ class SigreturnABI(SyscallABI):
|
||||
linux_i386 = ABI('esp', [], 4, 0)
|
||||
linux_amd64 = ABI('rsp', ['rdi','rsi','rdx','rcx','r8','r9'], 8, 0)
|
||||
linux_arm = ABI('sp', ['r0', 'r1', 'r2', 'r3'], 8, 0)
|
||||
linux_aarch64 = ABI('sp', ['x0', 'x1', 'x2', 'x3'], 16, 0)
|
||||
linux_aarch64 = ABI('sp', ['x0', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7'], 16, 0)
|
||||
linux_mips = ABI('$sp', ['$a0','$a1','$a2','$a3'], 4, 0)
|
||||
linux_ppc = ABI('sp', ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10'], 4, 0)
|
||||
linux_ppc64 = ABI('sp', ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10'], 8, 0)
|
||||
|
||||
+26
-6
@@ -123,7 +123,7 @@ def current_device(any=False):
|
||||
|
||||
>>> device = adb.current_device(any=True)
|
||||
>>> device # doctest: +ELLIPSIS
|
||||
AdbDevice(serial='emulator-5554', type='device', port='emulator', product='sdk_...phone_...', model='...', device='generic...')
|
||||
AdbDevice(serial='emulator-5554', type='device', port='emulator', product='sdk_...phone..._...', model='...', device='...')
|
||||
>>> device.port
|
||||
'emulator'
|
||||
"""
|
||||
@@ -259,7 +259,7 @@ class AdbDevice(Device):
|
||||
>>> device.os
|
||||
'android'
|
||||
>>> device.product # doctest: +ELLIPSIS
|
||||
'sdk_...phone_...'
|
||||
'sdk_...phone..._...'
|
||||
>>> device.serial
|
||||
'emulator-5554'
|
||||
"""
|
||||
@@ -880,7 +880,7 @@ def which(name, all = False, *a, **kw):
|
||||
>>> adb.which('sh')
|
||||
'/system/bin/sh'
|
||||
>>> adb.which('sh', all=True)
|
||||
['/system/bin/sh']
|
||||
['/system/bin/sh', '/vendor/bin/sh']
|
||||
|
||||
>>> adb.which('foobar') is None
|
||||
True
|
||||
@@ -988,7 +988,7 @@ def proc_exe(pid):
|
||||
:skipif: skip_android
|
||||
|
||||
>>> adb.proc_exe(1)
|
||||
b'/init'
|
||||
b'/system/bin/init'
|
||||
"""
|
||||
with context.quiet:
|
||||
io = process(['realpath','/proc/%d/exe' % pid])
|
||||
@@ -1275,8 +1275,28 @@ properties = Property()
|
||||
|
||||
def _build_date():
|
||||
"""Returns the build date in the form YYYY-MM-DD as a string"""
|
||||
import datetime
|
||||
|
||||
# Use ro.build.date.utc (integer epoch seconds) which is set by the
|
||||
# AOSP build system and available on all standard Android devices.
|
||||
# This avoids ro.build.date which is locale-dependent and can contain
|
||||
# non-ASCII characters that dateutil cannot parse. See #2513.
|
||||
utc = getprop('ro.build.date.utc')
|
||||
if utc and utc.strip().isdigit():
|
||||
try:
|
||||
as_datetime = datetime.datetime.fromtimestamp(int(utc.strip()), dateutil.tz.UTC)
|
||||
return as_datetime.strftime('%Y-%b-%d')
|
||||
except (OSError, OverflowError, ValueError):
|
||||
pass
|
||||
|
||||
# Fallback for non-standard builds missing ro.build.date.utc.
|
||||
as_string = getprop('ro.build.date')
|
||||
as_datetime = dateutil.parser.parse(as_string)
|
||||
if not as_string:
|
||||
return ''
|
||||
try:
|
||||
as_datetime = dateutil.parser.parse(as_string)
|
||||
except (ValueError, OverflowError):
|
||||
return as_string
|
||||
return as_datetime.strftime('%Y-%b-%d')
|
||||
|
||||
def find_ndk_project_root(source):
|
||||
@@ -1365,7 +1385,7 @@ def compile(source):
|
||||
>>> filename = adb.compile(temp)
|
||||
>>> sent = adb.push(filename, "/data/local/tmp")
|
||||
>>> adb.process(sent).recvall() # doctest: +ELLIPSIS
|
||||
b'... /system/lib64/libc.so\n...'
|
||||
b'... /system/lib64/libc++.so\n...'
|
||||
"""
|
||||
|
||||
ndk_build = misc.which('ndk-build')
|
||||
|
||||
@@ -159,6 +159,11 @@ def STDERR(v):
|
||||
"""Sends logging to ``stderr`` by default, instead of ``stdout``"""
|
||||
context.log_console = sys.stderr
|
||||
|
||||
def LOCAL_LIBCDB(v):
|
||||
"""Sets path to local libc-database via ``context.local_libcdb``, e.g.
|
||||
``LOCAL_LIBCDB='/path/to/libc-databse'``"""
|
||||
context.local_libcdb = v
|
||||
|
||||
hooks = {
|
||||
'LOG_LEVEL': LOG_LEVEL,
|
||||
'LOG_FILE': LOG_FILE,
|
||||
@@ -170,6 +175,7 @@ hooks = {
|
||||
'NOASLR': NOASLR,
|
||||
'NOPTRACE': NOPTRACE,
|
||||
'STDERR': STDERR,
|
||||
'LOCAL_LIBCDB': LOCAL_LIBCDB,
|
||||
}
|
||||
|
||||
def initialize():
|
||||
|
||||
+92
-16
@@ -59,6 +59,9 @@ from pwnlib import shellcraft
|
||||
from pwnlib.context import LocalContext
|
||||
from pwnlib.context import context
|
||||
from pwnlib.log import getLogger
|
||||
from pwnlib.util.hashes import sha1sumhex
|
||||
from pwnlib.util.packing import _encode
|
||||
from pwnlib.version import __version__
|
||||
|
||||
log = getLogger(__name__)
|
||||
|
||||
@@ -167,6 +170,8 @@ def which_binutils(util, check_version=False):
|
||||
'.../bin/arm-...-as'
|
||||
>>> which_binutils('as', arch='powerpc') #doctest: +ELLIPSIS
|
||||
'.../bin/powerpc...-as'
|
||||
>>> which_binutils('as', arch='mips', endianness='little') #doctest: +ELLIPSIS
|
||||
'.../bin/mipsel...-as'
|
||||
>>> which_binutils('as', arch='msp430') #doctest: +SKIP
|
||||
...
|
||||
Traceback (most recent call last):
|
||||
@@ -175,28 +180,44 @@ def which_binutils(util, check_version=False):
|
||||
"""
|
||||
arch = context.arch
|
||||
|
||||
# Handle endianness-specific naming for mips/mips64
|
||||
arch = {
|
||||
('mips', 'little'): 'mipsel',
|
||||
('mips64', 'little'): 'mips64el',
|
||||
}.get((arch, context.endianness), arch)
|
||||
|
||||
# Fix up pwntools vs Debian triplet naming, and account
|
||||
# for 'thumb' being its own pwntools architecture.
|
||||
arches = [arch] + {
|
||||
aliases = {
|
||||
'thumb': ['arm', 'aarch64'],
|
||||
'i386': ['x86_64', 'amd64'],
|
||||
'i686': ['x86_64', 'amd64'],
|
||||
'amd64': ['x86_64', 'i386'],
|
||||
'mips64': ['mips'],
|
||||
'powerpc64': ['powerpc'],
|
||||
'sparc64': ['sparc'],
|
||||
'riscv32': ['riscv32', 'riscv64', 'riscv'],
|
||||
'riscv64': ['riscv64', 'riscv32', 'riscv'],
|
||||
'amd64': ['x86_64'],
|
||||
}.get(arch, [])
|
||||
|
||||
# Some binutils can support multiple architectures. Try them as fallbacks.
|
||||
fallback_arches = {
|
||||
'i386': ['x86_64', 'amd64'],
|
||||
'amd64': ['i386'],
|
||||
'arm': ['aarch64'],
|
||||
'mips': ['mipsel'],
|
||||
'mipsel': ['mips'],
|
||||
'mips64': ['mips64el', 'mips', 'mipsel'],
|
||||
'mips64el': ['mips64', 'mipsel', 'mips'],
|
||||
'powerpc64': ['powerpc'],
|
||||
'sparc64': ['sparc'],
|
||||
'riscv32': ['riscv64', 'riscv'],
|
||||
'riscv64': ['riscv32', 'riscv'],
|
||||
}.get(arch, [])
|
||||
arches = [arch] + aliases + fallback_arches
|
||||
|
||||
# If one of the candidate architectures matches the native
|
||||
# architecture, use that as a last resort.
|
||||
# architecture, use that as a last resort before trying fallbacks.
|
||||
machine = platform.machine()
|
||||
machine = 'i386' if machine == 'i686' else machine
|
||||
try:
|
||||
with context.local(arch = machine):
|
||||
if context.arch in arches:
|
||||
arches.append(None)
|
||||
arches = [arch] + aliases + [None] + fallback_arches
|
||||
except AttributeError:
|
||||
log.warn_once("Your local binutils won't be used because architecture %r is not supported." % machine)
|
||||
|
||||
@@ -206,6 +227,11 @@ def which_binutils(util, check_version=False):
|
||||
if platform.system() == 'Darwin':
|
||||
utils = ['g'+util, util]
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
utils = [util + '.exe']
|
||||
|
||||
# Try the explicit tools for the target architecture first,
|
||||
# then the native one optionally, then fallbacks.
|
||||
for arch in arches:
|
||||
for gutil in utils:
|
||||
# e.g. objdump
|
||||
@@ -220,7 +246,7 @@ def which_binutils(util, check_version=False):
|
||||
'%s-%s' % (arch, gutil)]
|
||||
|
||||
for pattern in patterns:
|
||||
for dir in environ['PATH'].split(':'):
|
||||
for dir in environ['PATH'].split(os.pathsep):
|
||||
for res in sorted(glob(path.join(dir, pattern))):
|
||||
if check_version:
|
||||
ver = check_binutils_version(res)
|
||||
@@ -457,15 +483,20 @@ def cpp(shellcode):
|
||||
>>> cpp("SYS_setresuid", os = "freebsd")
|
||||
'311\n'
|
||||
"""
|
||||
if platform.system() == 'Windows':
|
||||
cpp = which_binutils('cpp')
|
||||
else:
|
||||
cpp = 'cpp'
|
||||
|
||||
code = _include_header() + shellcode
|
||||
cmd = [
|
||||
'cpp',
|
||||
cpp,
|
||||
'-Wno-unused-command-line-argument',
|
||||
'-C',
|
||||
'-nostdinc',
|
||||
'-undef',
|
||||
'-P',
|
||||
'-I' + _incdir,
|
||||
'/dev/stdin'
|
||||
]
|
||||
return _run(cmd, code).strip('\n').rstrip() + '\n'
|
||||
|
||||
@@ -751,8 +782,23 @@ def asm(shellcode, vma = 0, extract = True, shared = False):
|
||||
b'0@*\x00'
|
||||
>>> asm("la %r0, 42", arch = 's390', bits=64)
|
||||
b'A\x00\x00*'
|
||||
|
||||
The output is cached:
|
||||
|
||||
>>> start = time.time()
|
||||
>>> asm("lea rax, [rip+0]", arch = 'amd64', cache_dir = None) # force uncached time
|
||||
b'H\x8d\x05\x00\x00\x00\x00'
|
||||
>>> uncached_time = time.time() - start
|
||||
>>> asm("lea rax, [rip+0]", arch = 'amd64') # cache it
|
||||
b'H\x8d\x05\x00\x00\x00\x00'
|
||||
>>> start = time.time()
|
||||
>>> asm("lea rax, [rip+0]", arch = 'amd64')
|
||||
b'H\x8d\x05\x00\x00\x00\x00'
|
||||
>>> cached_time = time.time() - start
|
||||
>>> uncached_time > cached_time
|
||||
True
|
||||
"""
|
||||
result = ''
|
||||
result = b''
|
||||
|
||||
assembler = _assembler()
|
||||
linker = _linker()
|
||||
@@ -763,6 +809,30 @@ def asm(shellcode, vma = 0, extract = True, shared = False):
|
||||
|
||||
log.debug('Assembling\n%s' % code)
|
||||
|
||||
cache_file = None
|
||||
if context.cache_dir:
|
||||
cache_dir = os.path.join(context.cache_dir, 'asm-cache')
|
||||
if not os.path.isdir(cache_dir):
|
||||
os.makedirs(cache_dir)
|
||||
|
||||
# Include the context in the hash in addition to the shellcode
|
||||
hash_params = '{}_{}_{}_{}'.format(vma, extract, shared, __version__)
|
||||
fingerprint_params = _encode(code) + _encode(hash_params) + _encode(' '.join(assembler)) + _encode(' '.join(linker)) + _encode(' '.join(objcopy))
|
||||
asm_hash = sha1sumhex(fingerprint_params)
|
||||
cache_file = os.path.join(cache_dir, asm_hash)
|
||||
if os.path.exists(cache_file):
|
||||
log.debug('Using cached assembly output from %r', cache_file)
|
||||
if extract:
|
||||
with open(cache_file, 'rb') as f:
|
||||
return f.read()
|
||||
|
||||
# Create a temporary copy of the cached file to avoid modification.
|
||||
tmpdir = tempfile.mkdtemp(prefix = 'pwn-asm-')
|
||||
atexit.register(shutil.rmtree, tmpdir)
|
||||
step3 = os.path.join(tmpdir, 'step3')
|
||||
shutil.copy(cache_file, step3)
|
||||
return step3
|
||||
|
||||
tmpdir = tempfile.mkdtemp(prefix = 'pwn-asm-')
|
||||
step1 = path.join(tmpdir, 'step1')
|
||||
step2 = path.join(tmpdir, 'step2')
|
||||
@@ -810,6 +880,8 @@ def asm(shellcode, vma = 0, extract = True, shared = False):
|
||||
shutil.copy(step2, step3)
|
||||
|
||||
if not extract:
|
||||
if cache_file is not None:
|
||||
shutil.copy(step3, cache_file)
|
||||
return step3
|
||||
|
||||
_run(objcopy + [step3, step4])
|
||||
@@ -823,6 +895,10 @@ def asm(shellcode, vma = 0, extract = True, shared = False):
|
||||
else:
|
||||
atexit.register(lambda: shutil.rmtree(tmpdir))
|
||||
|
||||
if cache_file is not None and result != b'':
|
||||
with open(cache_file, 'wb') as f:
|
||||
f.write(result)
|
||||
|
||||
return result
|
||||
|
||||
@LocalContext
|
||||
@@ -855,8 +931,8 @@ def disasm(data, vma = 0, byte = True, offset = True, instructions = True):
|
||||
0: b8 17 00 00 00 mov eax, 0x17
|
||||
>>> print(disasm(unhex('48c7c017000000'), arch = 'amd64'))
|
||||
0: 48 c7 c0 17 00 00 00 mov rax, 0x17
|
||||
>>> print(disasm(unhex('04001fe552009000'), arch = 'arm'))
|
||||
0: e51f0004 ldr r0, [pc, #-4] ; 0x4
|
||||
>>> print(disasm(unhex('04001fe552009000'), arch = 'arm')) # doctest: +ELLIPSIS
|
||||
0: e51f0004 ldr r0, [pc, #-4] ...
|
||||
4: 00900052 addseq r0, r0, r2, asr r0
|
||||
>>> print(disasm(unhex('4ff00500'), arch = 'thumb', bits=32))
|
||||
0: f04f 0005 mov.w r0, #5
|
||||
|
||||
@@ -137,4 +137,4 @@ def main(args):
|
||||
args.output.write(b'\n')
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -4,7 +4,7 @@ from __future__ import division
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from pwnlib.elf import ELF
|
||||
from pwn import *
|
||||
from pwnlib.commandline import common
|
||||
|
||||
parser = common.parser_commands.add_parser(
|
||||
@@ -15,7 +15,6 @@ parser = common.parser_commands.add_parser(
|
||||
parser.add_argument(
|
||||
'elf',
|
||||
nargs='*',
|
||||
type=argparse.FileType('rb'),
|
||||
help='Files to check'
|
||||
)
|
||||
parser.add_argument(
|
||||
@@ -23,19 +22,21 @@ parser.add_argument(
|
||||
nargs='*',
|
||||
dest='elf2',
|
||||
metavar='elf',
|
||||
type=argparse.FileType('rb'),
|
||||
help='File to check (for compatibility with checksec.sh)'
|
||||
)
|
||||
|
||||
def main(args):
|
||||
files = args.elf or args.elf2 or []
|
||||
files = args.elf or args.elf2 or []
|
||||
|
||||
if not files:
|
||||
parser.print_usage()
|
||||
return
|
||||
|
||||
for f in files:
|
||||
e = ELF(f.name)
|
||||
try:
|
||||
e = ELF(f)
|
||||
except Exception as e:
|
||||
print("{name}: {error}".format(name=f, error=e))
|
||||
|
||||
if __name__ == '__main__':
|
||||
common.main(__file__)
|
||||
common.main(__file__, main)
|
||||
@@ -25,8 +25,25 @@ parser = argparse.ArgumentParser(description='Pwntools Command-line Interface',
|
||||
prog='pwn')
|
||||
parser_commands = parser.add_subparsers(dest='command')
|
||||
|
||||
def main(file=sys.argv[0]):
|
||||
import pwnlib.commandline.main
|
||||
def main(file=sys.argv[0], command_main=None):
|
||||
name = os.path.splitext(os.path.basename(file))[0]
|
||||
if command_main is None:
|
||||
import importlib
|
||||
command_main = importlib.import_module('pwnlib.commandline.%s' % name).main
|
||||
sys.argv.insert(1, name)
|
||||
pwnlib.commandline.main.main()
|
||||
entrypoint({name: command_main})
|
||||
|
||||
def deprecated_main():
|
||||
file=sys.argv[0]
|
||||
name = os.path.splitext(os.path.basename(file))[0]
|
||||
import warnings
|
||||
warnings.warn("The '%s' command is deprecated and will be removed in a future version. Please use 'pwn %s' instead." % (name, name), DeprecationWarning, stacklevel=2)
|
||||
main(file)
|
||||
|
||||
def entrypoint(commands):
|
||||
if len(sys.argv) < 2:
|
||||
parser.print_usage()
|
||||
sys.exit()
|
||||
args = parser.parse_args()
|
||||
with context.local(log_console = sys.stderr):
|
||||
commands[args.command](args)
|
||||
@@ -133,4 +133,4 @@ def main(args):
|
||||
print('(%s) == %s' % (' | '.join(k for v, k in good), args.constant))
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -107,4 +107,4 @@ def main(args):
|
||||
out.write(b'\n')
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -102,4 +102,4 @@ def main(args):
|
||||
gdb.debug(target, gdbscript=gdbscript, sysroot=args.sysroot).interactive()
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -24,4 +24,4 @@ def main(args):
|
||||
ELF(e.path)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -110,4 +110,4 @@ def main(args):
|
||||
print(disasm(dat, vma=safeeval.const(args.address)))
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -59,4 +59,4 @@ def main(a):
|
||||
print(diff(x, y))
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -34,4 +34,4 @@ def main(a):
|
||||
getattr(sys.stdout, 'buffer', sys.stdout).write(elf.get_data())
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -46,4 +46,4 @@ def main(args):
|
||||
print(os.strerror(value))
|
||||
|
||||
if __name__ == '__main__':
|
||||
common.main(__file__)
|
||||
common.main(__file__, main)
|
||||
@@ -50,4 +50,4 @@ def main(args):
|
||||
print(encoded)
|
||||
|
||||
if __name__ == '__main__':
|
||||
common.main(__file__)
|
||||
common.main(__file__, main)
|
||||
+111
-68
@@ -37,19 +37,12 @@ lookup_parser.add_argument(
|
||||
)
|
||||
|
||||
lookup_parser.add_argument(
|
||||
'--download-libc',
|
||||
'-d', '--download-libc',
|
||||
action = 'store_true',
|
||||
default = False,
|
||||
help = 'Attempt to download the matching libc.so'
|
||||
)
|
||||
|
||||
lookup_parser.add_argument(
|
||||
'--unstrip',
|
||||
action = 'store_true',
|
||||
default = True,
|
||||
help = 'Attempt to unstrip the libc binary with debug symbols from a debuginfod server'
|
||||
)
|
||||
|
||||
lookup_parser.add_argument(
|
||||
'--no-unstrip',
|
||||
action = 'store_false',
|
||||
@@ -57,6 +50,14 @@ lookup_parser.add_argument(
|
||||
help = 'Do NOT attempt to unstrip the libc binary with debug symbols from a debuginfod server'
|
||||
)
|
||||
|
||||
lookup_parser.add_argument(
|
||||
'--offline-only',
|
||||
action = 'store_true',
|
||||
default = False,
|
||||
dest = 'offline_only',
|
||||
help = 'Attempt to searching with offline only mode'
|
||||
)
|
||||
|
||||
hash_parser = libc_commands.add_parser(
|
||||
'hash',
|
||||
help = 'Display information of a libc version given an unique hash',
|
||||
@@ -80,19 +81,12 @@ hash_parser.add_argument(
|
||||
)
|
||||
|
||||
hash_parser.add_argument(
|
||||
'--download-libc',
|
||||
'-d', '--download-libc',
|
||||
action = 'store_true',
|
||||
default = False,
|
||||
help = 'Attempt to download the matching libc.so'
|
||||
)
|
||||
|
||||
hash_parser.add_argument(
|
||||
'--unstrip',
|
||||
action = 'store_true',
|
||||
default = True,
|
||||
help = 'Attempt to unstrip the libc binary with debug symbols from a debuginfod server'
|
||||
)
|
||||
|
||||
hash_parser.add_argument(
|
||||
'--no-unstrip',
|
||||
action = 'store_false',
|
||||
@@ -100,6 +94,14 @@ hash_parser.add_argument(
|
||||
help = 'Do NOT attempt to unstrip the libc binary with debug symbols from a debuginfod server'
|
||||
)
|
||||
|
||||
hash_parser.add_argument(
|
||||
'--offline-only',
|
||||
action = 'store_true',
|
||||
default = False,
|
||||
dest = 'offline_only',
|
||||
help = 'Attempt to searching with offline only mode'
|
||||
)
|
||||
|
||||
file_parser = libc_commands.add_parser(
|
||||
'file',
|
||||
help = 'Dump information about a libc binary',
|
||||
@@ -130,25 +132,34 @@ file_parser.add_argument(
|
||||
file_parser.add_argument(
|
||||
'--unstrip',
|
||||
action = 'store_true',
|
||||
default = False,
|
||||
dest = 'unstrip',
|
||||
help = 'Attempt to unstrip the libc binary inplace with debug symbols from a debuginfod server'
|
||||
)
|
||||
|
||||
fetch_parser = libc_commands.add_parser(
|
||||
'fetch',
|
||||
help = 'Fetch libc database',
|
||||
description = 'Fetch libc database. If no argument passed, it will init and upgrade libc-database repository',
|
||||
)
|
||||
|
||||
fetch_parser.add_argument(
|
||||
'path',
|
||||
nargs = '?',
|
||||
default = context.local_libcdb,
|
||||
help = 'Set libc-database path, If it is empty, the default path will be `context.local_libcdb` (%s)' % context.local_libcdb
|
||||
)
|
||||
|
||||
fetch_parser.add_argument(
|
||||
'-u', '--update',
|
||||
metavar = 'update',
|
||||
nargs = '+',
|
||||
choices = ['all', 'ubuntu', 'debian', 'rpm', 'centos', 'arch', 'alpine', 'kali', 'parrotsec', 'launchpad'],
|
||||
help = 'Fetch the desired libc categories'
|
||||
)
|
||||
|
||||
common_symbols = ['dup2', 'printf', 'puts', 'read', 'system', 'write']
|
||||
|
||||
def find_libc(params):
|
||||
import requests
|
||||
url = "https://libc.rip/api/find"
|
||||
result = requests.post(url, json=params, timeout=20)
|
||||
log.debug('Request: %s', params)
|
||||
log.debug('Result: %s', result.json())
|
||||
if result.status_code != 200 or len(result.json()) == 0:
|
||||
log.failure("Could not find libc for %s on libc.rip", params)
|
||||
return []
|
||||
|
||||
return result.json()
|
||||
|
||||
def print_libc(libc):
|
||||
def print_libc_info(libc):
|
||||
log.info('%s', text.red(libc['id']))
|
||||
log.indented('\t%-20s %s', text.green('BuildID:'), libc['buildid'])
|
||||
log.indented('\t%-20s %s', text.green('MD5:'), libc['md5'])
|
||||
@@ -158,14 +169,39 @@ def print_libc(libc):
|
||||
for symbol in libc['symbols'].items():
|
||||
log.indented('\t%25s = %s', symbol[0], symbol[1])
|
||||
|
||||
def handle_remote_libc(args, libc):
|
||||
print_libc(libc)
|
||||
if args.download_libc:
|
||||
path = libcdb.search_by_build_id(libc['buildid'], args.unstrip)
|
||||
if path:
|
||||
if args.unstrip:
|
||||
libcdb.unstrip_libc(path)
|
||||
shutil.copy(path, './{}.so'.format(libc['id']))
|
||||
def print_libc_elf(exe):
|
||||
from hashlib import md5, sha1, sha256
|
||||
|
||||
log.info('%s', text.red(os.path.basename(exe.path)))
|
||||
|
||||
libc_version = get_libc_version(exe)
|
||||
if libc_version:
|
||||
log.indented('%-20s %s', text.green('Version:'), libc_version)
|
||||
|
||||
if exe.buildid:
|
||||
log.indented('%-20s %s', text.green('BuildID:'), enhex(exe.buildid))
|
||||
|
||||
log.indented('%-20s %s', text.green('MD5:'), md5(exe.data).hexdigest())
|
||||
log.indented('%-20s %s', text.green('SHA1:'), sha1(exe.data).hexdigest())
|
||||
log.indented('%-20s %s', text.green('SHA256:'), sha256(exe.data).hexdigest())
|
||||
|
||||
# Always dump the basic list of common symbols
|
||||
log.indented('%s', text.green('Symbols:'))
|
||||
synthetic_symbols = collect_synthetic_symbols(exe)
|
||||
|
||||
symbols = common_symbols + (args.symbols or []) + synthetic_symbols
|
||||
symbols.sort()
|
||||
for symbol in symbols:
|
||||
if symbol not in exe.symbols:
|
||||
log.indented('%25s = %s', symbol, text.red('not found'))
|
||||
else:
|
||||
log.indented('%25s = %#x', symbol, translate_offset(exe.symbols[symbol], args, exe))
|
||||
|
||||
def get_libc_version(exe):
|
||||
res = re.search(br'libc[ -](\d+\.\d+)', exe.data)
|
||||
if res:
|
||||
return res.group(1).decode()
|
||||
return None
|
||||
|
||||
def translate_offset(offs, args, exe):
|
||||
if args.offset:
|
||||
@@ -182,7 +218,7 @@ def collect_synthetic_symbols(exe):
|
||||
available_symbols.append('str_bin_sh')
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
|
||||
libc_start_main_return = exe.libc_start_main_return
|
||||
if libc_start_main_return > 0:
|
||||
exe.symbols['__libc_start_main_ret'] = libc_start_main_return
|
||||
@@ -200,52 +236,59 @@ def main(args):
|
||||
if len(pairs) % 2 != 0:
|
||||
log.failure('Uneven number of arguments. Please provide "symbol offset" pairs')
|
||||
return
|
||||
|
||||
|
||||
symbols = {pairs[i]:pairs[i+1] for i in range(0, len(pairs), 2)}
|
||||
matched_libcs = find_libc({'symbols': symbols})
|
||||
matched_libcs = libcdb.search_by_symbol_offsets(symbols, offline_only=args.offline_only, return_raw=True)
|
||||
|
||||
if not matched_libcs:
|
||||
return
|
||||
|
||||
for libc in matched_libcs:
|
||||
handle_remote_libc(args, libc)
|
||||
print_libc_info(libc)
|
||||
if args.download_libc:
|
||||
path = libcdb.search_by_build_id(libc['buildid'], args.unstrip)
|
||||
if path:
|
||||
shutil.copy(path, './{}.so'.format(libc['id']))
|
||||
|
||||
elif args.libc_command == 'hash':
|
||||
inverted_map = {v: k for k, v in libcdb.MAP_TYPES.items()}
|
||||
hash_type = inverted_map.get(args.hash_type, args.hash_type)
|
||||
|
||||
for hash_value in args.hash_value:
|
||||
matched_libcs = find_libc({args.hash_type: hash_value})
|
||||
for libc in matched_libcs:
|
||||
handle_remote_libc(args, libc)
|
||||
path = libcdb.search_by_hash(hash_value, hash_type, unstrip=args.unstrip, offline_only=args.offline_only)
|
||||
exe = ELF(path, checksec=False)
|
||||
print_libc_elf(exe)
|
||||
|
||||
if args.download_libc:
|
||||
# if we cannot get actual libc version then copy with cache name
|
||||
shutil.copy(path, './libc-{}.so'.format(get_libc_version(exe) or Path(path).stem))
|
||||
|
||||
elif args.libc_command == 'file':
|
||||
from hashlib import md5, sha1, sha256
|
||||
for file in args.files:
|
||||
if not os.path.exists(file) or not os.path.isfile(file):
|
||||
log.failure('File does not exist %s', args.file)
|
||||
continue
|
||||
|
||||
|
||||
if args.unstrip:
|
||||
libcdb.unstrip_libc(file)
|
||||
|
||||
exe = ELF(file, checksec=False)
|
||||
log.info('%s', text.red(os.path.basename(file)))
|
||||
print_libc_elf(ELF(file, checksec=False))
|
||||
|
||||
libc_version = re.search(br'libc[ -](\d+\.\d+)', exe.data)
|
||||
if libc_version:
|
||||
log.indented('%-20s %s', text.green('Version:'), libc_version.group(1).decode())
|
||||
elif args.libc_command == 'fetch':
|
||||
|
||||
if exe.buildid:
|
||||
log.indented('%-20s %s', text.green('BuildID:'), enhex(exe.buildid))
|
||||
log.indented('%-20s %s', text.green('MD5:'), md5(exe.data).hexdigest())
|
||||
log.indented('%-20s %s', text.green('SHA1:'), sha1(exe.data).hexdigest())
|
||||
log.indented('%-20s %s', text.green('SHA256:'), sha256(exe.data).hexdigest())
|
||||
if args.update:
|
||||
subprocess.check_call(['./get'] + args.update, cwd=args.path)
|
||||
|
||||
# Always dump the basic list of common symbols
|
||||
log.indented('%s', text.green('Symbols:'))
|
||||
synthetic_symbols = collect_synthetic_symbols(exe)
|
||||
else:
|
||||
if not Path(args.path).exists():
|
||||
if yesno("Would you like to initialize the libc-database repository? "
|
||||
"If the path already exists, this prompt will not display, and automatically upgrade repository."):
|
||||
log.waitfor("init libc-database repository")
|
||||
subprocess.check_call(['git', 'clone', 'https://github.com/niklasb/libc-database/', args.path])
|
||||
else:
|
||||
log.waitfor("upgrade libc-database repository")
|
||||
subprocess.check_call(['git', 'pull'], cwd=args.path)
|
||||
|
||||
symbols = common_symbols + (args.symbols or []) + synthetic_symbols
|
||||
symbols.sort()
|
||||
for symbol in symbols:
|
||||
if symbol not in exe.symbols:
|
||||
log.indented('%25s = %s', symbol, text.red('not found'))
|
||||
else:
|
||||
log.indented('%25s = %#x', symbol, translate_offset(exe.symbols[symbol], args, exe))
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -1,7 +1,5 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import sys
|
||||
|
||||
from pwnlib.commandline import asm
|
||||
from pwnlib.commandline import checksec
|
||||
from pwnlib.commandline import common
|
||||
@@ -23,8 +21,7 @@ from pwnlib.commandline import template
|
||||
from pwnlib.commandline import unhex
|
||||
from pwnlib.commandline import update
|
||||
from pwnlib.commandline import version
|
||||
from pwnlib.commandline.common import parser
|
||||
from pwnlib.context import context
|
||||
from pwnlib.commandline.common import parser as parser
|
||||
|
||||
commands = {
|
||||
'asm': asm.main,
|
||||
@@ -50,12 +47,7 @@ commands = {
|
||||
}
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
parser.print_usage()
|
||||
sys.exit()
|
||||
args = parser.parse_args()
|
||||
with context.local(log_console = sys.stderr):
|
||||
commands[args.command](args)
|
||||
common.entrypoint(commands)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -109,4 +109,4 @@ def main(args):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -53,4 +53,4 @@ def main(args):
|
||||
args.output.write(result)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -110,4 +110,4 @@ def main(args):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -71,17 +71,9 @@ p.add_argument(
|
||||
|
||||
p.add_argument(
|
||||
'shellcode',
|
||||
nargs = '?',
|
||||
help = 'The shellcode you want',
|
||||
type = str
|
||||
)
|
||||
|
||||
p.add_argument(
|
||||
'args',
|
||||
nargs = '*',
|
||||
metavar = 'arg',
|
||||
default = (),
|
||||
help = 'Argument to the chosen shellcode',
|
||||
help = 'The shellcodes you want. shellcode [args ...] [+ shellcode [args ...]]',
|
||||
type = str
|
||||
)
|
||||
|
||||
p.add_argument(
|
||||
@@ -91,6 +83,12 @@ p.add_argument(
|
||||
action='store_true'
|
||||
)
|
||||
|
||||
p.add_argument(
|
||||
'--delim',
|
||||
help='Set the delimiter between multilple shellcodes',
|
||||
default='+'
|
||||
)
|
||||
|
||||
p.add_argument(
|
||||
'-b',
|
||||
'--before',
|
||||
@@ -172,24 +170,50 @@ p.add_argument(
|
||||
help='Generated ELF is a shared library'
|
||||
)
|
||||
|
||||
def get_template(name):
|
||||
func = shellcraft
|
||||
for attr in name.split('.'):
|
||||
func = getattr(func, attr)
|
||||
return func
|
||||
def get_template(shellcodes):
|
||||
funcs = []
|
||||
for shellcode in shellcodes:
|
||||
func = shellcraft
|
||||
cur_name = shellcode[0]
|
||||
args = []
|
||||
if len(shellcode) > 1:
|
||||
args = shellcode[1:]
|
||||
for attr in cur_name.split('.'):
|
||||
func = getattr(func, attr)
|
||||
funcs.append((cur_name, func, args))
|
||||
return funcs
|
||||
|
||||
def is_not_a_syscall_template(name):
|
||||
template_src = shellcraft._get_source(name)
|
||||
return '/syscalls' not in template_src
|
||||
|
||||
def main(args):
|
||||
delim = '+'
|
||||
if args.delim:
|
||||
delim = args.delim.strip()
|
||||
|
||||
shellcodes = []
|
||||
if args.shellcode:
|
||||
current = []
|
||||
for s in args.shellcode:
|
||||
if s.strip() == delim:
|
||||
shellcodes.append(current)
|
||||
current = []
|
||||
else:
|
||||
current.append(s)
|
||||
if len(current) > 0:
|
||||
shellcodes.append(current)
|
||||
|
||||
if args.list:
|
||||
templates = shellcraft.templates
|
||||
|
||||
if args.shellcode:
|
||||
templates = filter(lambda a: args.shellcode in a, templates)
|
||||
template_array = []
|
||||
for s in shellcodes:
|
||||
template_array.extend(list(filter(lambda a: s[0] in a, templates)))
|
||||
templates = template_array
|
||||
elif not args.syscalls:
|
||||
templates = filter(is_not_a_syscall_template, templates)
|
||||
templates = list(filter(is_not_a_syscall_template, templates))
|
||||
|
||||
print('\n'.join(templates))
|
||||
exit()
|
||||
@@ -199,84 +223,92 @@ def main(args):
|
||||
exit()
|
||||
|
||||
try:
|
||||
func = get_template(args.shellcode)
|
||||
funcs = get_template(shellcodes)
|
||||
except AttributeError:
|
||||
log.error("Unknown shellcraft template %r. Use --list to see available shellcodes." % args.shellcode)
|
||||
|
||||
if args.show:
|
||||
# remove doctests
|
||||
doc = []
|
||||
in_doctest = False
|
||||
block_indent = None
|
||||
caption = None
|
||||
lines = func.__doc__.splitlines()
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
if line.lstrip().startswith('>>>'):
|
||||
# this line starts a doctest
|
||||
in_doctest = True
|
||||
block_indent = None
|
||||
if caption:
|
||||
# delete back up to the caption
|
||||
doc = doc[:caption - i]
|
||||
caption = None
|
||||
elif line == '':
|
||||
# skip blank lines
|
||||
pass
|
||||
elif in_doctest:
|
||||
# indentation marks the end of a doctest
|
||||
indent = len(line) - len(line.lstrip())
|
||||
if block_indent is None:
|
||||
if not line.lstrip().startswith('...'):
|
||||
block_indent = indent
|
||||
elif indent < block_indent:
|
||||
in_doctest = False
|
||||
for (name, func, _args) in funcs:
|
||||
# remove doctests
|
||||
doc = []
|
||||
in_doctest = False
|
||||
block_indent = None
|
||||
caption = None
|
||||
lines = func.__doc__.splitlines()
|
||||
i = 0
|
||||
if len(funcs) > 1:
|
||||
print('%s:' % name)
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
if line.lstrip().startswith('>>>'):
|
||||
# this line starts a doctest
|
||||
in_doctest = True
|
||||
block_indent = None
|
||||
# re-evalutate this line
|
||||
continue
|
||||
elif line.endswith(':'):
|
||||
# save index of caption
|
||||
caption = i
|
||||
else:
|
||||
# this is not blank space and we're not in a doctest, so the
|
||||
# previous caption (if any) was not for a doctest
|
||||
caption = None
|
||||
if caption:
|
||||
# delete back up to the caption
|
||||
doc = doc[:caption - i]
|
||||
caption = None
|
||||
elif line == '':
|
||||
# skip blank lines
|
||||
pass
|
||||
elif in_doctest:
|
||||
# indentation marks the end of a doctest
|
||||
indent = len(line) - len(line.lstrip())
|
||||
if block_indent is None:
|
||||
if not line.lstrip().startswith('...'):
|
||||
block_indent = indent
|
||||
elif indent < block_indent:
|
||||
in_doctest = False
|
||||
block_indent = None
|
||||
# re-evalutate this line
|
||||
continue
|
||||
elif line.endswith(':'):
|
||||
# save index of caption
|
||||
caption = i
|
||||
else:
|
||||
# this is not blank space and we're not in a doctest, so the
|
||||
# previous caption (if any) was not for a doctest
|
||||
caption = None
|
||||
|
||||
if not in_doctest:
|
||||
doc.append(line)
|
||||
i += 1
|
||||
print('\n'.join(doc).rstrip())
|
||||
if not in_doctest:
|
||||
doc.append(line)
|
||||
i += 1
|
||||
print('\n'.join(doc).rstrip())
|
||||
if len(funcs) > 1:
|
||||
print('')
|
||||
exit()
|
||||
|
||||
defargs = len(six.get_function_defaults(func) or ())
|
||||
reqargs = six.get_function_code(func).co_argcount - defargs
|
||||
if len(args.args) < reqargs:
|
||||
if defargs > 0:
|
||||
log.critical('%s takes at least %d arguments' % (args.shellcode, reqargs))
|
||||
sys.exit(1)
|
||||
else:
|
||||
log.critical('%s takes exactly %d arguments' % (args.shellcode, reqargs))
|
||||
sys.exit(1)
|
||||
code_array = []
|
||||
for (name, func, func_args) in funcs:
|
||||
defargs = len(six.get_function_defaults(func) or ())
|
||||
reqargs = six.get_function_code(func).co_argcount - defargs
|
||||
|
||||
# Captain uglyness saves the day!
|
||||
for i, val in enumerate(args.args):
|
||||
try:
|
||||
args.args[i] = util.safeeval.expr(val)
|
||||
except ValueError:
|
||||
pass
|
||||
if len(func_args) < reqargs:
|
||||
if defargs > 0:
|
||||
log.critical('%s takes at least %d arguments' % (name, reqargs))
|
||||
sys.exit(1)
|
||||
else:
|
||||
log.critical('%s takes exactly %d arguments' % (name, reqargs))
|
||||
sys.exit(1)
|
||||
|
||||
# And he strikes again!
|
||||
list(map(common.context_arg, args.shellcode.split('.')))
|
||||
code = func(*args.args)
|
||||
# Captain uglyness saves the day!
|
||||
for i, val in enumerate(func_args):
|
||||
try:
|
||||
func_args[i] = util.safeeval.expr(val)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# And he strikes again!
|
||||
list(map(common.context_arg, name.split('.')))
|
||||
code_array.append(func(*func_args))
|
||||
|
||||
code = "".join(code_array)
|
||||
|
||||
if args.before:
|
||||
code = shellcraft.trap() + code
|
||||
if args.after:
|
||||
code = code + shellcraft.trap()
|
||||
|
||||
|
||||
if args.format in ['a', 'asm', 'assembly']:
|
||||
if args.color:
|
||||
from pygments import highlight
|
||||
@@ -319,7 +351,7 @@ def main(args):
|
||||
else:
|
||||
args.format = 'raw'
|
||||
|
||||
arch = args.shellcode.split('.')[0]
|
||||
arch = name.split('.')[0]
|
||||
|
||||
if args.debug:
|
||||
if not args.avoid:
|
||||
@@ -352,4 +384,4 @@ def main(args):
|
||||
args.out.write(code)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -1,9 +1,12 @@
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from pwn import *
|
||||
from pwnlib.commandline import common
|
||||
from pwnlib.util.misc import which, parse_ldd_output, write
|
||||
|
||||
from sys import stderr
|
||||
from mako.lookup import TemplateLookup, Template
|
||||
|
||||
parser = common.parser_commands.add_parser(
|
||||
@@ -32,18 +35,113 @@ parser.add_argument('--template', help='Path to a custom template. Tries to use
|
||||
os.path.join(printable_data_path, "templates", "pwnup.mako"))
|
||||
parser.add_argument('--no-auto', help='Do not automatically detect missing binaries', action='store_false', dest='auto')
|
||||
|
||||
def get_docker_image_libraries():
|
||||
"""Tries to retrieve challenge libraries from a Docker image built from the Dockerfile in the current working directory.
|
||||
|
||||
The libraries are retrieved by parsing the output of running ldd on /bin/sh.
|
||||
Supports regular Docker images as well as jail images.
|
||||
"""
|
||||
with log.progress("Extracting challenge libraries from Docker image") as progress:
|
||||
if not which("docker"):
|
||||
progress.failure("docker command not found")
|
||||
return None, None
|
||||
# maps jail image name to the root directory of the child image
|
||||
jail_image_to_chroot_dir = {
|
||||
"pwn.red/jail": "/srv",
|
||||
}
|
||||
dockerfile = open("Dockerfile", "r").read()
|
||||
jail = None
|
||||
chroot_dir = "/"
|
||||
for jail_image in jail_image_to_chroot_dir:
|
||||
if re.search(r"^FROM %s" % jail_image, dockerfile, re.MULTILINE):
|
||||
jail = jail_image
|
||||
chroot_dir = jail_image_to_chroot_dir[jail_image]
|
||||
break
|
||||
try:
|
||||
progress.status("Building image")
|
||||
image_sha = subprocess.check_output(["docker", "build", "-q", "."], stderr=subprocess.PIPE, shell=False).decode().strip()
|
||||
|
||||
progress.status("Retrieving library paths")
|
||||
ldd_command = ["-c", "chroot %s /bin/sh -c 'ldd /bin/sh'" % chroot_dir]
|
||||
ldd_output = subprocess.check_output([
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"--entrypoint",
|
||||
"/bin/sh",
|
||||
] + (["--privileged"] if jail else []) + [
|
||||
image_sha,
|
||||
] + ldd_command,
|
||||
stderr=subprocess.PIPE,
|
||||
shell=False
|
||||
).decode()
|
||||
|
||||
libc, ld = None, None
|
||||
libc_basename, ld_basename = None, None
|
||||
for lib_path in parse_ldd_output(ldd_output):
|
||||
if "libc." in lib_path:
|
||||
libc = lib_path
|
||||
libc_basename = os.path.basename(lib_path)
|
||||
if "ld-" in lib_path:
|
||||
ld = lib_path
|
||||
ld_basename = os.path.basename(lib_path)
|
||||
|
||||
if not (libc and ld):
|
||||
progress.failure("Could not find libraries")
|
||||
return None, None
|
||||
|
||||
progress.status("Copying libraries to current directory")
|
||||
for filename, basename in zip((libc, ld), (libc_basename, ld_basename)):
|
||||
cat_command = ["-c", "chroot %s /bin/sh -c '/bin/cat %s'" % (chroot_dir, filename)]
|
||||
contents = subprocess.check_output([
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"--entrypoint",
|
||||
"/bin/sh",
|
||||
] + (["--privileged"] if jail else []) + [
|
||||
image_sha
|
||||
] + cat_command,
|
||||
stderr=subprocess.PIPE,
|
||||
shell=False
|
||||
)
|
||||
write(basename, contents)
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(e.stderr.decode(), file=sys.stderr)
|
||||
progress.failure("docker failed with status: %d" % e.returncode)
|
||||
return None, None
|
||||
|
||||
progress.success("Retrieved libraries from Docker image")
|
||||
return libc_basename, ld_basename
|
||||
|
||||
def detect_missing_binaries(args):
|
||||
"""Automatically detects challenge binaries and libraries in the current directory.
|
||||
|
||||
This function scans the current directory for executable files, libc, and ld libraries.
|
||||
If a Dockerfile is present and no libraries are found, it attempts to extract them from
|
||||
the Docker image, but only if the binary is not statically linked.
|
||||
|
||||
Args:
|
||||
args: Argument namespace containing exe and libc attributes.
|
||||
|
||||
Returns:
|
||||
tuple: A pair of (executable_path, libc_path) where either may be None if not found.
|
||||
"""
|
||||
log.info("Automatically detecting challenge binaries...")
|
||||
# look for challenge binary, libc, and ld in current directory
|
||||
exe, libc, ld = args.exe, args.libc, None
|
||||
has_dockerfile = False
|
||||
other_files = []
|
||||
for filename in os.listdir():
|
||||
for filename in os.listdir("."):
|
||||
if not os.path.isfile(filename):
|
||||
continue
|
||||
if not libc and ('libc-' in filename or 'libc.' in filename):
|
||||
libc = filename
|
||||
elif not ld and 'ld-' in filename:
|
||||
ld = filename
|
||||
elif filename == "Dockerfile":
|
||||
has_dockerfile = True
|
||||
else:
|
||||
if os.access(filename, os.X_OK):
|
||||
other_files.append(filename)
|
||||
@@ -52,6 +150,21 @@ def detect_missing_binaries(args):
|
||||
exe = other_files[0]
|
||||
elif len(other_files) > 1:
|
||||
log.warning("Failed to find challenge binary. There are multiple binaries in the current directory: %s", other_files)
|
||||
|
||||
# Check if the binary is statically linked before trying to extract libraries from Docker
|
||||
is_statically_linked = False
|
||||
if exe:
|
||||
try:
|
||||
binary = ELF(exe, checksec=False)
|
||||
is_statically_linked = binary.statically_linked
|
||||
if is_statically_linked:
|
||||
log.info("Binary is statically linked, no need for external libraries")
|
||||
except Exception as e:
|
||||
log.warning("Could not check if binary is statically linked: %s", e)
|
||||
|
||||
# Only extract libraries from Docker if the binary is not statically linked
|
||||
if has_dockerfile and exe and not (libc or ld) and not is_statically_linked:
|
||||
libc, ld = get_docker_image_libraries()
|
||||
|
||||
if exe != args.exe:
|
||||
log.success("Found challenge binary %r", exe)
|
||||
@@ -122,5 +235,5 @@ def main(args):
|
||||
except OSError: pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
|
||||
@@ -30,4 +30,4 @@ def main(args):
|
||||
raise
|
||||
|
||||
if __name__ == '__main__':
|
||||
common.main(__file__)
|
||||
common.main(__file__, main)
|
||||
@@ -30,4 +30,4 @@ def main(a):
|
||||
subprocess.check_call(result, shell=False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -29,4 +29,4 @@ def main(a):
|
||||
log.info("Pwntools v%s" % version)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
pwnlib.commandline.common.main(__file__, main)
|
||||
@@ -88,6 +88,7 @@ VOL_CAP_FMT_NO_PERMISSIONS = Constant('VOL_CAP_FMT_NO_PERMISSIONS',0x00400000)
|
||||
VOL_CAP_FMT_SHARED_SPACE = Constant('VOL_CAP_FMT_SHARED_SPACE',0x00800000)
|
||||
VOL_CAP_FMT_VOL_GROUPS = Constant('VOL_CAP_FMT_VOL_GROUPS',0x01000000)
|
||||
VOL_CAP_FMT_SEALED = Constant('VOL_CAP_FMT_SEALED',0x02000000)
|
||||
VOL_CAP_FMT_CLONE_MAPPING = Constant('VOL_CAP_FMT_CLONE_MAPPING',0x04000000)
|
||||
VOL_CAP_INT_SEARCHFS = Constant('VOL_CAP_INT_SEARCHFS',0x00000001)
|
||||
VOL_CAP_INT_ATTRLIST = Constant('VOL_CAP_INT_ATTRLIST',0x00000002)
|
||||
VOL_CAP_INT_NFSEXPORT = Constant('VOL_CAP_INT_NFSEXPORT',0x00000004)
|
||||
@@ -109,6 +110,8 @@ VOL_CAP_INT_RENAME_SWAP = Constant('VOL_CAP_INT_RENAME_SWAP',0x00040000)
|
||||
VOL_CAP_INT_RENAME_EXCL = Constant('VOL_CAP_INT_RENAME_EXCL',0x00080000)
|
||||
VOL_CAP_INT_RENAME_OPENFAIL = Constant('VOL_CAP_INT_RENAME_OPENFAIL',0x00100000)
|
||||
VOL_CAP_INT_RENAME_SECLUDE = Constant('VOL_CAP_INT_RENAME_SECLUDE',0x00200000)
|
||||
VOL_CAP_INT_ATTRIBUTION_TAG = Constant('VOL_CAP_INT_ATTRIBUTION_TAG',0x00400000)
|
||||
VOL_CAP_INT_PUNCHHOLE = Constant('VOL_CAP_INT_PUNCHHOLE',0x00800000)
|
||||
ATTR_CMN_NAME = Constant('ATTR_CMN_NAME',0x00000001)
|
||||
ATTR_CMN_DEVID = Constant('ATTR_CMN_DEVID',0x00000002)
|
||||
ATTR_CMN_FSID = Constant('ATTR_CMN_FSID',0x00000004)
|
||||
@@ -293,6 +296,8 @@ IO_SYSCALL_DISPATCH = Constant('IO_SYSCALL_DISPATCH',0x100000)
|
||||
IO_SWAP_DISPATCH = Constant('IO_SWAP_DISPATCH',0x200000)
|
||||
IO_SKIP_ENCRYPTION = Constant('IO_SKIP_ENCRYPTION',0x400000)
|
||||
IO_EVTONLY = Constant('IO_EVTONLY',0x800000)
|
||||
IO_NOCACHE_SYSSPACE = Constant('IO_NOCACHE_SYSSPACE',0x1000000)
|
||||
IO_NOCACHE_SWRITE = Constant('IO_NOCACHE_SWRITE',0x2000000)
|
||||
LOOKUP = Constant('LOOKUP',0)
|
||||
CREATE = Constant('CREATE',1)
|
||||
DELETE = Constant('DELETE',2)
|
||||
@@ -347,6 +352,7 @@ VNODE_UPDATE_PURGE = Constant('VNODE_UPDATE_PURGE',0x08)
|
||||
VNODE_LOOKUP_NOFOLLOW = Constant('VNODE_LOOKUP_NOFOLLOW',0x01)
|
||||
VNODE_LOOKUP_NOCROSSMOUNT = Constant('VNODE_LOOKUP_NOCROSSMOUNT',0x02)
|
||||
VNODE_LOOKUP_CROSSMOUNTNOWAIT = Constant('VNODE_LOOKUP_CROSSMOUNTNOWAIT',0x04)
|
||||
VNODE_LOOKUP_NOFOLLOW_ANY = Constant('VNODE_LOOKUP_NOFOLLOW_ANY',0x08)
|
||||
VNODE_RELOAD = Constant('VNODE_RELOAD',0x01)
|
||||
VNODE_WAIT = Constant('VNODE_WAIT',0x02)
|
||||
VNODE_WRITEABLE = Constant('VNODE_WRITEABLE',0x04)
|
||||
@@ -425,7 +431,7 @@ LOCKPARENT = Constant('LOCKPARENT',0x0008)
|
||||
WANTPARENT = Constant('WANTPARENT',0x0010)
|
||||
UIO_MAXIOV = Constant('UIO_MAXIOV',1024)
|
||||
UIO_SMALLIOV = Constant('UIO_SMALLIOV',8)
|
||||
EVFILT_SYSCOUNT = Constant('EVFILT_SYSCOUNT',17)
|
||||
EVFILT_SYSCOUNT = Constant('EVFILT_SYSCOUNT',18)
|
||||
KEVENT_FLAG_NONE = Constant('KEVENT_FLAG_NONE',0x000000)
|
||||
KEVENT_FLAG_IMMEDIATE = Constant('KEVENT_FLAG_IMMEDIATE',0x000001)
|
||||
KEVENT_FLAG_ERROR_EVENTS = Constant('KEVENT_FLAG_ERROR_EVENTS',0x000002)
|
||||
@@ -503,6 +509,7 @@ IMGPF_IS_64BIT_ADDR = Constant('IMGPF_IS_64BIT_ADDR',0x00000008)
|
||||
IMGPF_SPAWN = Constant('IMGPF_SPAWN',0x00000010)
|
||||
IMGPF_DISABLE_ASLR = Constant('IMGPF_DISABLE_ASLR',0x00000020)
|
||||
IMGPF_ALLOW_DATA_EXEC = Constant('IMGPF_ALLOW_DATA_EXEC',0x00000040)
|
||||
IMGPF_3P_PLUGINS = Constant('IMGPF_3P_PLUGINS',0x00000080)
|
||||
IMGPF_EXEC = Constant('IMGPF_EXEC',0x00000100)
|
||||
IMGPF_HIGH_BITS_ASLR = Constant('IMGPF_HIGH_BITS_ASLR',0x00000200)
|
||||
IMGPF_IS_64BIT_DATA = Constant('IMGPF_IS_64BIT_DATA',0x00000400)
|
||||
@@ -512,6 +519,7 @@ IMGPF_PLUGIN_HOST_DISABLE_A_KEYS = Constant('IMGPF_PLUGIN_HOST_DISABLE_A_KEYS',0
|
||||
IMGPF_HW_TPRO = Constant('IMGPF_HW_TPRO',0x00004000)
|
||||
IMGPF_ROSETTA = Constant('IMGPF_ROSETTA',0x10000000)
|
||||
IMGPF_ALT_ROSETTA = Constant('IMGPF_ALT_ROSETTA',0x20000000)
|
||||
IMGPF_RESERVED_2 = Constant('IMGPF_RESERVED_2',0x40000000)
|
||||
IMGPF_NOJOP = Constant('IMGPF_NOJOP',0x80000000)
|
||||
IMGPF_SB_DEFAULT = Constant('IMGPF_SB_DEFAULT',0)
|
||||
IMGPF_SB_TRUE = Constant('IMGPF_SB_TRUE',1)
|
||||
@@ -560,9 +568,34 @@ WSTOPPED = Constant('WSTOPPED',0x00000008)
|
||||
WCONTINUED = Constant('WCONTINUED',0x00000010)
|
||||
WNOWAIT = Constant('WNOWAIT',0x00000020)
|
||||
WAIT_MYPGRP = Constant('WAIT_MYPGRP',0)
|
||||
PRIO_DARWIN_GPU = Constant('PRIO_DARWIN_GPU',5)
|
||||
PRIO_DARWIN_GPU_ALLOW = Constant('PRIO_DARWIN_GPU_ALLOW',0x1)
|
||||
PRIO_DARWIN_GPU_DENY = Constant('PRIO_DARWIN_GPU_DENY',0x2)
|
||||
PRIO_DARWIN_ROLE = Constant('PRIO_DARWIN_ROLE',6)
|
||||
PRIO_DARWIN_ROLE_DEFAULT = Constant('PRIO_DARWIN_ROLE_DEFAULT',0x0)
|
||||
PRIO_DARWIN_ROLE_UI_FOCAL = Constant('PRIO_DARWIN_ROLE_UI_FOCAL',0x1)
|
||||
PRIO_DARWIN_ROLE_UI = Constant('PRIO_DARWIN_ROLE_UI',0x2)
|
||||
PRIO_DARWIN_ROLE_NON_UI = Constant('PRIO_DARWIN_ROLE_NON_UI',0x3)
|
||||
PRIO_DARWIN_ROLE_UI_NON_FOCAL = Constant('PRIO_DARWIN_ROLE_UI_NON_FOCAL',0x4)
|
||||
PRIO_DARWIN_ROLE_TAL_LAUNCH = Constant('PRIO_DARWIN_ROLE_TAL_LAUNCH',0x5)
|
||||
PRIO_DARWIN_ROLE_DARWIN_BG = Constant('PRIO_DARWIN_ROLE_DARWIN_BG',0x6)
|
||||
PRIO_DARWIN_GAME_MODE = Constant('PRIO_DARWIN_GAME_MODE',7)
|
||||
PRIO_DARWIN_CARPLAY_MODE = Constant('PRIO_DARWIN_CARPLAY_MODE',8)
|
||||
PRIO_DARWIN_GAME_MODE_OFF = Constant('PRIO_DARWIN_GAME_MODE_OFF',0x0)
|
||||
PRIO_DARWIN_GAME_MODE_ON = Constant('PRIO_DARWIN_GAME_MODE_ON',0x1)
|
||||
PRIO_DARWIN_CARPLAY_MODE_OFF = Constant('PRIO_DARWIN_CARPLAY_MODE_OFF',0x0)
|
||||
PRIO_DARWIN_CARPLAY_MODE_ON = Constant('PRIO_DARWIN_CARPLAY_MODE_ON',0x1)
|
||||
IOMON_ENABLE = Constant('IOMON_ENABLE',0x01)
|
||||
IOMON_DISABLE = Constant('IOMON_DISABLE',0x02)
|
||||
IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY = Constant('IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY',1)
|
||||
IOPOL_TYPE_VFS_ALTLINK = Constant('IOPOL_TYPE_VFS_ALTLINK',11)
|
||||
IOPOL_TYPE_VFS_NOCACHE_WRITE_FS_BLKSIZE = Constant('IOPOL_TYPE_VFS_NOCACHE_WRITE_FS_BLKSIZE',12)
|
||||
IOPOL_VFS_HFS_CASE_SENSITIVITY_DEFAULT = Constant('IOPOL_VFS_HFS_CASE_SENSITIVITY_DEFAULT',0)
|
||||
IOPOL_VFS_HFS_CASE_SENSITIVITY_FORCE_CASE_SENSITIVE = Constant('IOPOL_VFS_HFS_CASE_SENSITIVITY_FORCE_CASE_SENSITIVE',1)
|
||||
IOPOL_VFS_ALTLINK_DISABLED = Constant('IOPOL_VFS_ALTLINK_DISABLED',0)
|
||||
IOPOL_VFS_ALTLINK_ENABLED = Constant('IOPOL_VFS_ALTLINK_ENABLED',1)
|
||||
IOPOL_CMD_GET = Constant('IOPOL_CMD_GET',0x00000001)
|
||||
IOPOL_CMD_SET = Constant('IOPOL_CMD_SET',0x00000002)
|
||||
IPC_CREAT = Constant('IPC_CREAT',0o001000)
|
||||
IPC_EXCL = Constant('IPC_EXCL',0o002000)
|
||||
IPC_NOWAIT = Constant('IPC_NOWAIT',0o004000)
|
||||
@@ -677,6 +710,7 @@ F_SETLEASE = Constant('F_SETLEASE',106)
|
||||
F_GETLEASE = Constant('F_GETLEASE',107)
|
||||
F_TRANSFEREXTENTS = Constant('F_TRANSFEREXTENTS',110)
|
||||
F_ATTRIBUTION_TAG = Constant('F_ATTRIBUTION_TAG',111)
|
||||
F_ADDSIGS_MAIN_BINARY = Constant('F_ADDSIGS_MAIN_BINARY',113)
|
||||
FCNTL_FS_SPECIFIC_BASE = Constant('FCNTL_FS_SPECIFIC_BASE',0x00010000)
|
||||
F_DUPFD_CLOEXEC = Constant('F_DUPFD_CLOEXEC',67)
|
||||
FD_CLOEXEC = Constant('FD_CLOEXEC',1)
|
||||
@@ -904,6 +938,7 @@ MADV_FREE_REUSABLE = Constant('MADV_FREE_REUSABLE',7)
|
||||
MADV_FREE_REUSE = Constant('MADV_FREE_REUSE',8)
|
||||
MADV_CAN_REUSE = Constant('MADV_CAN_REUSE',9)
|
||||
MADV_PAGEOUT = Constant('MADV_PAGEOUT',10)
|
||||
MADV_ZERO = Constant('MADV_ZERO',11)
|
||||
MINCORE_INCORE = Constant('MINCORE_INCORE',0x1)
|
||||
MINCORE_REFERENCED = Constant('MINCORE_REFERENCED',0x2)
|
||||
MINCORE_MODIFIED = Constant('MINCORE_MODIFIED',0x4)
|
||||
@@ -1111,6 +1146,9 @@ DBG_MACH_EXCP_EMUL = Constant('DBG_MACH_EXCP_EMUL',0x0E)
|
||||
DBG_MACH_IHDLR = Constant('DBG_MACH_IHDLR',0x10)
|
||||
DBG_MACH_IPC = Constant('DBG_MACH_IPC',0x20)
|
||||
DBG_MACH_RESOURCE = Constant('DBG_MACH_RESOURCE',0x25)
|
||||
DBG_MACH_EXCLAVES = Constant('DBG_MACH_EXCLAVES',0x2A)
|
||||
DBG_MACH_EXCLAVES_SCHEDULER = Constant('DBG_MACH_EXCLAVES_SCHEDULER',0x2B)
|
||||
DBG_MACH_EPOCH_SYNC = Constant('DBG_MACH_EPOCH_SYNC',0x2C)
|
||||
DBG_MACH_VM = Constant('DBG_MACH_VM',0x30)
|
||||
DBG_MACH_LEAKS = Constant('DBG_MACH_LEAKS',0x31)
|
||||
DBG_MACH_WORKINGSET = Constant('DBG_MACH_WORKINGSET',0x32)
|
||||
@@ -1136,6 +1174,7 @@ DBG_MACH_HV = Constant('DBG_MACH_HV',0xAC)
|
||||
DBG_MACH_KCOV = Constant('DBG_MACH_KCOV',0xAD)
|
||||
DBG_MACH_MACHDEP_EXCP_SC_x86 = Constant('DBG_MACH_MACHDEP_EXCP_SC_x86',0xAE)
|
||||
DBG_MACH_MACHDEP_EXCP_SC_ARM = Constant('DBG_MACH_MACHDEP_EXCP_SC_ARM',0xAF)
|
||||
DBG_MACH_VM_RECLAIM = Constant('DBG_MACH_VM_RECLAIM',0xB0)
|
||||
DBC_MACH_IO_MMIO_READ = Constant('DBC_MACH_IO_MMIO_READ',0x1)
|
||||
DBC_MACH_IO_MMIO_WRITE = Constant('DBC_MACH_IO_MMIO_WRITE',0x2)
|
||||
DBC_MACH_IO_PHYS_READ = Constant('DBC_MACH_IO_PHYS_READ',0x3)
|
||||
@@ -1177,7 +1216,6 @@ MACH_RW_DEMOTE = Constant('MACH_RW_DEMOTE',0x1d)
|
||||
MACH_SCHED_MAINTENANCE = Constant('MACH_SCHED_MAINTENANCE',0x1f)
|
||||
MACH_DISPATCH = Constant('MACH_DISPATCH',0x20)
|
||||
MACH_QUANTUM_HANDOFF = Constant('MACH_QUANTUM_HANDOFF',0x21)
|
||||
MACH_MULTIQ_DEQUEUE = Constant('MACH_MULTIQ_DEQUEUE',0x22)
|
||||
MACH_SCHED_THREAD_SWITCH = Constant('MACH_SCHED_THREAD_SWITCH',0x23)
|
||||
MACH_SCHED_SMT_BALANCE = Constant('MACH_SCHED_SMT_BALANCE',0x24)
|
||||
MACH_REMOTE_DEFERRED_AST = Constant('MACH_REMOTE_DEFERRED_AST',0x25)
|
||||
@@ -1229,6 +1267,7 @@ MACH_RT_DISALLOWED_WORK_INTERVAL = Constant('MACH_RT_DISALLOWED_WORK_INTERVAL',0
|
||||
MACH_SCHED_WI_EXTERNAL_WAKEUP = Constant('MACH_SCHED_WI_EXTERNAL_WAKEUP',0x61)
|
||||
MACH_SCHED_AST_CHECK = Constant('MACH_SCHED_AST_CHECK',0x62)
|
||||
MACH_SCHED_PREEMPT_TIMER_ACTIVE = Constant('MACH_SCHED_PREEMPT_TIMER_ACTIVE',0x63)
|
||||
MACH_PROCESSOR_SHUTDOWN = Constant('MACH_PROCESSOR_SHUTDOWN',0x64)
|
||||
MACH_SCHED_CLUTCH_ROOT_BUCKET_STATE = Constant('MACH_SCHED_CLUTCH_ROOT_BUCKET_STATE',0x0)
|
||||
MACH_SCHED_CLUTCH_TG_BUCKET_STATE = Constant('MACH_SCHED_CLUTCH_TG_BUCKET_STATE',0x1)
|
||||
MACH_SCHED_CLUTCH_THREAD_SELECT = Constant('MACH_SCHED_CLUTCH_THREAD_SELECT',0x2)
|
||||
@@ -1254,20 +1293,83 @@ WORKGROUP_INTERVAL_SET_WORKLOAD_ID = Constant('WORKGROUP_INTERVAL_SET_WORKLOAD_I
|
||||
WORKGROUP_INTERVAL_SET_WORKLOAD_ID_NAME = Constant('WORKGROUP_INTERVAL_SET_WORKLOAD_ID_NAME',0x7)
|
||||
KCOV_STKSZ_THRESHOLD_ABOVE = Constant('KCOV_STKSZ_THRESHOLD_ABOVE',0x0)
|
||||
KCOV_STKSZ_THRESHOLD_BELOW = Constant('KCOV_STKSZ_THRESHOLD_BELOW',0x1)
|
||||
MACH_MULTIQ_BOUND = Constant('MACH_MULTIQ_BOUND',1)
|
||||
MACH_MULTIQ_GROUP = Constant('MACH_MULTIQ_GROUP',2)
|
||||
MACH_MULTIQ_GLOBAL = Constant('MACH_MULTIQ_GLOBAL',3)
|
||||
DBG_ZERO_FILL_FAULT = Constant('DBG_ZERO_FILL_FAULT',1)
|
||||
DBG_PAGEIN_FAULT = Constant('DBG_PAGEIN_FAULT',2)
|
||||
DBG_COW_FAULT = Constant('DBG_COW_FAULT',3)
|
||||
DBG_CACHE_HIT_FAULT = Constant('DBG_CACHE_HIT_FAULT',4)
|
||||
DBG_NZF_PAGE_FAULT = Constant('DBG_NZF_PAGE_FAULT',5)
|
||||
DBG_GUARD_FAULT = Constant('DBG_GUARD_FAULT',6)
|
||||
DBG_PAGEINV_FAULT = Constant('DBG_PAGEINV_FAULT',7)
|
||||
DBG_PAGEIND_FAULT = Constant('DBG_PAGEIND_FAULT',8)
|
||||
DBG_COMPRESSOR_FAULT = Constant('DBG_COMPRESSOR_FAULT',9)
|
||||
DBG_COMPRESSOR_SWAPIN_FAULT = Constant('DBG_COMPRESSOR_SWAPIN_FAULT',10)
|
||||
DBG_COR_FAULT = Constant('DBG_COR_FAULT',11)
|
||||
DBG_VM_VNODE_PAGEOUT = Constant('DBG_VM_VNODE_PAGEOUT',0x001)
|
||||
DBG_VM_FAULT_INTERNAL = Constant('DBG_VM_FAULT_INTERNAL',0x002)
|
||||
DBG_VM_PURGEABLE_TOKEN_ADD = Constant('DBG_VM_PURGEABLE_TOKEN_ADD',0x040)
|
||||
DBG_VM_PURGEABLE_TOKEN_DELETE = Constant('DBG_VM_PURGEABLE_TOKEN_DELETE',0x041)
|
||||
DBG_VM_PURGEABLE_TOKEN_RIPEN = Constant('DBG_VM_PURGEABLE_TOKEN_RIPEN',0x042)
|
||||
DBG_VM_PURGEABLE_OBJECT_ADD = Constant('DBG_VM_PURGEABLE_OBJECT_ADD',0x048)
|
||||
DBG_VM_PURGEABLE_OBJECT_REMOVE = Constant('DBG_VM_PURGEABLE_OBJECT_REMOVE',0x049)
|
||||
DBG_VM_PURGEABLE_OBJECT_PURGE = Constant('DBG_VM_PURGEABLE_OBJECT_PURGE',0x04a)
|
||||
DBG_VM_PURGEABLE_OBJECT_PURGE_ALL = Constant('DBG_VM_PURGEABLE_OBJECT_PURGE_ALL',0x04b)
|
||||
DBG_VM_PURGEABLE_OBJECT_PURGE_ONE = Constant('DBG_VM_PURGEABLE_OBJECT_PURGE_ONE',0x04c)
|
||||
DBG_VM_PURGEABLE_OBJECT_PURGE_LOOP = Constant('DBG_VM_PURGEABLE_OBJECT_PURGE_LOOP',0x04e)
|
||||
DBG_VM_MAP_PARTIAL_REAP = Constant('DBG_VM_MAP_PARTIAL_REAP',0x054)
|
||||
DBG_VM_MAP_WILLNEED = Constant('DBG_VM_MAP_WILLNEED',0x055)
|
||||
DBG_VM_FAULT_CHECK_ZFDELAY = Constant('DBG_VM_FAULT_CHECK_ZFDELAY',0x100)
|
||||
DBG_VM_FAULT_COWDELAY = Constant('DBG_VM_FAULT_COWDELAY',0x101)
|
||||
DBG_VM_FAULT_ZFDELAY = Constant('DBG_VM_FAULT_ZFDELAY',0x102)
|
||||
DBG_VM_FAULT_COMPRESSORDELAY = Constant('DBG_VM_FAULT_COMPRESSORDELAY',0x103)
|
||||
DBG_VM_PAGEOUT_SCAN = Constant('DBG_VM_PAGEOUT_SCAN',0x104)
|
||||
DBG_VM_PAGEOUT_BALANCE = Constant('DBG_VM_PAGEOUT_BALANCE',0x105)
|
||||
DBG_VM_PAGEOUT_FREELIST = Constant('DBG_VM_PAGEOUT_FREELIST',0x106)
|
||||
DBG_VM_PAGEOUT_PURGEONE = Constant('DBG_VM_PAGEOUT_PURGEONE',0x107)
|
||||
DBG_VM_PAGEOUT_CACHE_EVICT = Constant('DBG_VM_PAGEOUT_CACHE_EVICT',0x108)
|
||||
DBG_VM_PAGEOUT_THREAD_BLOCK = Constant('DBG_VM_PAGEOUT_THREAD_BLOCK',0x109)
|
||||
DBG_VM_PAGEOUT_JETSAM = Constant('DBG_VM_PAGEOUT_JETSAM',0x10A)
|
||||
DBG_VM_INFO1 = Constant('DBG_VM_INFO1',0x10B)
|
||||
DBG_VM_INFO2 = Constant('DBG_VM_INFO2',0x10C)
|
||||
DBG_VM_INFO3 = Constant('DBG_VM_INFO3',0x10D)
|
||||
DBG_VM_INFO4 = Constant('DBG_VM_INFO4',0x10E)
|
||||
DBG_VM_INFO5 = Constant('DBG_VM_INFO5',0x10F)
|
||||
DBG_VM_INFO6 = Constant('DBG_VM_INFO6',0x110)
|
||||
DBG_VM_INFO7 = Constant('DBG_VM_INFO7',0x111)
|
||||
DBG_VM_INFO8 = Constant('DBG_VM_INFO8',0x112)
|
||||
DBG_VM_INFO9 = Constant('DBG_VM_INFO9',0x113)
|
||||
DBG_VM_INFO10 = Constant('DBG_VM_INFO10',0x114)
|
||||
DBG_VM_UPL_PAGE_WAIT = Constant('DBG_VM_UPL_PAGE_WAIT',0x120)
|
||||
DBG_VM_IOPL_PAGE_WAIT = Constant('DBG_VM_IOPL_PAGE_WAIT',0x121)
|
||||
DBG_VM_PAGE_WAIT_BLOCK = Constant('DBG_VM_PAGE_WAIT_BLOCK',0x122)
|
||||
DBG_VM_PAGE_SLEEP = Constant('DBG_VM_PAGE_SLEEP',0x123)
|
||||
DBG_VM_PAGE_EXPEDITE = Constant('DBG_VM_PAGE_EXPEDITE',0x124)
|
||||
DBG_VM_PAGE_EXPEDITE_NO_MEMORY = Constant('DBG_VM_PAGE_EXPEDITE_NO_MEMORY',0x125)
|
||||
DBG_VM_PAGE_GRAB = Constant('DBG_VM_PAGE_GRAB',0x126)
|
||||
DBG_VM_PAGE_RELEASE = Constant('DBG_VM_PAGE_RELEASE',0x127)
|
||||
DBG_VM_COMPRESSOR_COMPACT_AND_SWAP = Constant('DBG_VM_COMPRESSOR_COMPACT_AND_SWAP',0x128)
|
||||
DBG_VM_COMPRESSOR_DELAYED_COMPACT = Constant('DBG_VM_COMPRESSOR_DELAYED_COMPACT',0x129)
|
||||
DBG_VM_OBJECT_SLEEP = Constant('DBG_VM_OBJECT_SLEEP',0x12a)
|
||||
DBG_VM_PAGE_WAKEUP = Constant('DBG_VM_PAGE_WAKEUP',0x12b)
|
||||
DBG_VM_PAGE_WAKEUP_DONE = Constant('DBG_VM_PAGE_WAKEUP_DONE',0x12c)
|
||||
DBG_VM_PRESSURE_EVENT = Constant('DBG_VM_PRESSURE_EVENT',0x130)
|
||||
DBG_VM_EXECVE = Constant('DBG_VM_EXECVE',0x131)
|
||||
DBG_VM_WAKEUP_COMPACTOR_SWAPPER = Constant('DBG_VM_WAKEUP_COMPACTOR_SWAPPER',0x132)
|
||||
DBG_VM_UPL_REQUEST = Constant('DBG_VM_UPL_REQUEST',0x133)
|
||||
DBG_VM_IOPL_REQUEST = Constant('DBG_VM_IOPL_REQUEST',0x134)
|
||||
DBG_VM_KERN_REQUEST = Constant('DBG_VM_KERN_REQUEST',0x135)
|
||||
DBG_VM_DATA_WRITE = Constant('DBG_VM_DATA_WRITE',0x140)
|
||||
DBG_VM_PRESSURE_LEVEL_CHANGE = Constant('DBG_VM_PRESSURE_LEVEL_CHANGE',0x141)
|
||||
DBG_VM_PHYS_WRITE_ACCT = Constant('DBG_VM_PHYS_WRITE_ACCT',0x142)
|
||||
DBG_VM_MAP_LOOKUP_ENTRY_FAILURE = Constant('DBG_VM_MAP_LOOKUP_ENTRY_FAILURE',0x143)
|
||||
VM_DISCONNECT_ALL_PAGE_MAPPINGS = Constant('VM_DISCONNECT_ALL_PAGE_MAPPINGS',0x00)
|
||||
VM_DISCONNECT_TASK_PAGE_MAPPINGS = Constant('VM_DISCONNECT_TASK_PAGE_MAPPINGS',0x01)
|
||||
VM_REAL_FAULT_ADDR_INTERNAL = Constant('VM_REAL_FAULT_ADDR_INTERNAL',0x02)
|
||||
VM_REAL_FAULT_ADDR_PURGABLE = Constant('VM_REAL_FAULT_ADDR_PURGABLE',0x03)
|
||||
VM_REAL_FAULT_ADDR_EXTERNAL = Constant('VM_REAL_FAULT_ADDR_EXTERNAL',0x04)
|
||||
VM_REAL_FAULT_ADDR_SHAREDCACHE = Constant('VM_REAL_FAULT_ADDR_SHAREDCACHE',0x05)
|
||||
VM_REAL_FAULT_FAST = Constant('VM_REAL_FAULT_FAST',0x06)
|
||||
VM_REAL_FAULT_SLOW = Constant('VM_REAL_FAULT_SLOW',0x07)
|
||||
VM_MAP_LOOKUP_OBJECT = Constant('VM_MAP_LOOKUP_OBJECT',0x08)
|
||||
DBG_ZERO_FILL_FAULT = Constant('DBG_ZERO_FILL_FAULT',0x01)
|
||||
DBG_PAGEIN_FAULT = Constant('DBG_PAGEIN_FAULT',0x02)
|
||||
DBG_COW_FAULT = Constant('DBG_COW_FAULT',0x03)
|
||||
DBG_CACHE_HIT_FAULT = Constant('DBG_CACHE_HIT_FAULT',0x04)
|
||||
DBG_NZF_PAGE_FAULT = Constant('DBG_NZF_PAGE_FAULT',0x05)
|
||||
DBG_GUARD_FAULT = Constant('DBG_GUARD_FAULT',0x06)
|
||||
DBG_PAGEINV_FAULT = Constant('DBG_PAGEINV_FAULT',0x07)
|
||||
DBG_PAGEIND_FAULT = Constant('DBG_PAGEIND_FAULT',0x08)
|
||||
DBG_COMPRESSOR_FAULT = Constant('DBG_COMPRESSOR_FAULT',0x09)
|
||||
DBG_COMPRESSOR_SWAPIN_FAULT = Constant('DBG_COMPRESSOR_SWAPIN_FAULT',0x0a)
|
||||
DBG_COR_FAULT = Constant('DBG_COR_FAULT',0x0b)
|
||||
MACH_TASK_SUSPEND = Constant('MACH_TASK_SUSPEND',0x0)
|
||||
MACH_TASK_RESUME = Constant('MACH_TASK_RESUME',0x1)
|
||||
MACH_THREAD_SET_VOUCHER = Constant('MACH_THREAD_SET_VOUCHER',0x2)
|
||||
@@ -1282,6 +1384,31 @@ MACH_IPC_KMSG_INFO = Constant('MACH_IPC_KMSG_INFO',0xa)
|
||||
MACH_IPC_KMSG_LINK = Constant('MACH_IPC_KMSG_LINK',0xb)
|
||||
MACH_IPC_PORT_ENTRY_MODIFY = Constant('MACH_IPC_PORT_ENTRY_MODIFY',0xc)
|
||||
MACH_IPC_DESTROY_GUARDED_DESC = Constant('MACH_IPC_DESTROY_GUARDED_DESC',0xd)
|
||||
MACH_THREAD_SUSPEND = Constant('MACH_THREAD_SUSPEND',0xe)
|
||||
MACH_THREAD_RESUME = Constant('MACH_THREAD_RESUME',0xf)
|
||||
MACH_EXCLAVES_SWITCH = Constant('MACH_EXCLAVES_SWITCH',0x0)
|
||||
MACH_EXCLAVES_XNUPROXY = Constant('MACH_EXCLAVES_XNUPROXY',0x1)
|
||||
MACH_EXCLAVES_RPC = Constant('MACH_EXCLAVES_RPC',0x2)
|
||||
MACH_EXCLAVES_UPCALL = Constant('MACH_EXCLAVES_UPCALL',0x3)
|
||||
MACH_EXCLAVES_BOOT_TASK = Constant('MACH_EXCLAVES_BOOT_TASK',0x4)
|
||||
MACH_EXCLAVES_SCHEDULER_YIELD = Constant('MACH_EXCLAVES_SCHEDULER_YIELD',0x0)
|
||||
MACH_EXCLAVES_SCHEDULER_SPAWNED = Constant('MACH_EXCLAVES_SCHEDULER_SPAWNED',0x1)
|
||||
MACH_EXCLAVES_SCHEDULER_TERMINATED = Constant('MACH_EXCLAVES_SCHEDULER_TERMINATED',0x2)
|
||||
MACH_EXCLAVES_SCHEDULER_WAIT = Constant('MACH_EXCLAVES_SCHEDULER_WAIT',0x3)
|
||||
MACH_EXCLAVES_SCHEDULER_WAKE = Constant('MACH_EXCLAVES_SCHEDULER_WAKE',0x4)
|
||||
MACH_EXCLAVES_SCHEDULER_SUSPENDED = Constant('MACH_EXCLAVES_SCHEDULER_SUSPENDED',0x5)
|
||||
MACH_EXCLAVES_SCHEDULER_RESUMED = Constant('MACH_EXCLAVES_SCHEDULER_RESUMED',0x6)
|
||||
MACH_EXCLAVES_SCHEDULER_INTERRUPTED = Constant('MACH_EXCLAVES_SCHEDULER_INTERRUPTED',0x7)
|
||||
MACH_EXCLAVES_SCHEDULER_NOTHING_SCHEDULED = Constant('MACH_EXCLAVES_SCHEDULER_NOTHING_SCHEDULED',0x8)
|
||||
MACH_EXCLAVES_SCHEDULER_ALL_EXCLAVES_BOOTED = Constant('MACH_EXCLAVES_SCHEDULER_ALL_EXCLAVES_BOOTED',0x9)
|
||||
MACH_EXCLAVES_SCHEDULER_EARLY_ALLOC = Constant('MACH_EXCLAVES_SCHEDULER_EARLY_ALLOC',0xa)
|
||||
MACH_EPOCH_SYNC_WAIT_STALE = Constant('MACH_EPOCH_SYNC_WAIT_STALE',0x0)
|
||||
MACH_EPOCH_SYNC_WAIT = Constant('MACH_EPOCH_SYNC_WAIT',0x1)
|
||||
MACH_EPOCH_SYNC_WAKE_NO_WAITERS = Constant('MACH_EPOCH_SYNC_WAKE_NO_WAITERS',0x2)
|
||||
MACH_EPOCH_SYNC_WAKE_ONE = Constant('MACH_EPOCH_SYNC_WAKE_ONE',0x3)
|
||||
MACH_EPOCH_SYNC_WAKE_ALL = Constant('MACH_EPOCH_SYNC_WAKE_ALL',0x4)
|
||||
MACH_EPOCH_SYNC_WAKE_ONE_WITH_OWNER = Constant('MACH_EPOCH_SYNC_WAKE_ONE_WITH_OWNER',0x5)
|
||||
MACH_EPOCH_SYNC_WAKE_THREAD = Constant('MACH_EPOCH_SYNC_WAKE_THREAD',0x6)
|
||||
MACH_THREAD_GROUP_NEW = Constant('MACH_THREAD_GROUP_NEW',0x0)
|
||||
MACH_THREAD_GROUP_FREE = Constant('MACH_THREAD_GROUP_FREE',0x1)
|
||||
MACH_THREAD_GROUP_SET = Constant('MACH_THREAD_GROUP_SET',0x2)
|
||||
@@ -1424,6 +1551,13 @@ HV_X86_VM_MAP_TRAP = Constant('HV_X86_VM_MAP_TRAP',0x2a)
|
||||
HV_X86_VM_PROTECT_TRAP = Constant('HV_X86_VM_PROTECT_TRAP',0x2b)
|
||||
HV_X86_VM_UNMAP_TRAP = Constant('HV_X86_VM_UNMAP_TRAP',0x2c)
|
||||
HV_X86_TSC_OFFSET_SET = Constant('HV_X86_TSC_OFFSET_SET',0x2d)
|
||||
VM_RECLAIM_UPDATE_ACCOUNTING = Constant('VM_RECLAIM_UPDATE_ACCOUNTING',0x01)
|
||||
VM_RECLAIM_ENTRIES = Constant('VM_RECLAIM_ENTRIES',0x02)
|
||||
VM_RECLAIM_CHUNK = Constant('VM_RECLAIM_CHUNK',0x03)
|
||||
VM_RECLAIM_ENTRY = Constant('VM_RECLAIM_ENTRY',0x04)
|
||||
VM_RECLAIM_ALL_MEMORY = Constant('VM_RECLAIM_ALL_MEMORY',0x05)
|
||||
VM_RECLAIM_ASYNC_MEMORY = Constant('VM_RECLAIM_ASYNC_MEMORY',0x06)
|
||||
VM_RECLAIM_INIT = Constant('VM_RECLAIM_INIT',0x07)
|
||||
DBG_NETIP = Constant('DBG_NETIP',1)
|
||||
DBG_NETARP = Constant('DBG_NETARP',2)
|
||||
DBG_NETUDP = Constant('DBG_NETUDP',3)
|
||||
@@ -2109,6 +2243,7 @@ XATTR_REPLACE = Constant('XATTR_REPLACE',0x0004)
|
||||
XATTR_NOSECURITY = Constant('XATTR_NOSECURITY',0x0008)
|
||||
XATTR_NODEFAULT = Constant('XATTR_NODEFAULT',0x0010)
|
||||
XATTR_SHOWCOMPRESSION = Constant('XATTR_SHOWCOMPRESSION',0x0020)
|
||||
XATTR_NOFOLLOW_ANY = Constant('XATTR_NOFOLLOW_ANY',0x0040)
|
||||
XATTR_MAXNAMELEN = Constant('XATTR_MAXNAMELEN',127)
|
||||
PR_SLOWHZ = Constant('PR_SLOWHZ',2)
|
||||
PRC_IFDOWN = Constant('PRC_IFDOWN',0)
|
||||
@@ -2142,6 +2277,7 @@ CTL_FLAG_REG_ID_UNIT = Constant('CTL_FLAG_REG_ID_UNIT',0x2)
|
||||
CTL_FLAG_REG_SOCK_STREAM = Constant('CTL_FLAG_REG_SOCK_STREAM',0x4)
|
||||
CTL_DATA_NOWAKEUP = Constant('CTL_DATA_NOWAKEUP',0x1)
|
||||
CTL_DATA_EOR = Constant('CTL_DATA_EOR',0x2)
|
||||
__has_safe_buffers = Constant('__has_safe_buffers',0)
|
||||
__DARWIN_ONLY_64_BIT_INO_T = Constant('__DARWIN_ONLY_64_BIT_INO_T',0)
|
||||
__DARWIN_ONLY_UNIX_CONFORMANCE = Constant('__DARWIN_ONLY_UNIX_CONFORMANCE',0)
|
||||
__DARWIN_ONLY_VERS_1050 = Constant('__DARWIN_ONLY_VERS_1050',0)
|
||||
@@ -2479,7 +2615,8 @@ VQ_QUOTA = Constant('VQ_QUOTA',0x1000)
|
||||
VQ_NEARLOWDISK = Constant('VQ_NEARLOWDISK',0x2000)
|
||||
VQ_DESIRED_DISK = Constant('VQ_DESIRED_DISK',0x4000)
|
||||
VQ_FREE_SPACE_CHANGE = Constant('VQ_FREE_SPACE_CHANGE',0x8000)
|
||||
VQ_FLAG10000 = Constant('VQ_FLAG10000',0x10000)
|
||||
VQ_PURGEABLE_SPACE_CHANGE = Constant('VQ_PURGEABLE_SPACE_CHANGE',0x10000)
|
||||
VQ_FLAG20000 = Constant('VQ_FLAG20000',0x20000)
|
||||
VFS_IOATTR_FLAGS_FUA = Constant('VFS_IOATTR_FLAGS_FUA',0x00000001)
|
||||
VFS_IOATTR_FLAGS_UNMAP = Constant('VFS_IOATTR_FLAGS_UNMAP',0x00000002)
|
||||
VFS_IOATTR_FLAGS_SWAPPIN_SUPPORTED = Constant('VFS_IOATTR_FLAGS_SWAPPIN_SUPPORTED',0x00000010)
|
||||
@@ -2510,7 +2647,7 @@ LK_NOWAIT = Constant('LK_NOWAIT',1)
|
||||
NFSV4_MAX_FH_SIZE = Constant('NFSV4_MAX_FH_SIZE',128)
|
||||
NFSV3_MAX_FH_SIZE = Constant('NFSV3_MAX_FH_SIZE',64)
|
||||
NFSV2_MAX_FH_SIZE = Constant('NFSV2_MAX_FH_SIZE',32)
|
||||
CRYPTEX_AUTH_STRUCT_VERSION = Constant('CRYPTEX_AUTH_STRUCT_VERSION',1)
|
||||
CRYPTEX_AUTH_STRUCT_VERSION = Constant('CRYPTEX_AUTH_STRUCT_VERSION',2)
|
||||
EV_FD = Constant('EV_FD',1)
|
||||
EV_RE = Constant('EV_RE',1)
|
||||
EV_WR = Constant('EV_WR',2)
|
||||
@@ -2534,6 +2671,10 @@ KDEBUG_LEVEL_STANDARD = Constant('KDEBUG_LEVEL_STANDARD',2)
|
||||
KDEBUG_LEVEL_FULL = Constant('KDEBUG_LEVEL_FULL',3)
|
||||
KDBG_FLAG_FILTERED = Constant('KDBG_FLAG_FILTERED',0x01)
|
||||
KDBG_FLAG_NOPROCFILT = Constant('KDBG_FLAG_NOPROCFILT',0x02)
|
||||
__DARWIN_LITTLE_ENDIAN = Constant('__DARWIN_LITTLE_ENDIAN',1234)
|
||||
__DARWIN_BIG_ENDIAN = Constant('__DARWIN_BIG_ENDIAN',4321)
|
||||
__DARWIN_PDP_ENDIAN = Constant('__DARWIN_PDP_ENDIAN',3412)
|
||||
USE_CLANG_TYPES = Constant('USE_CLANG_TYPES',0)
|
||||
__DARWIN_NULL = Constant('__DARWIN_NULL',0)
|
||||
UBC_PUSHDIRTY = Constant('UBC_PUSHDIRTY',0x01)
|
||||
UBC_PUSHALL = Constant('UBC_PUSHALL',0x02)
|
||||
@@ -3069,7 +3210,9 @@ SYS_record_system_event = Constant('SYS_record_system_event',552)
|
||||
SYS_mkfifoat = Constant('SYS_mkfifoat',553)
|
||||
SYS_mknodat = Constant('SYS_mknodat',554)
|
||||
SYS_ungraftdmg = Constant('SYS_ungraftdmg',555)
|
||||
SYS_MAXSYSCALL = Constant('SYS_MAXSYSCALL',556)
|
||||
SYS_coalition_policy_set = Constant('SYS_coalition_policy_set',556)
|
||||
SYS_coalition_policy_get = Constant('SYS_coalition_policy_get',557)
|
||||
SYS_MAXSYSCALL = Constant('SYS_MAXSYSCALL',558)
|
||||
SYS_invalid = Constant('SYS_invalid',63)
|
||||
SOCK_STREAM = Constant('SOCK_STREAM',1)
|
||||
SOCK_DGRAM = Constant('SOCK_DGRAM',2)
|
||||
@@ -3117,6 +3260,7 @@ SO_NUMRCVPKT = Constant('SO_NUMRCVPKT',0x1112)
|
||||
SO_NET_SERVICE_TYPE = Constant('SO_NET_SERVICE_TYPE',0x1116)
|
||||
SO_NETSVC_MARKING_LEVEL = Constant('SO_NETSVC_MARKING_LEVEL',0x1119)
|
||||
SO_RESOLVER_SIGNATURE = Constant('SO_RESOLVER_SIGNATURE',0x1131)
|
||||
SO_BINDTODEVICE = Constant('SO_BINDTODEVICE',0x1134)
|
||||
NET_SERVICE_TYPE_BE = Constant('NET_SERVICE_TYPE_BE',0)
|
||||
NET_SERVICE_TYPE_BK = Constant('NET_SERVICE_TYPE_BK',1)
|
||||
NET_SERVICE_TYPE_SIG = Constant('NET_SERVICE_TYPE_SIG',2)
|
||||
|
||||
@@ -88,6 +88,7 @@ VOL_CAP_FMT_NO_PERMISSIONS = Constant('VOL_CAP_FMT_NO_PERMISSIONS',0x00400000)
|
||||
VOL_CAP_FMT_SHARED_SPACE = Constant('VOL_CAP_FMT_SHARED_SPACE',0x00800000)
|
||||
VOL_CAP_FMT_VOL_GROUPS = Constant('VOL_CAP_FMT_VOL_GROUPS',0x01000000)
|
||||
VOL_CAP_FMT_SEALED = Constant('VOL_CAP_FMT_SEALED',0x02000000)
|
||||
VOL_CAP_FMT_CLONE_MAPPING = Constant('VOL_CAP_FMT_CLONE_MAPPING',0x04000000)
|
||||
VOL_CAP_INT_SEARCHFS = Constant('VOL_CAP_INT_SEARCHFS',0x00000001)
|
||||
VOL_CAP_INT_ATTRLIST = Constant('VOL_CAP_INT_ATTRLIST',0x00000002)
|
||||
VOL_CAP_INT_NFSEXPORT = Constant('VOL_CAP_INT_NFSEXPORT',0x00000004)
|
||||
@@ -109,6 +110,8 @@ VOL_CAP_INT_RENAME_SWAP = Constant('VOL_CAP_INT_RENAME_SWAP',0x00040000)
|
||||
VOL_CAP_INT_RENAME_EXCL = Constant('VOL_CAP_INT_RENAME_EXCL',0x00080000)
|
||||
VOL_CAP_INT_RENAME_OPENFAIL = Constant('VOL_CAP_INT_RENAME_OPENFAIL',0x00100000)
|
||||
VOL_CAP_INT_RENAME_SECLUDE = Constant('VOL_CAP_INT_RENAME_SECLUDE',0x00200000)
|
||||
VOL_CAP_INT_ATTRIBUTION_TAG = Constant('VOL_CAP_INT_ATTRIBUTION_TAG',0x00400000)
|
||||
VOL_CAP_INT_PUNCHHOLE = Constant('VOL_CAP_INT_PUNCHHOLE',0x00800000)
|
||||
ATTR_CMN_NAME = Constant('ATTR_CMN_NAME',0x00000001)
|
||||
ATTR_CMN_DEVID = Constant('ATTR_CMN_DEVID',0x00000002)
|
||||
ATTR_CMN_FSID = Constant('ATTR_CMN_FSID',0x00000004)
|
||||
@@ -293,6 +296,8 @@ IO_SYSCALL_DISPATCH = Constant('IO_SYSCALL_DISPATCH',0x100000)
|
||||
IO_SWAP_DISPATCH = Constant('IO_SWAP_DISPATCH',0x200000)
|
||||
IO_SKIP_ENCRYPTION = Constant('IO_SKIP_ENCRYPTION',0x400000)
|
||||
IO_EVTONLY = Constant('IO_EVTONLY',0x800000)
|
||||
IO_NOCACHE_SYSSPACE = Constant('IO_NOCACHE_SYSSPACE',0x1000000)
|
||||
IO_NOCACHE_SWRITE = Constant('IO_NOCACHE_SWRITE',0x2000000)
|
||||
LOOKUP = Constant('LOOKUP',0)
|
||||
CREATE = Constant('CREATE',1)
|
||||
DELETE = Constant('DELETE',2)
|
||||
@@ -347,6 +352,7 @@ VNODE_UPDATE_PURGE = Constant('VNODE_UPDATE_PURGE',0x08)
|
||||
VNODE_LOOKUP_NOFOLLOW = Constant('VNODE_LOOKUP_NOFOLLOW',0x01)
|
||||
VNODE_LOOKUP_NOCROSSMOUNT = Constant('VNODE_LOOKUP_NOCROSSMOUNT',0x02)
|
||||
VNODE_LOOKUP_CROSSMOUNTNOWAIT = Constant('VNODE_LOOKUP_CROSSMOUNTNOWAIT',0x04)
|
||||
VNODE_LOOKUP_NOFOLLOW_ANY = Constant('VNODE_LOOKUP_NOFOLLOW_ANY',0x08)
|
||||
VNODE_RELOAD = Constant('VNODE_RELOAD',0x01)
|
||||
VNODE_WAIT = Constant('VNODE_WAIT',0x02)
|
||||
VNODE_WRITEABLE = Constant('VNODE_WRITEABLE',0x04)
|
||||
@@ -425,7 +431,7 @@ LOCKPARENT = Constant('LOCKPARENT',0x0008)
|
||||
WANTPARENT = Constant('WANTPARENT',0x0010)
|
||||
UIO_MAXIOV = Constant('UIO_MAXIOV',1024)
|
||||
UIO_SMALLIOV = Constant('UIO_SMALLIOV',8)
|
||||
EVFILT_SYSCOUNT = Constant('EVFILT_SYSCOUNT',17)
|
||||
EVFILT_SYSCOUNT = Constant('EVFILT_SYSCOUNT',18)
|
||||
KEVENT_FLAG_NONE = Constant('KEVENT_FLAG_NONE',0x000000)
|
||||
KEVENT_FLAG_IMMEDIATE = Constant('KEVENT_FLAG_IMMEDIATE',0x000001)
|
||||
KEVENT_FLAG_ERROR_EVENTS = Constant('KEVENT_FLAG_ERROR_EVENTS',0x000002)
|
||||
@@ -503,6 +509,7 @@ IMGPF_IS_64BIT_ADDR = Constant('IMGPF_IS_64BIT_ADDR',0x00000008)
|
||||
IMGPF_SPAWN = Constant('IMGPF_SPAWN',0x00000010)
|
||||
IMGPF_DISABLE_ASLR = Constant('IMGPF_DISABLE_ASLR',0x00000020)
|
||||
IMGPF_ALLOW_DATA_EXEC = Constant('IMGPF_ALLOW_DATA_EXEC',0x00000040)
|
||||
IMGPF_3P_PLUGINS = Constant('IMGPF_3P_PLUGINS',0x00000080)
|
||||
IMGPF_EXEC = Constant('IMGPF_EXEC',0x00000100)
|
||||
IMGPF_HIGH_BITS_ASLR = Constant('IMGPF_HIGH_BITS_ASLR',0x00000200)
|
||||
IMGPF_IS_64BIT_DATA = Constant('IMGPF_IS_64BIT_DATA',0x00000400)
|
||||
@@ -512,6 +519,7 @@ IMGPF_PLUGIN_HOST_DISABLE_A_KEYS = Constant('IMGPF_PLUGIN_HOST_DISABLE_A_KEYS',0
|
||||
IMGPF_HW_TPRO = Constant('IMGPF_HW_TPRO',0x00004000)
|
||||
IMGPF_ROSETTA = Constant('IMGPF_ROSETTA',0x10000000)
|
||||
IMGPF_ALT_ROSETTA = Constant('IMGPF_ALT_ROSETTA',0x20000000)
|
||||
IMGPF_RESERVED_2 = Constant('IMGPF_RESERVED_2',0x40000000)
|
||||
IMGPF_NOJOP = Constant('IMGPF_NOJOP',0x80000000)
|
||||
IMGPF_SB_DEFAULT = Constant('IMGPF_SB_DEFAULT',0)
|
||||
IMGPF_SB_TRUE = Constant('IMGPF_SB_TRUE',1)
|
||||
@@ -560,9 +568,34 @@ WSTOPPED = Constant('WSTOPPED',0x00000008)
|
||||
WCONTINUED = Constant('WCONTINUED',0x00000010)
|
||||
WNOWAIT = Constant('WNOWAIT',0x00000020)
|
||||
WAIT_MYPGRP = Constant('WAIT_MYPGRP',0)
|
||||
PRIO_DARWIN_GPU = Constant('PRIO_DARWIN_GPU',5)
|
||||
PRIO_DARWIN_GPU_ALLOW = Constant('PRIO_DARWIN_GPU_ALLOW',0x1)
|
||||
PRIO_DARWIN_GPU_DENY = Constant('PRIO_DARWIN_GPU_DENY',0x2)
|
||||
PRIO_DARWIN_ROLE = Constant('PRIO_DARWIN_ROLE',6)
|
||||
PRIO_DARWIN_ROLE_DEFAULT = Constant('PRIO_DARWIN_ROLE_DEFAULT',0x0)
|
||||
PRIO_DARWIN_ROLE_UI_FOCAL = Constant('PRIO_DARWIN_ROLE_UI_FOCAL',0x1)
|
||||
PRIO_DARWIN_ROLE_UI = Constant('PRIO_DARWIN_ROLE_UI',0x2)
|
||||
PRIO_DARWIN_ROLE_NON_UI = Constant('PRIO_DARWIN_ROLE_NON_UI',0x3)
|
||||
PRIO_DARWIN_ROLE_UI_NON_FOCAL = Constant('PRIO_DARWIN_ROLE_UI_NON_FOCAL',0x4)
|
||||
PRIO_DARWIN_ROLE_TAL_LAUNCH = Constant('PRIO_DARWIN_ROLE_TAL_LAUNCH',0x5)
|
||||
PRIO_DARWIN_ROLE_DARWIN_BG = Constant('PRIO_DARWIN_ROLE_DARWIN_BG',0x6)
|
||||
PRIO_DARWIN_GAME_MODE = Constant('PRIO_DARWIN_GAME_MODE',7)
|
||||
PRIO_DARWIN_CARPLAY_MODE = Constant('PRIO_DARWIN_CARPLAY_MODE',8)
|
||||
PRIO_DARWIN_GAME_MODE_OFF = Constant('PRIO_DARWIN_GAME_MODE_OFF',0x0)
|
||||
PRIO_DARWIN_GAME_MODE_ON = Constant('PRIO_DARWIN_GAME_MODE_ON',0x1)
|
||||
PRIO_DARWIN_CARPLAY_MODE_OFF = Constant('PRIO_DARWIN_CARPLAY_MODE_OFF',0x0)
|
||||
PRIO_DARWIN_CARPLAY_MODE_ON = Constant('PRIO_DARWIN_CARPLAY_MODE_ON',0x1)
|
||||
IOMON_ENABLE = Constant('IOMON_ENABLE',0x01)
|
||||
IOMON_DISABLE = Constant('IOMON_DISABLE',0x02)
|
||||
IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY = Constant('IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY',1)
|
||||
IOPOL_TYPE_VFS_ALTLINK = Constant('IOPOL_TYPE_VFS_ALTLINK',11)
|
||||
IOPOL_TYPE_VFS_NOCACHE_WRITE_FS_BLKSIZE = Constant('IOPOL_TYPE_VFS_NOCACHE_WRITE_FS_BLKSIZE',12)
|
||||
IOPOL_VFS_HFS_CASE_SENSITIVITY_DEFAULT = Constant('IOPOL_VFS_HFS_CASE_SENSITIVITY_DEFAULT',0)
|
||||
IOPOL_VFS_HFS_CASE_SENSITIVITY_FORCE_CASE_SENSITIVE = Constant('IOPOL_VFS_HFS_CASE_SENSITIVITY_FORCE_CASE_SENSITIVE',1)
|
||||
IOPOL_VFS_ALTLINK_DISABLED = Constant('IOPOL_VFS_ALTLINK_DISABLED',0)
|
||||
IOPOL_VFS_ALTLINK_ENABLED = Constant('IOPOL_VFS_ALTLINK_ENABLED',1)
|
||||
IOPOL_CMD_GET = Constant('IOPOL_CMD_GET',0x00000001)
|
||||
IOPOL_CMD_SET = Constant('IOPOL_CMD_SET',0x00000002)
|
||||
IPC_CREAT = Constant('IPC_CREAT',0o001000)
|
||||
IPC_EXCL = Constant('IPC_EXCL',0o002000)
|
||||
IPC_NOWAIT = Constant('IPC_NOWAIT',0o004000)
|
||||
@@ -677,6 +710,7 @@ F_SETLEASE = Constant('F_SETLEASE',106)
|
||||
F_GETLEASE = Constant('F_GETLEASE',107)
|
||||
F_TRANSFEREXTENTS = Constant('F_TRANSFEREXTENTS',110)
|
||||
F_ATTRIBUTION_TAG = Constant('F_ATTRIBUTION_TAG',111)
|
||||
F_ADDSIGS_MAIN_BINARY = Constant('F_ADDSIGS_MAIN_BINARY',113)
|
||||
FCNTL_FS_SPECIFIC_BASE = Constant('FCNTL_FS_SPECIFIC_BASE',0x00010000)
|
||||
F_DUPFD_CLOEXEC = Constant('F_DUPFD_CLOEXEC',67)
|
||||
FD_CLOEXEC = Constant('FD_CLOEXEC',1)
|
||||
@@ -904,6 +938,7 @@ MADV_FREE_REUSABLE = Constant('MADV_FREE_REUSABLE',7)
|
||||
MADV_FREE_REUSE = Constant('MADV_FREE_REUSE',8)
|
||||
MADV_CAN_REUSE = Constant('MADV_CAN_REUSE',9)
|
||||
MADV_PAGEOUT = Constant('MADV_PAGEOUT',10)
|
||||
MADV_ZERO = Constant('MADV_ZERO',11)
|
||||
MINCORE_INCORE = Constant('MINCORE_INCORE',0x1)
|
||||
MINCORE_REFERENCED = Constant('MINCORE_REFERENCED',0x2)
|
||||
MINCORE_MODIFIED = Constant('MINCORE_MODIFIED',0x4)
|
||||
@@ -1111,6 +1146,9 @@ DBG_MACH_EXCP_EMUL = Constant('DBG_MACH_EXCP_EMUL',0x0E)
|
||||
DBG_MACH_IHDLR = Constant('DBG_MACH_IHDLR',0x10)
|
||||
DBG_MACH_IPC = Constant('DBG_MACH_IPC',0x20)
|
||||
DBG_MACH_RESOURCE = Constant('DBG_MACH_RESOURCE',0x25)
|
||||
DBG_MACH_EXCLAVES = Constant('DBG_MACH_EXCLAVES',0x2A)
|
||||
DBG_MACH_EXCLAVES_SCHEDULER = Constant('DBG_MACH_EXCLAVES_SCHEDULER',0x2B)
|
||||
DBG_MACH_EPOCH_SYNC = Constant('DBG_MACH_EPOCH_SYNC',0x2C)
|
||||
DBG_MACH_VM = Constant('DBG_MACH_VM',0x30)
|
||||
DBG_MACH_LEAKS = Constant('DBG_MACH_LEAKS',0x31)
|
||||
DBG_MACH_WORKINGSET = Constant('DBG_MACH_WORKINGSET',0x32)
|
||||
@@ -1136,6 +1174,7 @@ DBG_MACH_HV = Constant('DBG_MACH_HV',0xAC)
|
||||
DBG_MACH_KCOV = Constant('DBG_MACH_KCOV',0xAD)
|
||||
DBG_MACH_MACHDEP_EXCP_SC_x86 = Constant('DBG_MACH_MACHDEP_EXCP_SC_x86',0xAE)
|
||||
DBG_MACH_MACHDEP_EXCP_SC_ARM = Constant('DBG_MACH_MACHDEP_EXCP_SC_ARM',0xAF)
|
||||
DBG_MACH_VM_RECLAIM = Constant('DBG_MACH_VM_RECLAIM',0xB0)
|
||||
DBC_MACH_IO_MMIO_READ = Constant('DBC_MACH_IO_MMIO_READ',0x1)
|
||||
DBC_MACH_IO_MMIO_WRITE = Constant('DBC_MACH_IO_MMIO_WRITE',0x2)
|
||||
DBC_MACH_IO_PHYS_READ = Constant('DBC_MACH_IO_PHYS_READ',0x3)
|
||||
@@ -1177,7 +1216,6 @@ MACH_RW_DEMOTE = Constant('MACH_RW_DEMOTE',0x1d)
|
||||
MACH_SCHED_MAINTENANCE = Constant('MACH_SCHED_MAINTENANCE',0x1f)
|
||||
MACH_DISPATCH = Constant('MACH_DISPATCH',0x20)
|
||||
MACH_QUANTUM_HANDOFF = Constant('MACH_QUANTUM_HANDOFF',0x21)
|
||||
MACH_MULTIQ_DEQUEUE = Constant('MACH_MULTIQ_DEQUEUE',0x22)
|
||||
MACH_SCHED_THREAD_SWITCH = Constant('MACH_SCHED_THREAD_SWITCH',0x23)
|
||||
MACH_SCHED_SMT_BALANCE = Constant('MACH_SCHED_SMT_BALANCE',0x24)
|
||||
MACH_REMOTE_DEFERRED_AST = Constant('MACH_REMOTE_DEFERRED_AST',0x25)
|
||||
@@ -1229,6 +1267,7 @@ MACH_RT_DISALLOWED_WORK_INTERVAL = Constant('MACH_RT_DISALLOWED_WORK_INTERVAL',0
|
||||
MACH_SCHED_WI_EXTERNAL_WAKEUP = Constant('MACH_SCHED_WI_EXTERNAL_WAKEUP',0x61)
|
||||
MACH_SCHED_AST_CHECK = Constant('MACH_SCHED_AST_CHECK',0x62)
|
||||
MACH_SCHED_PREEMPT_TIMER_ACTIVE = Constant('MACH_SCHED_PREEMPT_TIMER_ACTIVE',0x63)
|
||||
MACH_PROCESSOR_SHUTDOWN = Constant('MACH_PROCESSOR_SHUTDOWN',0x64)
|
||||
MACH_SCHED_CLUTCH_ROOT_BUCKET_STATE = Constant('MACH_SCHED_CLUTCH_ROOT_BUCKET_STATE',0x0)
|
||||
MACH_SCHED_CLUTCH_TG_BUCKET_STATE = Constant('MACH_SCHED_CLUTCH_TG_BUCKET_STATE',0x1)
|
||||
MACH_SCHED_CLUTCH_THREAD_SELECT = Constant('MACH_SCHED_CLUTCH_THREAD_SELECT',0x2)
|
||||
@@ -1254,20 +1293,83 @@ WORKGROUP_INTERVAL_SET_WORKLOAD_ID = Constant('WORKGROUP_INTERVAL_SET_WORKLOAD_I
|
||||
WORKGROUP_INTERVAL_SET_WORKLOAD_ID_NAME = Constant('WORKGROUP_INTERVAL_SET_WORKLOAD_ID_NAME',0x7)
|
||||
KCOV_STKSZ_THRESHOLD_ABOVE = Constant('KCOV_STKSZ_THRESHOLD_ABOVE',0x0)
|
||||
KCOV_STKSZ_THRESHOLD_BELOW = Constant('KCOV_STKSZ_THRESHOLD_BELOW',0x1)
|
||||
MACH_MULTIQ_BOUND = Constant('MACH_MULTIQ_BOUND',1)
|
||||
MACH_MULTIQ_GROUP = Constant('MACH_MULTIQ_GROUP',2)
|
||||
MACH_MULTIQ_GLOBAL = Constant('MACH_MULTIQ_GLOBAL',3)
|
||||
DBG_ZERO_FILL_FAULT = Constant('DBG_ZERO_FILL_FAULT',1)
|
||||
DBG_PAGEIN_FAULT = Constant('DBG_PAGEIN_FAULT',2)
|
||||
DBG_COW_FAULT = Constant('DBG_COW_FAULT',3)
|
||||
DBG_CACHE_HIT_FAULT = Constant('DBG_CACHE_HIT_FAULT',4)
|
||||
DBG_NZF_PAGE_FAULT = Constant('DBG_NZF_PAGE_FAULT',5)
|
||||
DBG_GUARD_FAULT = Constant('DBG_GUARD_FAULT',6)
|
||||
DBG_PAGEINV_FAULT = Constant('DBG_PAGEINV_FAULT',7)
|
||||
DBG_PAGEIND_FAULT = Constant('DBG_PAGEIND_FAULT',8)
|
||||
DBG_COMPRESSOR_FAULT = Constant('DBG_COMPRESSOR_FAULT',9)
|
||||
DBG_COMPRESSOR_SWAPIN_FAULT = Constant('DBG_COMPRESSOR_SWAPIN_FAULT',10)
|
||||
DBG_COR_FAULT = Constant('DBG_COR_FAULT',11)
|
||||
DBG_VM_VNODE_PAGEOUT = Constant('DBG_VM_VNODE_PAGEOUT',0x001)
|
||||
DBG_VM_FAULT_INTERNAL = Constant('DBG_VM_FAULT_INTERNAL',0x002)
|
||||
DBG_VM_PURGEABLE_TOKEN_ADD = Constant('DBG_VM_PURGEABLE_TOKEN_ADD',0x040)
|
||||
DBG_VM_PURGEABLE_TOKEN_DELETE = Constant('DBG_VM_PURGEABLE_TOKEN_DELETE',0x041)
|
||||
DBG_VM_PURGEABLE_TOKEN_RIPEN = Constant('DBG_VM_PURGEABLE_TOKEN_RIPEN',0x042)
|
||||
DBG_VM_PURGEABLE_OBJECT_ADD = Constant('DBG_VM_PURGEABLE_OBJECT_ADD',0x048)
|
||||
DBG_VM_PURGEABLE_OBJECT_REMOVE = Constant('DBG_VM_PURGEABLE_OBJECT_REMOVE',0x049)
|
||||
DBG_VM_PURGEABLE_OBJECT_PURGE = Constant('DBG_VM_PURGEABLE_OBJECT_PURGE',0x04a)
|
||||
DBG_VM_PURGEABLE_OBJECT_PURGE_ALL = Constant('DBG_VM_PURGEABLE_OBJECT_PURGE_ALL',0x04b)
|
||||
DBG_VM_PURGEABLE_OBJECT_PURGE_ONE = Constant('DBG_VM_PURGEABLE_OBJECT_PURGE_ONE',0x04c)
|
||||
DBG_VM_PURGEABLE_OBJECT_PURGE_LOOP = Constant('DBG_VM_PURGEABLE_OBJECT_PURGE_LOOP',0x04e)
|
||||
DBG_VM_MAP_PARTIAL_REAP = Constant('DBG_VM_MAP_PARTIAL_REAP',0x054)
|
||||
DBG_VM_MAP_WILLNEED = Constant('DBG_VM_MAP_WILLNEED',0x055)
|
||||
DBG_VM_FAULT_CHECK_ZFDELAY = Constant('DBG_VM_FAULT_CHECK_ZFDELAY',0x100)
|
||||
DBG_VM_FAULT_COWDELAY = Constant('DBG_VM_FAULT_COWDELAY',0x101)
|
||||
DBG_VM_FAULT_ZFDELAY = Constant('DBG_VM_FAULT_ZFDELAY',0x102)
|
||||
DBG_VM_FAULT_COMPRESSORDELAY = Constant('DBG_VM_FAULT_COMPRESSORDELAY',0x103)
|
||||
DBG_VM_PAGEOUT_SCAN = Constant('DBG_VM_PAGEOUT_SCAN',0x104)
|
||||
DBG_VM_PAGEOUT_BALANCE = Constant('DBG_VM_PAGEOUT_BALANCE',0x105)
|
||||
DBG_VM_PAGEOUT_FREELIST = Constant('DBG_VM_PAGEOUT_FREELIST',0x106)
|
||||
DBG_VM_PAGEOUT_PURGEONE = Constant('DBG_VM_PAGEOUT_PURGEONE',0x107)
|
||||
DBG_VM_PAGEOUT_CACHE_EVICT = Constant('DBG_VM_PAGEOUT_CACHE_EVICT',0x108)
|
||||
DBG_VM_PAGEOUT_THREAD_BLOCK = Constant('DBG_VM_PAGEOUT_THREAD_BLOCK',0x109)
|
||||
DBG_VM_PAGEOUT_JETSAM = Constant('DBG_VM_PAGEOUT_JETSAM',0x10A)
|
||||
DBG_VM_INFO1 = Constant('DBG_VM_INFO1',0x10B)
|
||||
DBG_VM_INFO2 = Constant('DBG_VM_INFO2',0x10C)
|
||||
DBG_VM_INFO3 = Constant('DBG_VM_INFO3',0x10D)
|
||||
DBG_VM_INFO4 = Constant('DBG_VM_INFO4',0x10E)
|
||||
DBG_VM_INFO5 = Constant('DBG_VM_INFO5',0x10F)
|
||||
DBG_VM_INFO6 = Constant('DBG_VM_INFO6',0x110)
|
||||
DBG_VM_INFO7 = Constant('DBG_VM_INFO7',0x111)
|
||||
DBG_VM_INFO8 = Constant('DBG_VM_INFO8',0x112)
|
||||
DBG_VM_INFO9 = Constant('DBG_VM_INFO9',0x113)
|
||||
DBG_VM_INFO10 = Constant('DBG_VM_INFO10',0x114)
|
||||
DBG_VM_UPL_PAGE_WAIT = Constant('DBG_VM_UPL_PAGE_WAIT',0x120)
|
||||
DBG_VM_IOPL_PAGE_WAIT = Constant('DBG_VM_IOPL_PAGE_WAIT',0x121)
|
||||
DBG_VM_PAGE_WAIT_BLOCK = Constant('DBG_VM_PAGE_WAIT_BLOCK',0x122)
|
||||
DBG_VM_PAGE_SLEEP = Constant('DBG_VM_PAGE_SLEEP',0x123)
|
||||
DBG_VM_PAGE_EXPEDITE = Constant('DBG_VM_PAGE_EXPEDITE',0x124)
|
||||
DBG_VM_PAGE_EXPEDITE_NO_MEMORY = Constant('DBG_VM_PAGE_EXPEDITE_NO_MEMORY',0x125)
|
||||
DBG_VM_PAGE_GRAB = Constant('DBG_VM_PAGE_GRAB',0x126)
|
||||
DBG_VM_PAGE_RELEASE = Constant('DBG_VM_PAGE_RELEASE',0x127)
|
||||
DBG_VM_COMPRESSOR_COMPACT_AND_SWAP = Constant('DBG_VM_COMPRESSOR_COMPACT_AND_SWAP',0x128)
|
||||
DBG_VM_COMPRESSOR_DELAYED_COMPACT = Constant('DBG_VM_COMPRESSOR_DELAYED_COMPACT',0x129)
|
||||
DBG_VM_OBJECT_SLEEP = Constant('DBG_VM_OBJECT_SLEEP',0x12a)
|
||||
DBG_VM_PAGE_WAKEUP = Constant('DBG_VM_PAGE_WAKEUP',0x12b)
|
||||
DBG_VM_PAGE_WAKEUP_DONE = Constant('DBG_VM_PAGE_WAKEUP_DONE',0x12c)
|
||||
DBG_VM_PRESSURE_EVENT = Constant('DBG_VM_PRESSURE_EVENT',0x130)
|
||||
DBG_VM_EXECVE = Constant('DBG_VM_EXECVE',0x131)
|
||||
DBG_VM_WAKEUP_COMPACTOR_SWAPPER = Constant('DBG_VM_WAKEUP_COMPACTOR_SWAPPER',0x132)
|
||||
DBG_VM_UPL_REQUEST = Constant('DBG_VM_UPL_REQUEST',0x133)
|
||||
DBG_VM_IOPL_REQUEST = Constant('DBG_VM_IOPL_REQUEST',0x134)
|
||||
DBG_VM_KERN_REQUEST = Constant('DBG_VM_KERN_REQUEST',0x135)
|
||||
DBG_VM_DATA_WRITE = Constant('DBG_VM_DATA_WRITE',0x140)
|
||||
DBG_VM_PRESSURE_LEVEL_CHANGE = Constant('DBG_VM_PRESSURE_LEVEL_CHANGE',0x141)
|
||||
DBG_VM_PHYS_WRITE_ACCT = Constant('DBG_VM_PHYS_WRITE_ACCT',0x142)
|
||||
DBG_VM_MAP_LOOKUP_ENTRY_FAILURE = Constant('DBG_VM_MAP_LOOKUP_ENTRY_FAILURE',0x143)
|
||||
VM_DISCONNECT_ALL_PAGE_MAPPINGS = Constant('VM_DISCONNECT_ALL_PAGE_MAPPINGS',0x00)
|
||||
VM_DISCONNECT_TASK_PAGE_MAPPINGS = Constant('VM_DISCONNECT_TASK_PAGE_MAPPINGS',0x01)
|
||||
VM_REAL_FAULT_ADDR_INTERNAL = Constant('VM_REAL_FAULT_ADDR_INTERNAL',0x02)
|
||||
VM_REAL_FAULT_ADDR_PURGABLE = Constant('VM_REAL_FAULT_ADDR_PURGABLE',0x03)
|
||||
VM_REAL_FAULT_ADDR_EXTERNAL = Constant('VM_REAL_FAULT_ADDR_EXTERNAL',0x04)
|
||||
VM_REAL_FAULT_ADDR_SHAREDCACHE = Constant('VM_REAL_FAULT_ADDR_SHAREDCACHE',0x05)
|
||||
VM_REAL_FAULT_FAST = Constant('VM_REAL_FAULT_FAST',0x06)
|
||||
VM_REAL_FAULT_SLOW = Constant('VM_REAL_FAULT_SLOW',0x07)
|
||||
VM_MAP_LOOKUP_OBJECT = Constant('VM_MAP_LOOKUP_OBJECT',0x08)
|
||||
DBG_ZERO_FILL_FAULT = Constant('DBG_ZERO_FILL_FAULT',0x01)
|
||||
DBG_PAGEIN_FAULT = Constant('DBG_PAGEIN_FAULT',0x02)
|
||||
DBG_COW_FAULT = Constant('DBG_COW_FAULT',0x03)
|
||||
DBG_CACHE_HIT_FAULT = Constant('DBG_CACHE_HIT_FAULT',0x04)
|
||||
DBG_NZF_PAGE_FAULT = Constant('DBG_NZF_PAGE_FAULT',0x05)
|
||||
DBG_GUARD_FAULT = Constant('DBG_GUARD_FAULT',0x06)
|
||||
DBG_PAGEINV_FAULT = Constant('DBG_PAGEINV_FAULT',0x07)
|
||||
DBG_PAGEIND_FAULT = Constant('DBG_PAGEIND_FAULT',0x08)
|
||||
DBG_COMPRESSOR_FAULT = Constant('DBG_COMPRESSOR_FAULT',0x09)
|
||||
DBG_COMPRESSOR_SWAPIN_FAULT = Constant('DBG_COMPRESSOR_SWAPIN_FAULT',0x0a)
|
||||
DBG_COR_FAULT = Constant('DBG_COR_FAULT',0x0b)
|
||||
MACH_TASK_SUSPEND = Constant('MACH_TASK_SUSPEND',0x0)
|
||||
MACH_TASK_RESUME = Constant('MACH_TASK_RESUME',0x1)
|
||||
MACH_THREAD_SET_VOUCHER = Constant('MACH_THREAD_SET_VOUCHER',0x2)
|
||||
@@ -1282,6 +1384,31 @@ MACH_IPC_KMSG_INFO = Constant('MACH_IPC_KMSG_INFO',0xa)
|
||||
MACH_IPC_KMSG_LINK = Constant('MACH_IPC_KMSG_LINK',0xb)
|
||||
MACH_IPC_PORT_ENTRY_MODIFY = Constant('MACH_IPC_PORT_ENTRY_MODIFY',0xc)
|
||||
MACH_IPC_DESTROY_GUARDED_DESC = Constant('MACH_IPC_DESTROY_GUARDED_DESC',0xd)
|
||||
MACH_THREAD_SUSPEND = Constant('MACH_THREAD_SUSPEND',0xe)
|
||||
MACH_THREAD_RESUME = Constant('MACH_THREAD_RESUME',0xf)
|
||||
MACH_EXCLAVES_SWITCH = Constant('MACH_EXCLAVES_SWITCH',0x0)
|
||||
MACH_EXCLAVES_XNUPROXY = Constant('MACH_EXCLAVES_XNUPROXY',0x1)
|
||||
MACH_EXCLAVES_RPC = Constant('MACH_EXCLAVES_RPC',0x2)
|
||||
MACH_EXCLAVES_UPCALL = Constant('MACH_EXCLAVES_UPCALL',0x3)
|
||||
MACH_EXCLAVES_BOOT_TASK = Constant('MACH_EXCLAVES_BOOT_TASK',0x4)
|
||||
MACH_EXCLAVES_SCHEDULER_YIELD = Constant('MACH_EXCLAVES_SCHEDULER_YIELD',0x0)
|
||||
MACH_EXCLAVES_SCHEDULER_SPAWNED = Constant('MACH_EXCLAVES_SCHEDULER_SPAWNED',0x1)
|
||||
MACH_EXCLAVES_SCHEDULER_TERMINATED = Constant('MACH_EXCLAVES_SCHEDULER_TERMINATED',0x2)
|
||||
MACH_EXCLAVES_SCHEDULER_WAIT = Constant('MACH_EXCLAVES_SCHEDULER_WAIT',0x3)
|
||||
MACH_EXCLAVES_SCHEDULER_WAKE = Constant('MACH_EXCLAVES_SCHEDULER_WAKE',0x4)
|
||||
MACH_EXCLAVES_SCHEDULER_SUSPENDED = Constant('MACH_EXCLAVES_SCHEDULER_SUSPENDED',0x5)
|
||||
MACH_EXCLAVES_SCHEDULER_RESUMED = Constant('MACH_EXCLAVES_SCHEDULER_RESUMED',0x6)
|
||||
MACH_EXCLAVES_SCHEDULER_INTERRUPTED = Constant('MACH_EXCLAVES_SCHEDULER_INTERRUPTED',0x7)
|
||||
MACH_EXCLAVES_SCHEDULER_NOTHING_SCHEDULED = Constant('MACH_EXCLAVES_SCHEDULER_NOTHING_SCHEDULED',0x8)
|
||||
MACH_EXCLAVES_SCHEDULER_ALL_EXCLAVES_BOOTED = Constant('MACH_EXCLAVES_SCHEDULER_ALL_EXCLAVES_BOOTED',0x9)
|
||||
MACH_EXCLAVES_SCHEDULER_EARLY_ALLOC = Constant('MACH_EXCLAVES_SCHEDULER_EARLY_ALLOC',0xa)
|
||||
MACH_EPOCH_SYNC_WAIT_STALE = Constant('MACH_EPOCH_SYNC_WAIT_STALE',0x0)
|
||||
MACH_EPOCH_SYNC_WAIT = Constant('MACH_EPOCH_SYNC_WAIT',0x1)
|
||||
MACH_EPOCH_SYNC_WAKE_NO_WAITERS = Constant('MACH_EPOCH_SYNC_WAKE_NO_WAITERS',0x2)
|
||||
MACH_EPOCH_SYNC_WAKE_ONE = Constant('MACH_EPOCH_SYNC_WAKE_ONE',0x3)
|
||||
MACH_EPOCH_SYNC_WAKE_ALL = Constant('MACH_EPOCH_SYNC_WAKE_ALL',0x4)
|
||||
MACH_EPOCH_SYNC_WAKE_ONE_WITH_OWNER = Constant('MACH_EPOCH_SYNC_WAKE_ONE_WITH_OWNER',0x5)
|
||||
MACH_EPOCH_SYNC_WAKE_THREAD = Constant('MACH_EPOCH_SYNC_WAKE_THREAD',0x6)
|
||||
MACH_THREAD_GROUP_NEW = Constant('MACH_THREAD_GROUP_NEW',0x0)
|
||||
MACH_THREAD_GROUP_FREE = Constant('MACH_THREAD_GROUP_FREE',0x1)
|
||||
MACH_THREAD_GROUP_SET = Constant('MACH_THREAD_GROUP_SET',0x2)
|
||||
@@ -1424,6 +1551,13 @@ HV_X86_VM_MAP_TRAP = Constant('HV_X86_VM_MAP_TRAP',0x2a)
|
||||
HV_X86_VM_PROTECT_TRAP = Constant('HV_X86_VM_PROTECT_TRAP',0x2b)
|
||||
HV_X86_VM_UNMAP_TRAP = Constant('HV_X86_VM_UNMAP_TRAP',0x2c)
|
||||
HV_X86_TSC_OFFSET_SET = Constant('HV_X86_TSC_OFFSET_SET',0x2d)
|
||||
VM_RECLAIM_UPDATE_ACCOUNTING = Constant('VM_RECLAIM_UPDATE_ACCOUNTING',0x01)
|
||||
VM_RECLAIM_ENTRIES = Constant('VM_RECLAIM_ENTRIES',0x02)
|
||||
VM_RECLAIM_CHUNK = Constant('VM_RECLAIM_CHUNK',0x03)
|
||||
VM_RECLAIM_ENTRY = Constant('VM_RECLAIM_ENTRY',0x04)
|
||||
VM_RECLAIM_ALL_MEMORY = Constant('VM_RECLAIM_ALL_MEMORY',0x05)
|
||||
VM_RECLAIM_ASYNC_MEMORY = Constant('VM_RECLAIM_ASYNC_MEMORY',0x06)
|
||||
VM_RECLAIM_INIT = Constant('VM_RECLAIM_INIT',0x07)
|
||||
DBG_NETIP = Constant('DBG_NETIP',1)
|
||||
DBG_NETARP = Constant('DBG_NETARP',2)
|
||||
DBG_NETUDP = Constant('DBG_NETUDP',3)
|
||||
@@ -2109,6 +2243,7 @@ XATTR_REPLACE = Constant('XATTR_REPLACE',0x0004)
|
||||
XATTR_NOSECURITY = Constant('XATTR_NOSECURITY',0x0008)
|
||||
XATTR_NODEFAULT = Constant('XATTR_NODEFAULT',0x0010)
|
||||
XATTR_SHOWCOMPRESSION = Constant('XATTR_SHOWCOMPRESSION',0x0020)
|
||||
XATTR_NOFOLLOW_ANY = Constant('XATTR_NOFOLLOW_ANY',0x0040)
|
||||
XATTR_MAXNAMELEN = Constant('XATTR_MAXNAMELEN',127)
|
||||
PR_SLOWHZ = Constant('PR_SLOWHZ',2)
|
||||
PRC_IFDOWN = Constant('PRC_IFDOWN',0)
|
||||
@@ -2142,6 +2277,7 @@ CTL_FLAG_REG_ID_UNIT = Constant('CTL_FLAG_REG_ID_UNIT',0x2)
|
||||
CTL_FLAG_REG_SOCK_STREAM = Constant('CTL_FLAG_REG_SOCK_STREAM',0x4)
|
||||
CTL_DATA_NOWAKEUP = Constant('CTL_DATA_NOWAKEUP',0x1)
|
||||
CTL_DATA_EOR = Constant('CTL_DATA_EOR',0x2)
|
||||
__has_safe_buffers = Constant('__has_safe_buffers',0)
|
||||
__DARWIN_ONLY_64_BIT_INO_T = Constant('__DARWIN_ONLY_64_BIT_INO_T',0)
|
||||
__DARWIN_ONLY_UNIX_CONFORMANCE = Constant('__DARWIN_ONLY_UNIX_CONFORMANCE',0)
|
||||
__DARWIN_ONLY_VERS_1050 = Constant('__DARWIN_ONLY_VERS_1050',0)
|
||||
@@ -2479,7 +2615,8 @@ VQ_QUOTA = Constant('VQ_QUOTA',0x1000)
|
||||
VQ_NEARLOWDISK = Constant('VQ_NEARLOWDISK',0x2000)
|
||||
VQ_DESIRED_DISK = Constant('VQ_DESIRED_DISK',0x4000)
|
||||
VQ_FREE_SPACE_CHANGE = Constant('VQ_FREE_SPACE_CHANGE',0x8000)
|
||||
VQ_FLAG10000 = Constant('VQ_FLAG10000',0x10000)
|
||||
VQ_PURGEABLE_SPACE_CHANGE = Constant('VQ_PURGEABLE_SPACE_CHANGE',0x10000)
|
||||
VQ_FLAG20000 = Constant('VQ_FLAG20000',0x20000)
|
||||
VFS_IOATTR_FLAGS_FUA = Constant('VFS_IOATTR_FLAGS_FUA',0x00000001)
|
||||
VFS_IOATTR_FLAGS_UNMAP = Constant('VFS_IOATTR_FLAGS_UNMAP',0x00000002)
|
||||
VFS_IOATTR_FLAGS_SWAPPIN_SUPPORTED = Constant('VFS_IOATTR_FLAGS_SWAPPIN_SUPPORTED',0x00000010)
|
||||
@@ -2510,7 +2647,7 @@ LK_NOWAIT = Constant('LK_NOWAIT',1)
|
||||
NFSV4_MAX_FH_SIZE = Constant('NFSV4_MAX_FH_SIZE',128)
|
||||
NFSV3_MAX_FH_SIZE = Constant('NFSV3_MAX_FH_SIZE',64)
|
||||
NFSV2_MAX_FH_SIZE = Constant('NFSV2_MAX_FH_SIZE',32)
|
||||
CRYPTEX_AUTH_STRUCT_VERSION = Constant('CRYPTEX_AUTH_STRUCT_VERSION',1)
|
||||
CRYPTEX_AUTH_STRUCT_VERSION = Constant('CRYPTEX_AUTH_STRUCT_VERSION',2)
|
||||
EV_FD = Constant('EV_FD',1)
|
||||
EV_RE = Constant('EV_RE',1)
|
||||
EV_WR = Constant('EV_WR',2)
|
||||
@@ -2534,6 +2671,10 @@ KDEBUG_LEVEL_STANDARD = Constant('KDEBUG_LEVEL_STANDARD',2)
|
||||
KDEBUG_LEVEL_FULL = Constant('KDEBUG_LEVEL_FULL',3)
|
||||
KDBG_FLAG_FILTERED = Constant('KDBG_FLAG_FILTERED',0x01)
|
||||
KDBG_FLAG_NOPROCFILT = Constant('KDBG_FLAG_NOPROCFILT',0x02)
|
||||
__DARWIN_LITTLE_ENDIAN = Constant('__DARWIN_LITTLE_ENDIAN',1234)
|
||||
__DARWIN_BIG_ENDIAN = Constant('__DARWIN_BIG_ENDIAN',4321)
|
||||
__DARWIN_PDP_ENDIAN = Constant('__DARWIN_PDP_ENDIAN',3412)
|
||||
USE_CLANG_TYPES = Constant('USE_CLANG_TYPES',0)
|
||||
__DARWIN_NULL = Constant('__DARWIN_NULL',0)
|
||||
UBC_PUSHDIRTY = Constant('UBC_PUSHDIRTY',0x01)
|
||||
UBC_PUSHALL = Constant('UBC_PUSHALL',0x02)
|
||||
@@ -3069,7 +3210,9 @@ SYS_record_system_event = Constant('SYS_record_system_event',552 + 0x2000000)
|
||||
SYS_mkfifoat = Constant('SYS_mkfifoat',553 + 0x2000000)
|
||||
SYS_mknodat = Constant('SYS_mknodat',554 + 0x2000000)
|
||||
SYS_ungraftdmg = Constant('SYS_ungraftdmg',555 + 0x2000000)
|
||||
SYS_MAXSYSCALL = Constant('SYS_MAXSYSCALL',556 + 0x2000000)
|
||||
SYS_coalition_policy_set = Constant('SYS_coalition_policy_set',556 + 0x2000000)
|
||||
SYS_coalition_policy_get = Constant('SYS_coalition_policy_get',557 + 0x2000000)
|
||||
SYS_MAXSYSCALL = Constant('SYS_MAXSYSCALL',558 + 0x2000000)
|
||||
SYS_invalid = Constant('SYS_invalid',63 + 0x2000000)
|
||||
SOCK_STREAM = Constant('SOCK_STREAM',1)
|
||||
SOCK_DGRAM = Constant('SOCK_DGRAM',2)
|
||||
@@ -3117,6 +3260,7 @@ SO_NUMRCVPKT = Constant('SO_NUMRCVPKT',0x1112)
|
||||
SO_NET_SERVICE_TYPE = Constant('SO_NET_SERVICE_TYPE',0x1116)
|
||||
SO_NETSVC_MARKING_LEVEL = Constant('SO_NETSVC_MARKING_LEVEL',0x1119)
|
||||
SO_RESOLVER_SIGNATURE = Constant('SO_RESOLVER_SIGNATURE',0x1131)
|
||||
SO_BINDTODEVICE = Constant('SO_BINDTODEVICE',0x1134)
|
||||
NET_SERVICE_TYPE_BE = Constant('NET_SERVICE_TYPE_BE',0)
|
||||
NET_SERVICE_TYPE_BK = Constant('NET_SERVICE_TYPE_BK',1)
|
||||
NET_SERVICE_TYPE_SIG = Constant('NET_SERVICE_TYPE_SIG',2)
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
+152
-18
@@ -302,7 +302,7 @@ class ContextType(object):
|
||||
>>> context.os == 'linux'
|
||||
True
|
||||
>>> context.arch = 'arm'
|
||||
>>> vars(context) == {'arch': 'arm', 'bits': 32, 'endian': 'little', 'os': 'linux'}
|
||||
>>> vars(context) == {'arch': 'arm', 'bits': 32, 'endian': 'little', 'os': 'linux', 'newline': b'\n'}
|
||||
True
|
||||
>>> context.endian
|
||||
'little'
|
||||
@@ -359,13 +359,16 @@ class ContextType(object):
|
||||
'encoding': 'auto',
|
||||
'endian': 'little',
|
||||
'gdbinit': "",
|
||||
'gdb_binary': "",
|
||||
'kernel': None,
|
||||
'local_libcdb': "/var/lib/libc-database",
|
||||
'log_level': logging.INFO,
|
||||
'log_file': _devnull(),
|
||||
'log_console': sys.stdout,
|
||||
'randomize': False,
|
||||
'rename_corefiles': True,
|
||||
'newline': b'\n',
|
||||
'throw_eof_on_incomplete_line': None,
|
||||
'noptrace': False,
|
||||
'os': 'linux',
|
||||
'proxy': None,
|
||||
@@ -375,8 +378,19 @@ class ContextType(object):
|
||||
'timeout': Timeout.maximum,
|
||||
}
|
||||
|
||||
#: Valid values for :meth:`pwnlib.context.ContextType.os`
|
||||
oses = sorted(('linux','freebsd','windows','cgc','android','baremetal','darwin'))
|
||||
unix_like = {'newline': b'\n'}
|
||||
windows_like = {'newline': b'\r\n'}
|
||||
|
||||
#: Keys are valid values for :meth:`pwnlib.context.ContextType.os`
|
||||
oses = _longest({
|
||||
'linux': unix_like,
|
||||
'freebsd': unix_like,
|
||||
'windows': windows_like,
|
||||
'cgc': unix_like,
|
||||
'android': unix_like,
|
||||
'baremetal': unix_like,
|
||||
'darwin': unix_like,
|
||||
})
|
||||
|
||||
big_32 = {'endian': 'big', 'bits': 32}
|
||||
big_64 = {'endian': 'big', 'bits': 64}
|
||||
@@ -445,14 +459,14 @@ class ContextType(object):
|
||||
|
||||
|
||||
def copy(self):
|
||||
"""copy() -> dict
|
||||
r"""copy() -> dict
|
||||
Returns a copy of the current context as a dictionary.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> context.clear()
|
||||
>>> context.os = 'linux'
|
||||
>>> vars(context) == {'os': 'linux'}
|
||||
>>> vars(context) == {'os': 'linux', 'newline': b'\n'}
|
||||
True
|
||||
"""
|
||||
return self._tls.copy()
|
||||
@@ -581,9 +595,9 @@ class ContextType(object):
|
||||
... log.debug("DEBUG")
|
||||
... log.info("INFO")
|
||||
... log.warn("WARN")
|
||||
[DEBUG] DEBUG
|
||||
[*] INFO
|
||||
[!] WARN
|
||||
[...] DEBUG
|
||||
[...] INFO
|
||||
[...] WARN
|
||||
"""
|
||||
level = 'error'
|
||||
if context.log_level <= logging.DEBUG:
|
||||
@@ -651,7 +665,7 @@ class ContextType(object):
|
||||
information is printed.
|
||||
|
||||
>>> with context.verbose: func()
|
||||
[DEBUG] Hello
|
||||
[...] Hello
|
||||
|
||||
"""
|
||||
return self.local(log_level='debug')
|
||||
@@ -1021,6 +1035,8 @@ class ContextType(object):
|
||||
"""
|
||||
if isinstance(value, (bytes, six.text_type)):
|
||||
# check if mode was specified as "[value],[mode]"
|
||||
from pwnlib.util.packing import _need_text
|
||||
value = _need_text(value)
|
||||
if ',' not in value:
|
||||
value += ',a'
|
||||
filename, mode = value.rsplit(',', 1)
|
||||
@@ -1071,31 +1087,105 @@ class ContextType(object):
|
||||
stream = open(stream, 'wt')
|
||||
return stream
|
||||
|
||||
@_validator
|
||||
def local_libcdb(self, path):
|
||||
"""
|
||||
Sets path to local libc-database, get more information for libc-database:
|
||||
https://github.com/niklasb/libc-database
|
||||
|
||||
Works in :attr:`pwnlib.libcdb` when searching by local database provider.
|
||||
|
||||
The default value is ``/var/lib/libc-database``.
|
||||
|
||||
Sets `context.local_libcdb` to empty string or `None` will turn off local libc-database integration.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> context.local_libcdb = pwnlib.data.elf.path
|
||||
>>> context.local_libcdb = 'foobar'
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: 'foobar' does not exist, please download libc-database first
|
||||
"""
|
||||
|
||||
if not os.path.isdir(path):
|
||||
raise AttributeError("'%s' does not exist, please download libc-database first" % path)
|
||||
|
||||
return path
|
||||
|
||||
@property
|
||||
def mask(self):
|
||||
return (1 << self.bits) - 1
|
||||
|
||||
@_validator
|
||||
def os(self, os):
|
||||
"""
|
||||
r"""
|
||||
Operating system of the target machine.
|
||||
|
||||
The default value is ``linux``.
|
||||
|
||||
Allowed values are listed in :attr:`pwnlib.context.ContextType.oses`.
|
||||
|
||||
Side Effects:
|
||||
|
||||
If an os is specified some attributes will be set on the context
|
||||
if a user has not already set a value.
|
||||
|
||||
The following property may be modified:
|
||||
|
||||
- :attr:`newline`
|
||||
|
||||
Raises:
|
||||
AttributeError: An invalid os was specified
|
||||
|
||||
Examples:
|
||||
|
||||
>>> context.os = 'linux'
|
||||
>>> context.clear()
|
||||
>>> context.os == 'linux' # Default os
|
||||
True
|
||||
|
||||
>>> context.os = 'freebsd'
|
||||
>>> context.os == 'freebsd'
|
||||
True
|
||||
|
||||
>>> context.os = 'foobar' #doctest: +ELLIPSIS
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: os must be one of ['android', 'baremetal', 'cgc', 'freebsd', 'linux', 'windows']
|
||||
|
||||
>>> context.clear()
|
||||
>>> context.newline == b'\n' # Default value
|
||||
True
|
||||
>>> context.os = 'windows'
|
||||
>>> context.newline == b'\r\n' # New value
|
||||
True
|
||||
|
||||
Note that expressly setting :attr:`newline` means that we use
|
||||
that value instead of the default
|
||||
|
||||
>>> context.clear()
|
||||
>>> context.newline = b'\n'
|
||||
>>> context.os = 'windows'
|
||||
>>> context.newline == b'\n'
|
||||
True
|
||||
|
||||
Setting the os can override the default for :attr:`newline`
|
||||
|
||||
>>> context.clear()
|
||||
>>> context.os = 'windows'
|
||||
>>> vars(context) == {'os': 'windows', 'newline': b'\r\n'}
|
||||
True
|
||||
"""
|
||||
os = os.lower()
|
||||
|
||||
if os not in self.oses:
|
||||
raise AttributeError("os must be one of %r" % self.oses)
|
||||
try:
|
||||
defaults = self.oses[os]
|
||||
except KeyError:
|
||||
raise AttributeError("os must be one of %r" % sorted(self.oses))
|
||||
|
||||
for k,v in defaults.items():
|
||||
if k not in self._tls:
|
||||
self._tls[k] = v
|
||||
|
||||
return os
|
||||
|
||||
@@ -1288,9 +1378,9 @@ class ContextType(object):
|
||||
def cache_dir_base(self, new_base):
|
||||
"""Base directory to use for caching content.
|
||||
|
||||
Changing this to a different value will clear the `cache_dir` path
|
||||
Changing this to a different value will clear the :attr:`cache_dir` path
|
||||
stored in TLS since a new path will need to be generated to respect the
|
||||
new `cache_dir_base` value.
|
||||
new :attr:`cache_dir_base` value.
|
||||
"""
|
||||
|
||||
if new_base != self.cache_dir_base:
|
||||
@@ -1305,6 +1395,9 @@ class ContextType(object):
|
||||
|
||||
Note:
|
||||
May be either a path string, or :const:`None`.
|
||||
Set to :const:`None` to disable caching.
|
||||
Set to :const:`True` to generate the default cache directory path
|
||||
based on :attr:`cache_dir_base` again.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -1312,12 +1405,18 @@ class ContextType(object):
|
||||
>>> cache_dir is not None
|
||||
True
|
||||
>>> os.chmod(cache_dir, 0o000)
|
||||
>>> del context._tls['cache_dir']
|
||||
>>> context.cache_dir = True
|
||||
>>> context.cache_dir is None
|
||||
True
|
||||
>>> os.chmod(cache_dir, 0o755)
|
||||
>>> cache_dir == context.cache_dir
|
||||
True
|
||||
>>> context.cache_dir = None
|
||||
>>> context.cache_dir is None
|
||||
True
|
||||
>>> context.cache_dir = True
|
||||
>>> context.cache_dir is not None
|
||||
True
|
||||
"""
|
||||
try:
|
||||
# If the TLS already has a cache directory path, we return it
|
||||
@@ -1362,7 +1461,9 @@ class ContextType(object):
|
||||
|
||||
@cache_dir.setter
|
||||
def cache_dir(self, v):
|
||||
if os.access(v, os.W_OK):
|
||||
if v is True:
|
||||
del self._tls["cache_dir"]
|
||||
elif v is None or os.access(v, os.W_OK):
|
||||
# Stash this in TLS for later reuse
|
||||
self._tls["cache_dir"] = v
|
||||
|
||||
@@ -1402,6 +1503,25 @@ class ContextType(object):
|
||||
# circular imports
|
||||
from pwnlib.util.packing import _need_bytes
|
||||
return _need_bytes(v)
|
||||
|
||||
@_validator
|
||||
def throw_eof_on_incomplete_line(self, v):
|
||||
"""Whether to raise an :class:`EOFError` if an EOF is received before a newline in ``tube.recvline``.
|
||||
|
||||
Controls if an :class:`EOFError` is treated as newline in ``tube.recvline`` and similar functions
|
||||
and whether a warning should be logged about it.
|
||||
|
||||
Possible values are:
|
||||
|
||||
- ``True``: Raise an :class:`EOFError` if an EOF is received before a newline.
|
||||
- ``False``: Return the data received so far if an EOF is received
|
||||
before a newline without logging a warning.
|
||||
- ``None``: Return the data received so far if an EOF is received
|
||||
before a newline and log a warning.
|
||||
|
||||
Default value is ``None``.
|
||||
"""
|
||||
return v if v is None else bool(v)
|
||||
|
||||
|
||||
@_validator
|
||||
@@ -1420,6 +1540,20 @@ class ContextType(object):
|
||||
"""
|
||||
return str(value)
|
||||
|
||||
@_validator
|
||||
def gdb_binary(self, value):
|
||||
"""Path to the binary that is used when running GDB locally.
|
||||
|
||||
This is useful when you have multiple versions of gdb installed or the gdb binary is
|
||||
called something different.
|
||||
|
||||
If set to an empty string, pwntools will try to search for a reasonable gdb binary from
|
||||
the path.
|
||||
|
||||
Default value is ``""``.
|
||||
"""
|
||||
return str(value)
|
||||
|
||||
@_validator
|
||||
def cyclic_alphabet(self, alphabet):
|
||||
"""Cyclic alphabet.
|
||||
@@ -1614,7 +1748,7 @@ def update_context_defaults(section):
|
||||
|
||||
default = ContextType.defaults[key]
|
||||
|
||||
if isinstance(default, six.string_types + six.integer_types + (tuple, list, dict)):
|
||||
if isinstance(default, six.string_types + six.integer_types + (float, tuple, list, dict)):
|
||||
value = safeeval.expr(value)
|
||||
else:
|
||||
log.warn("Unsupported configuration option %r in section %r" % (key, 'context'))
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
#define VOL_CAP_FMT_SHARED_SPACE 0x00800000
|
||||
#define VOL_CAP_FMT_VOL_GROUPS 0x01000000
|
||||
#define VOL_CAP_FMT_SEALED 0x02000000
|
||||
#define VOL_CAP_FMT_CLONE_MAPPING 0x04000000
|
||||
#define VOL_CAP_INT_SEARCHFS 0x00000001
|
||||
#define VOL_CAP_INT_ATTRLIST 0x00000002
|
||||
#define VOL_CAP_INT_NFSEXPORT 0x00000004
|
||||
@@ -108,6 +109,8 @@
|
||||
#define VOL_CAP_INT_RENAME_EXCL 0x00080000
|
||||
#define VOL_CAP_INT_RENAME_OPENFAIL 0x00100000
|
||||
#define VOL_CAP_INT_RENAME_SECLUDE 0x00200000
|
||||
#define VOL_CAP_INT_ATTRIBUTION_TAG 0x00400000
|
||||
#define VOL_CAP_INT_PUNCHHOLE 0x00800000
|
||||
#define ATTR_CMN_NAME 0x00000001
|
||||
#define ATTR_CMN_DEVID 0x00000002
|
||||
#define ATTR_CMN_FSID 0x00000004
|
||||
@@ -292,6 +295,8 @@
|
||||
#define IO_SWAP_DISPATCH 0x200000
|
||||
#define IO_SKIP_ENCRYPTION 0x400000
|
||||
#define IO_EVTONLY 0x800000
|
||||
#define IO_NOCACHE_SYSSPACE 0x1000000
|
||||
#define IO_NOCACHE_SWRITE 0x2000000
|
||||
#define LOOKUP 0
|
||||
#define CREATE 1
|
||||
#define DELETE 2
|
||||
@@ -346,6 +351,7 @@
|
||||
#define VNODE_LOOKUP_NOFOLLOW 0x01
|
||||
#define VNODE_LOOKUP_NOCROSSMOUNT 0x02
|
||||
#define VNODE_LOOKUP_CROSSMOUNTNOWAIT 0x04
|
||||
#define VNODE_LOOKUP_NOFOLLOW_ANY 0x08
|
||||
#define VNODE_RELOAD 0x01
|
||||
#define VNODE_WAIT 0x02
|
||||
#define VNODE_WRITEABLE 0x04
|
||||
@@ -424,7 +430,7 @@
|
||||
#define WANTPARENT 0x0010
|
||||
#define UIO_MAXIOV 1024
|
||||
#define UIO_SMALLIOV 8
|
||||
#define EVFILT_SYSCOUNT 17
|
||||
#define EVFILT_SYSCOUNT 18
|
||||
#define KEVENT_FLAG_NONE 0x000000
|
||||
#define KEVENT_FLAG_IMMEDIATE 0x000001
|
||||
#define KEVENT_FLAG_ERROR_EVENTS 0x000002
|
||||
@@ -502,6 +508,7 @@
|
||||
#define IMGPF_SPAWN 0x00000010
|
||||
#define IMGPF_DISABLE_ASLR 0x00000020
|
||||
#define IMGPF_ALLOW_DATA_EXEC 0x00000040
|
||||
#define IMGPF_3P_PLUGINS 0x00000080
|
||||
#define IMGPF_EXEC 0x00000100
|
||||
#define IMGPF_HIGH_BITS_ASLR 0x00000200
|
||||
#define IMGPF_IS_64BIT_DATA 0x00000400
|
||||
@@ -511,6 +518,7 @@
|
||||
#define IMGPF_HW_TPRO 0x00004000
|
||||
#define IMGPF_ROSETTA 0x10000000
|
||||
#define IMGPF_ALT_ROSETTA 0x20000000
|
||||
#define IMGPF_RESERVED_2 0x40000000
|
||||
#define IMGPF_NOJOP 0x80000000
|
||||
#define IMGPF_SB_DEFAULT 0
|
||||
#define IMGPF_SB_TRUE 1
|
||||
@@ -559,9 +567,34 @@
|
||||
#define WCONTINUED 0x00000010
|
||||
#define WNOWAIT 0x00000020
|
||||
#define WAIT_MYPGRP 0
|
||||
#define PRIO_DARWIN_GPU 5
|
||||
#define PRIO_DARWIN_GPU_ALLOW 0x1
|
||||
#define PRIO_DARWIN_GPU_DENY 0x2
|
||||
#define PRIO_DARWIN_ROLE 6
|
||||
#define PRIO_DARWIN_ROLE_DEFAULT 0x0
|
||||
#define PRIO_DARWIN_ROLE_UI_FOCAL 0x1
|
||||
#define PRIO_DARWIN_ROLE_UI 0x2
|
||||
#define PRIO_DARWIN_ROLE_NON_UI 0x3
|
||||
#define PRIO_DARWIN_ROLE_UI_NON_FOCAL 0x4
|
||||
#define PRIO_DARWIN_ROLE_TAL_LAUNCH 0x5
|
||||
#define PRIO_DARWIN_ROLE_DARWIN_BG 0x6
|
||||
#define PRIO_DARWIN_GAME_MODE 7
|
||||
#define PRIO_DARWIN_CARPLAY_MODE 8
|
||||
#define PRIO_DARWIN_GAME_MODE_OFF 0x0
|
||||
#define PRIO_DARWIN_GAME_MODE_ON 0x1
|
||||
#define PRIO_DARWIN_CARPLAY_MODE_OFF 0x0
|
||||
#define PRIO_DARWIN_CARPLAY_MODE_ON 0x1
|
||||
#define IOMON_ENABLE 0x01
|
||||
#define IOMON_DISABLE 0x02
|
||||
#define IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY 1
|
||||
#define IOPOL_TYPE_VFS_ALTLINK 11
|
||||
#define IOPOL_TYPE_VFS_NOCACHE_WRITE_FS_BLKSIZE 12
|
||||
#define IOPOL_VFS_HFS_CASE_SENSITIVITY_DEFAULT 0
|
||||
#define IOPOL_VFS_HFS_CASE_SENSITIVITY_FORCE_CASE_SENSITIVE 1
|
||||
#define IOPOL_VFS_ALTLINK_DISABLED 0
|
||||
#define IOPOL_VFS_ALTLINK_ENABLED 1
|
||||
#define IOPOL_CMD_GET 0x00000001
|
||||
#define IOPOL_CMD_SET 0x00000002
|
||||
#define IPC_CREAT 0001000
|
||||
#define IPC_EXCL 0002000
|
||||
#define IPC_NOWAIT 0004000
|
||||
@@ -676,6 +709,7 @@
|
||||
#define F_GETLEASE 107
|
||||
#define F_TRANSFEREXTENTS 110
|
||||
#define F_ATTRIBUTION_TAG 111
|
||||
#define F_ADDSIGS_MAIN_BINARY 113
|
||||
#define FCNTL_FS_SPECIFIC_BASE 0x00010000
|
||||
#define F_DUPFD_CLOEXEC 67
|
||||
#define FD_CLOEXEC 1
|
||||
@@ -903,6 +937,7 @@
|
||||
#define MADV_FREE_REUSE 8
|
||||
#define MADV_CAN_REUSE 9
|
||||
#define MADV_PAGEOUT 10
|
||||
#define MADV_ZERO 11
|
||||
#define MINCORE_INCORE 0x1
|
||||
#define MINCORE_REFERENCED 0x2
|
||||
#define MINCORE_MODIFIED 0x4
|
||||
@@ -1110,6 +1145,9 @@
|
||||
#define DBG_MACH_IHDLR 0x10
|
||||
#define DBG_MACH_IPC 0x20
|
||||
#define DBG_MACH_RESOURCE 0x25
|
||||
#define DBG_MACH_EXCLAVES 0x2A
|
||||
#define DBG_MACH_EXCLAVES_SCHEDULER 0x2B
|
||||
#define DBG_MACH_EPOCH_SYNC 0x2C
|
||||
#define DBG_MACH_VM 0x30
|
||||
#define DBG_MACH_LEAKS 0x31
|
||||
#define DBG_MACH_WORKINGSET 0x32
|
||||
@@ -1135,6 +1173,7 @@
|
||||
#define DBG_MACH_KCOV 0xAD
|
||||
#define DBG_MACH_MACHDEP_EXCP_SC_x86 0xAE
|
||||
#define DBG_MACH_MACHDEP_EXCP_SC_ARM 0xAF
|
||||
#define DBG_MACH_VM_RECLAIM 0xB0
|
||||
#define DBC_MACH_IO_MMIO_READ 0x1
|
||||
#define DBC_MACH_IO_MMIO_WRITE 0x2
|
||||
#define DBC_MACH_IO_PHYS_READ 0x3
|
||||
@@ -1176,7 +1215,6 @@
|
||||
#define MACH_SCHED_MAINTENANCE 0x1f
|
||||
#define MACH_DISPATCH 0x20
|
||||
#define MACH_QUANTUM_HANDOFF 0x21
|
||||
#define MACH_MULTIQ_DEQUEUE 0x22
|
||||
#define MACH_SCHED_THREAD_SWITCH 0x23
|
||||
#define MACH_SCHED_SMT_BALANCE 0x24
|
||||
#define MACH_REMOTE_DEFERRED_AST 0x25
|
||||
@@ -1228,6 +1266,7 @@
|
||||
#define MACH_SCHED_WI_EXTERNAL_WAKEUP 0x61
|
||||
#define MACH_SCHED_AST_CHECK 0x62
|
||||
#define MACH_SCHED_PREEMPT_TIMER_ACTIVE 0x63
|
||||
#define MACH_PROCESSOR_SHUTDOWN 0x64
|
||||
#define MACH_SCHED_CLUTCH_ROOT_BUCKET_STATE 0x0
|
||||
#define MACH_SCHED_CLUTCH_TG_BUCKET_STATE 0x1
|
||||
#define MACH_SCHED_CLUTCH_THREAD_SELECT 0x2
|
||||
@@ -1253,20 +1292,83 @@
|
||||
#define WORKGROUP_INTERVAL_SET_WORKLOAD_ID_NAME 0x7
|
||||
#define KCOV_STKSZ_THRESHOLD_ABOVE 0x0
|
||||
#define KCOV_STKSZ_THRESHOLD_BELOW 0x1
|
||||
#define MACH_MULTIQ_BOUND 1
|
||||
#define MACH_MULTIQ_GROUP 2
|
||||
#define MACH_MULTIQ_GLOBAL 3
|
||||
#define DBG_ZERO_FILL_FAULT 1
|
||||
#define DBG_PAGEIN_FAULT 2
|
||||
#define DBG_COW_FAULT 3
|
||||
#define DBG_CACHE_HIT_FAULT 4
|
||||
#define DBG_NZF_PAGE_FAULT 5
|
||||
#define DBG_GUARD_FAULT 6
|
||||
#define DBG_PAGEINV_FAULT 7
|
||||
#define DBG_PAGEIND_FAULT 8
|
||||
#define DBG_COMPRESSOR_FAULT 9
|
||||
#define DBG_COMPRESSOR_SWAPIN_FAULT 10
|
||||
#define DBG_COR_FAULT 11
|
||||
#define DBG_VM_VNODE_PAGEOUT 0x001
|
||||
#define DBG_VM_FAULT_INTERNAL 0x002
|
||||
#define DBG_VM_PURGEABLE_TOKEN_ADD 0x040
|
||||
#define DBG_VM_PURGEABLE_TOKEN_DELETE 0x041
|
||||
#define DBG_VM_PURGEABLE_TOKEN_RIPEN 0x042
|
||||
#define DBG_VM_PURGEABLE_OBJECT_ADD 0x048
|
||||
#define DBG_VM_PURGEABLE_OBJECT_REMOVE 0x049
|
||||
#define DBG_VM_PURGEABLE_OBJECT_PURGE 0x04a
|
||||
#define DBG_VM_PURGEABLE_OBJECT_PURGE_ALL 0x04b
|
||||
#define DBG_VM_PURGEABLE_OBJECT_PURGE_ONE 0x04c
|
||||
#define DBG_VM_PURGEABLE_OBJECT_PURGE_LOOP 0x04e
|
||||
#define DBG_VM_MAP_PARTIAL_REAP 0x054
|
||||
#define DBG_VM_MAP_WILLNEED 0x055
|
||||
#define DBG_VM_FAULT_CHECK_ZFDELAY 0x100
|
||||
#define DBG_VM_FAULT_COWDELAY 0x101
|
||||
#define DBG_VM_FAULT_ZFDELAY 0x102
|
||||
#define DBG_VM_FAULT_COMPRESSORDELAY 0x103
|
||||
#define DBG_VM_PAGEOUT_SCAN 0x104
|
||||
#define DBG_VM_PAGEOUT_BALANCE 0x105
|
||||
#define DBG_VM_PAGEOUT_FREELIST 0x106
|
||||
#define DBG_VM_PAGEOUT_PURGEONE 0x107
|
||||
#define DBG_VM_PAGEOUT_CACHE_EVICT 0x108
|
||||
#define DBG_VM_PAGEOUT_THREAD_BLOCK 0x109
|
||||
#define DBG_VM_PAGEOUT_JETSAM 0x10A
|
||||
#define DBG_VM_INFO1 0x10B
|
||||
#define DBG_VM_INFO2 0x10C
|
||||
#define DBG_VM_INFO3 0x10D
|
||||
#define DBG_VM_INFO4 0x10E
|
||||
#define DBG_VM_INFO5 0x10F
|
||||
#define DBG_VM_INFO6 0x110
|
||||
#define DBG_VM_INFO7 0x111
|
||||
#define DBG_VM_INFO8 0x112
|
||||
#define DBG_VM_INFO9 0x113
|
||||
#define DBG_VM_INFO10 0x114
|
||||
#define DBG_VM_UPL_PAGE_WAIT 0x120
|
||||
#define DBG_VM_IOPL_PAGE_WAIT 0x121
|
||||
#define DBG_VM_PAGE_WAIT_BLOCK 0x122
|
||||
#define DBG_VM_PAGE_SLEEP 0x123
|
||||
#define DBG_VM_PAGE_EXPEDITE 0x124
|
||||
#define DBG_VM_PAGE_EXPEDITE_NO_MEMORY 0x125
|
||||
#define DBG_VM_PAGE_GRAB 0x126
|
||||
#define DBG_VM_PAGE_RELEASE 0x127
|
||||
#define DBG_VM_COMPRESSOR_COMPACT_AND_SWAP 0x128
|
||||
#define DBG_VM_COMPRESSOR_DELAYED_COMPACT 0x129
|
||||
#define DBG_VM_OBJECT_SLEEP 0x12a
|
||||
#define DBG_VM_PAGE_WAKEUP 0x12b
|
||||
#define DBG_VM_PAGE_WAKEUP_DONE 0x12c
|
||||
#define DBG_VM_PRESSURE_EVENT 0x130
|
||||
#define DBG_VM_EXECVE 0x131
|
||||
#define DBG_VM_WAKEUP_COMPACTOR_SWAPPER 0x132
|
||||
#define DBG_VM_UPL_REQUEST 0x133
|
||||
#define DBG_VM_IOPL_REQUEST 0x134
|
||||
#define DBG_VM_KERN_REQUEST 0x135
|
||||
#define DBG_VM_DATA_WRITE 0x140
|
||||
#define DBG_VM_PRESSURE_LEVEL_CHANGE 0x141
|
||||
#define DBG_VM_PHYS_WRITE_ACCT 0x142
|
||||
#define DBG_VM_MAP_LOOKUP_ENTRY_FAILURE 0x143
|
||||
#define VM_DISCONNECT_ALL_PAGE_MAPPINGS 0x00
|
||||
#define VM_DISCONNECT_TASK_PAGE_MAPPINGS 0x01
|
||||
#define VM_REAL_FAULT_ADDR_INTERNAL 0x02
|
||||
#define VM_REAL_FAULT_ADDR_PURGABLE 0x03
|
||||
#define VM_REAL_FAULT_ADDR_EXTERNAL 0x04
|
||||
#define VM_REAL_FAULT_ADDR_SHAREDCACHE 0x05
|
||||
#define VM_REAL_FAULT_FAST 0x06
|
||||
#define VM_REAL_FAULT_SLOW 0x07
|
||||
#define VM_MAP_LOOKUP_OBJECT 0x08
|
||||
#define DBG_ZERO_FILL_FAULT 0x01
|
||||
#define DBG_PAGEIN_FAULT 0x02
|
||||
#define DBG_COW_FAULT 0x03
|
||||
#define DBG_CACHE_HIT_FAULT 0x04
|
||||
#define DBG_NZF_PAGE_FAULT 0x05
|
||||
#define DBG_GUARD_FAULT 0x06
|
||||
#define DBG_PAGEINV_FAULT 0x07
|
||||
#define DBG_PAGEIND_FAULT 0x08
|
||||
#define DBG_COMPRESSOR_FAULT 0x09
|
||||
#define DBG_COMPRESSOR_SWAPIN_FAULT 0x0a
|
||||
#define DBG_COR_FAULT 0x0b
|
||||
#define MACH_TASK_SUSPEND 0x0
|
||||
#define MACH_TASK_RESUME 0x1
|
||||
#define MACH_THREAD_SET_VOUCHER 0x2
|
||||
@@ -1281,6 +1383,31 @@
|
||||
#define MACH_IPC_KMSG_LINK 0xb
|
||||
#define MACH_IPC_PORT_ENTRY_MODIFY 0xc
|
||||
#define MACH_IPC_DESTROY_GUARDED_DESC 0xd
|
||||
#define MACH_THREAD_SUSPEND 0xe
|
||||
#define MACH_THREAD_RESUME 0xf
|
||||
#define MACH_EXCLAVES_SWITCH 0x0
|
||||
#define MACH_EXCLAVES_XNUPROXY 0x1
|
||||
#define MACH_EXCLAVES_RPC 0x2
|
||||
#define MACH_EXCLAVES_UPCALL 0x3
|
||||
#define MACH_EXCLAVES_BOOT_TASK 0x4
|
||||
#define MACH_EXCLAVES_SCHEDULER_YIELD 0x0
|
||||
#define MACH_EXCLAVES_SCHEDULER_SPAWNED 0x1
|
||||
#define MACH_EXCLAVES_SCHEDULER_TERMINATED 0x2
|
||||
#define MACH_EXCLAVES_SCHEDULER_WAIT 0x3
|
||||
#define MACH_EXCLAVES_SCHEDULER_WAKE 0x4
|
||||
#define MACH_EXCLAVES_SCHEDULER_SUSPENDED 0x5
|
||||
#define MACH_EXCLAVES_SCHEDULER_RESUMED 0x6
|
||||
#define MACH_EXCLAVES_SCHEDULER_INTERRUPTED 0x7
|
||||
#define MACH_EXCLAVES_SCHEDULER_NOTHING_SCHEDULED 0x8
|
||||
#define MACH_EXCLAVES_SCHEDULER_ALL_EXCLAVES_BOOTED 0x9
|
||||
#define MACH_EXCLAVES_SCHEDULER_EARLY_ALLOC 0xa
|
||||
#define MACH_EPOCH_SYNC_WAIT_STALE 0x0
|
||||
#define MACH_EPOCH_SYNC_WAIT 0x1
|
||||
#define MACH_EPOCH_SYNC_WAKE_NO_WAITERS 0x2
|
||||
#define MACH_EPOCH_SYNC_WAKE_ONE 0x3
|
||||
#define MACH_EPOCH_SYNC_WAKE_ALL 0x4
|
||||
#define MACH_EPOCH_SYNC_WAKE_ONE_WITH_OWNER 0x5
|
||||
#define MACH_EPOCH_SYNC_WAKE_THREAD 0x6
|
||||
#define MACH_THREAD_GROUP_NEW 0x0
|
||||
#define MACH_THREAD_GROUP_FREE 0x1
|
||||
#define MACH_THREAD_GROUP_SET 0x2
|
||||
@@ -1423,6 +1550,13 @@
|
||||
#define HV_X86_VM_PROTECT_TRAP 0x2b
|
||||
#define HV_X86_VM_UNMAP_TRAP 0x2c
|
||||
#define HV_X86_TSC_OFFSET_SET 0x2d
|
||||
#define VM_RECLAIM_UPDATE_ACCOUNTING 0x01
|
||||
#define VM_RECLAIM_ENTRIES 0x02
|
||||
#define VM_RECLAIM_CHUNK 0x03
|
||||
#define VM_RECLAIM_ENTRY 0x04
|
||||
#define VM_RECLAIM_ALL_MEMORY 0x05
|
||||
#define VM_RECLAIM_ASYNC_MEMORY 0x06
|
||||
#define VM_RECLAIM_INIT 0x07
|
||||
#define DBG_NETIP 1
|
||||
#define DBG_NETARP 2
|
||||
#define DBG_NETUDP 3
|
||||
@@ -2108,6 +2242,7 @@
|
||||
#define XATTR_NOSECURITY 0x0008
|
||||
#define XATTR_NODEFAULT 0x0010
|
||||
#define XATTR_SHOWCOMPRESSION 0x0020
|
||||
#define XATTR_NOFOLLOW_ANY 0x0040
|
||||
#define XATTR_MAXNAMELEN 127
|
||||
#define PR_SLOWHZ 2
|
||||
#define PRC_IFDOWN 0
|
||||
@@ -2141,6 +2276,7 @@
|
||||
#define CTL_FLAG_REG_SOCK_STREAM 0x4
|
||||
#define CTL_DATA_NOWAKEUP 0x1
|
||||
#define CTL_DATA_EOR 0x2
|
||||
#define __has_safe_buffers 0
|
||||
#define __DARWIN_ONLY_64_BIT_INO_T 0
|
||||
#define __DARWIN_ONLY_UNIX_CONFORMANCE 0
|
||||
#define __DARWIN_ONLY_VERS_1050 0
|
||||
@@ -2478,7 +2614,8 @@
|
||||
#define VQ_NEARLOWDISK 0x2000
|
||||
#define VQ_DESIRED_DISK 0x4000
|
||||
#define VQ_FREE_SPACE_CHANGE 0x8000
|
||||
#define VQ_FLAG10000 0x10000
|
||||
#define VQ_PURGEABLE_SPACE_CHANGE 0x10000
|
||||
#define VQ_FLAG20000 0x20000
|
||||
#define VFS_IOATTR_FLAGS_FUA 0x00000001
|
||||
#define VFS_IOATTR_FLAGS_UNMAP 0x00000002
|
||||
#define VFS_IOATTR_FLAGS_SWAPPIN_SUPPORTED 0x00000010
|
||||
@@ -2509,7 +2646,7 @@
|
||||
#define NFSV4_MAX_FH_SIZE 128
|
||||
#define NFSV3_MAX_FH_SIZE 64
|
||||
#define NFSV2_MAX_FH_SIZE 32
|
||||
#define CRYPTEX_AUTH_STRUCT_VERSION 1
|
||||
#define CRYPTEX_AUTH_STRUCT_VERSION 2
|
||||
#define EV_FD 1
|
||||
#define EV_RE 1
|
||||
#define EV_WR 2
|
||||
@@ -2533,6 +2670,10 @@
|
||||
#define KDEBUG_LEVEL_FULL 3
|
||||
#define KDBG_FLAG_FILTERED 0x01
|
||||
#define KDBG_FLAG_NOPROCFILT 0x02
|
||||
#define __DARWIN_LITTLE_ENDIAN 1234
|
||||
#define __DARWIN_BIG_ENDIAN 4321
|
||||
#define __DARWIN_PDP_ENDIAN 3412
|
||||
#define USE_CLANG_TYPES 0
|
||||
#define __DARWIN_NULL 0
|
||||
#define UBC_PUSHDIRTY 0x01
|
||||
#define UBC_PUSHALL 0x02
|
||||
@@ -3068,7 +3209,9 @@
|
||||
#define SYS_mkfifoat 553
|
||||
#define SYS_mknodat 554
|
||||
#define SYS_ungraftdmg 555
|
||||
#define SYS_MAXSYSCALL 556
|
||||
#define SYS_coalition_policy_set 556
|
||||
#define SYS_coalition_policy_get 557
|
||||
#define SYS_MAXSYSCALL 558
|
||||
#define SYS_invalid 63
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
@@ -3116,6 +3259,7 @@
|
||||
#define SO_NET_SERVICE_TYPE 0x1116
|
||||
#define SO_NETSVC_MARKING_LEVEL 0x1119
|
||||
#define SO_RESOLVER_SIGNATURE 0x1131
|
||||
#define SO_BINDTODEVICE 0x1134
|
||||
#define NET_SERVICE_TYPE_BE 0
|
||||
#define NET_SERVICE_TYPE_BK 1
|
||||
#define NET_SERVICE_TYPE_SIG 2
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
#define VOL_CAP_FMT_SHARED_SPACE 0x00800000
|
||||
#define VOL_CAP_FMT_VOL_GROUPS 0x01000000
|
||||
#define VOL_CAP_FMT_SEALED 0x02000000
|
||||
#define VOL_CAP_FMT_CLONE_MAPPING 0x04000000
|
||||
#define VOL_CAP_INT_SEARCHFS 0x00000001
|
||||
#define VOL_CAP_INT_ATTRLIST 0x00000002
|
||||
#define VOL_CAP_INT_NFSEXPORT 0x00000004
|
||||
@@ -108,6 +109,8 @@
|
||||
#define VOL_CAP_INT_RENAME_EXCL 0x00080000
|
||||
#define VOL_CAP_INT_RENAME_OPENFAIL 0x00100000
|
||||
#define VOL_CAP_INT_RENAME_SECLUDE 0x00200000
|
||||
#define VOL_CAP_INT_ATTRIBUTION_TAG 0x00400000
|
||||
#define VOL_CAP_INT_PUNCHHOLE 0x00800000
|
||||
#define ATTR_CMN_NAME 0x00000001
|
||||
#define ATTR_CMN_DEVID 0x00000002
|
||||
#define ATTR_CMN_FSID 0x00000004
|
||||
@@ -292,6 +295,8 @@
|
||||
#define IO_SWAP_DISPATCH 0x200000
|
||||
#define IO_SKIP_ENCRYPTION 0x400000
|
||||
#define IO_EVTONLY 0x800000
|
||||
#define IO_NOCACHE_SYSSPACE 0x1000000
|
||||
#define IO_NOCACHE_SWRITE 0x2000000
|
||||
#define LOOKUP 0
|
||||
#define CREATE 1
|
||||
#define DELETE 2
|
||||
@@ -346,6 +351,7 @@
|
||||
#define VNODE_LOOKUP_NOFOLLOW 0x01
|
||||
#define VNODE_LOOKUP_NOCROSSMOUNT 0x02
|
||||
#define VNODE_LOOKUP_CROSSMOUNTNOWAIT 0x04
|
||||
#define VNODE_LOOKUP_NOFOLLOW_ANY 0x08
|
||||
#define VNODE_RELOAD 0x01
|
||||
#define VNODE_WAIT 0x02
|
||||
#define VNODE_WRITEABLE 0x04
|
||||
@@ -424,7 +430,7 @@
|
||||
#define WANTPARENT 0x0010
|
||||
#define UIO_MAXIOV 1024
|
||||
#define UIO_SMALLIOV 8
|
||||
#define EVFILT_SYSCOUNT 17
|
||||
#define EVFILT_SYSCOUNT 18
|
||||
#define KEVENT_FLAG_NONE 0x000000
|
||||
#define KEVENT_FLAG_IMMEDIATE 0x000001
|
||||
#define KEVENT_FLAG_ERROR_EVENTS 0x000002
|
||||
@@ -502,6 +508,7 @@
|
||||
#define IMGPF_SPAWN 0x00000010
|
||||
#define IMGPF_DISABLE_ASLR 0x00000020
|
||||
#define IMGPF_ALLOW_DATA_EXEC 0x00000040
|
||||
#define IMGPF_3P_PLUGINS 0x00000080
|
||||
#define IMGPF_EXEC 0x00000100
|
||||
#define IMGPF_HIGH_BITS_ASLR 0x00000200
|
||||
#define IMGPF_IS_64BIT_DATA 0x00000400
|
||||
@@ -511,6 +518,7 @@
|
||||
#define IMGPF_HW_TPRO 0x00004000
|
||||
#define IMGPF_ROSETTA 0x10000000
|
||||
#define IMGPF_ALT_ROSETTA 0x20000000
|
||||
#define IMGPF_RESERVED_2 0x40000000
|
||||
#define IMGPF_NOJOP 0x80000000
|
||||
#define IMGPF_SB_DEFAULT 0
|
||||
#define IMGPF_SB_TRUE 1
|
||||
@@ -559,9 +567,34 @@
|
||||
#define WCONTINUED 0x00000010
|
||||
#define WNOWAIT 0x00000020
|
||||
#define WAIT_MYPGRP 0
|
||||
#define PRIO_DARWIN_GPU 5
|
||||
#define PRIO_DARWIN_GPU_ALLOW 0x1
|
||||
#define PRIO_DARWIN_GPU_DENY 0x2
|
||||
#define PRIO_DARWIN_ROLE 6
|
||||
#define PRIO_DARWIN_ROLE_DEFAULT 0x0
|
||||
#define PRIO_DARWIN_ROLE_UI_FOCAL 0x1
|
||||
#define PRIO_DARWIN_ROLE_UI 0x2
|
||||
#define PRIO_DARWIN_ROLE_NON_UI 0x3
|
||||
#define PRIO_DARWIN_ROLE_UI_NON_FOCAL 0x4
|
||||
#define PRIO_DARWIN_ROLE_TAL_LAUNCH 0x5
|
||||
#define PRIO_DARWIN_ROLE_DARWIN_BG 0x6
|
||||
#define PRIO_DARWIN_GAME_MODE 7
|
||||
#define PRIO_DARWIN_CARPLAY_MODE 8
|
||||
#define PRIO_DARWIN_GAME_MODE_OFF 0x0
|
||||
#define PRIO_DARWIN_GAME_MODE_ON 0x1
|
||||
#define PRIO_DARWIN_CARPLAY_MODE_OFF 0x0
|
||||
#define PRIO_DARWIN_CARPLAY_MODE_ON 0x1
|
||||
#define IOMON_ENABLE 0x01
|
||||
#define IOMON_DISABLE 0x02
|
||||
#define IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY 1
|
||||
#define IOPOL_TYPE_VFS_ALTLINK 11
|
||||
#define IOPOL_TYPE_VFS_NOCACHE_WRITE_FS_BLKSIZE 12
|
||||
#define IOPOL_VFS_HFS_CASE_SENSITIVITY_DEFAULT 0
|
||||
#define IOPOL_VFS_HFS_CASE_SENSITIVITY_FORCE_CASE_SENSITIVE 1
|
||||
#define IOPOL_VFS_ALTLINK_DISABLED 0
|
||||
#define IOPOL_VFS_ALTLINK_ENABLED 1
|
||||
#define IOPOL_CMD_GET 0x00000001
|
||||
#define IOPOL_CMD_SET 0x00000002
|
||||
#define IPC_CREAT 0001000
|
||||
#define IPC_EXCL 0002000
|
||||
#define IPC_NOWAIT 0004000
|
||||
@@ -676,6 +709,7 @@
|
||||
#define F_GETLEASE 107
|
||||
#define F_TRANSFEREXTENTS 110
|
||||
#define F_ATTRIBUTION_TAG 111
|
||||
#define F_ADDSIGS_MAIN_BINARY 113
|
||||
#define FCNTL_FS_SPECIFIC_BASE 0x00010000
|
||||
#define F_DUPFD_CLOEXEC 67
|
||||
#define FD_CLOEXEC 1
|
||||
@@ -903,6 +937,7 @@
|
||||
#define MADV_FREE_REUSE 8
|
||||
#define MADV_CAN_REUSE 9
|
||||
#define MADV_PAGEOUT 10
|
||||
#define MADV_ZERO 11
|
||||
#define MINCORE_INCORE 0x1
|
||||
#define MINCORE_REFERENCED 0x2
|
||||
#define MINCORE_MODIFIED 0x4
|
||||
@@ -1110,6 +1145,9 @@
|
||||
#define DBG_MACH_IHDLR 0x10
|
||||
#define DBG_MACH_IPC 0x20
|
||||
#define DBG_MACH_RESOURCE 0x25
|
||||
#define DBG_MACH_EXCLAVES 0x2A
|
||||
#define DBG_MACH_EXCLAVES_SCHEDULER 0x2B
|
||||
#define DBG_MACH_EPOCH_SYNC 0x2C
|
||||
#define DBG_MACH_VM 0x30
|
||||
#define DBG_MACH_LEAKS 0x31
|
||||
#define DBG_MACH_WORKINGSET 0x32
|
||||
@@ -1135,6 +1173,7 @@
|
||||
#define DBG_MACH_KCOV 0xAD
|
||||
#define DBG_MACH_MACHDEP_EXCP_SC_x86 0xAE
|
||||
#define DBG_MACH_MACHDEP_EXCP_SC_ARM 0xAF
|
||||
#define DBG_MACH_VM_RECLAIM 0xB0
|
||||
#define DBC_MACH_IO_MMIO_READ 0x1
|
||||
#define DBC_MACH_IO_MMIO_WRITE 0x2
|
||||
#define DBC_MACH_IO_PHYS_READ 0x3
|
||||
@@ -1176,7 +1215,6 @@
|
||||
#define MACH_SCHED_MAINTENANCE 0x1f
|
||||
#define MACH_DISPATCH 0x20
|
||||
#define MACH_QUANTUM_HANDOFF 0x21
|
||||
#define MACH_MULTIQ_DEQUEUE 0x22
|
||||
#define MACH_SCHED_THREAD_SWITCH 0x23
|
||||
#define MACH_SCHED_SMT_BALANCE 0x24
|
||||
#define MACH_REMOTE_DEFERRED_AST 0x25
|
||||
@@ -1228,6 +1266,7 @@
|
||||
#define MACH_SCHED_WI_EXTERNAL_WAKEUP 0x61
|
||||
#define MACH_SCHED_AST_CHECK 0x62
|
||||
#define MACH_SCHED_PREEMPT_TIMER_ACTIVE 0x63
|
||||
#define MACH_PROCESSOR_SHUTDOWN 0x64
|
||||
#define MACH_SCHED_CLUTCH_ROOT_BUCKET_STATE 0x0
|
||||
#define MACH_SCHED_CLUTCH_TG_BUCKET_STATE 0x1
|
||||
#define MACH_SCHED_CLUTCH_THREAD_SELECT 0x2
|
||||
@@ -1253,20 +1292,83 @@
|
||||
#define WORKGROUP_INTERVAL_SET_WORKLOAD_ID_NAME 0x7
|
||||
#define KCOV_STKSZ_THRESHOLD_ABOVE 0x0
|
||||
#define KCOV_STKSZ_THRESHOLD_BELOW 0x1
|
||||
#define MACH_MULTIQ_BOUND 1
|
||||
#define MACH_MULTIQ_GROUP 2
|
||||
#define MACH_MULTIQ_GLOBAL 3
|
||||
#define DBG_ZERO_FILL_FAULT 1
|
||||
#define DBG_PAGEIN_FAULT 2
|
||||
#define DBG_COW_FAULT 3
|
||||
#define DBG_CACHE_HIT_FAULT 4
|
||||
#define DBG_NZF_PAGE_FAULT 5
|
||||
#define DBG_GUARD_FAULT 6
|
||||
#define DBG_PAGEINV_FAULT 7
|
||||
#define DBG_PAGEIND_FAULT 8
|
||||
#define DBG_COMPRESSOR_FAULT 9
|
||||
#define DBG_COMPRESSOR_SWAPIN_FAULT 10
|
||||
#define DBG_COR_FAULT 11
|
||||
#define DBG_VM_VNODE_PAGEOUT 0x001
|
||||
#define DBG_VM_FAULT_INTERNAL 0x002
|
||||
#define DBG_VM_PURGEABLE_TOKEN_ADD 0x040
|
||||
#define DBG_VM_PURGEABLE_TOKEN_DELETE 0x041
|
||||
#define DBG_VM_PURGEABLE_TOKEN_RIPEN 0x042
|
||||
#define DBG_VM_PURGEABLE_OBJECT_ADD 0x048
|
||||
#define DBG_VM_PURGEABLE_OBJECT_REMOVE 0x049
|
||||
#define DBG_VM_PURGEABLE_OBJECT_PURGE 0x04a
|
||||
#define DBG_VM_PURGEABLE_OBJECT_PURGE_ALL 0x04b
|
||||
#define DBG_VM_PURGEABLE_OBJECT_PURGE_ONE 0x04c
|
||||
#define DBG_VM_PURGEABLE_OBJECT_PURGE_LOOP 0x04e
|
||||
#define DBG_VM_MAP_PARTIAL_REAP 0x054
|
||||
#define DBG_VM_MAP_WILLNEED 0x055
|
||||
#define DBG_VM_FAULT_CHECK_ZFDELAY 0x100
|
||||
#define DBG_VM_FAULT_COWDELAY 0x101
|
||||
#define DBG_VM_FAULT_ZFDELAY 0x102
|
||||
#define DBG_VM_FAULT_COMPRESSORDELAY 0x103
|
||||
#define DBG_VM_PAGEOUT_SCAN 0x104
|
||||
#define DBG_VM_PAGEOUT_BALANCE 0x105
|
||||
#define DBG_VM_PAGEOUT_FREELIST 0x106
|
||||
#define DBG_VM_PAGEOUT_PURGEONE 0x107
|
||||
#define DBG_VM_PAGEOUT_CACHE_EVICT 0x108
|
||||
#define DBG_VM_PAGEOUT_THREAD_BLOCK 0x109
|
||||
#define DBG_VM_PAGEOUT_JETSAM 0x10A
|
||||
#define DBG_VM_INFO1 0x10B
|
||||
#define DBG_VM_INFO2 0x10C
|
||||
#define DBG_VM_INFO3 0x10D
|
||||
#define DBG_VM_INFO4 0x10E
|
||||
#define DBG_VM_INFO5 0x10F
|
||||
#define DBG_VM_INFO6 0x110
|
||||
#define DBG_VM_INFO7 0x111
|
||||
#define DBG_VM_INFO8 0x112
|
||||
#define DBG_VM_INFO9 0x113
|
||||
#define DBG_VM_INFO10 0x114
|
||||
#define DBG_VM_UPL_PAGE_WAIT 0x120
|
||||
#define DBG_VM_IOPL_PAGE_WAIT 0x121
|
||||
#define DBG_VM_PAGE_WAIT_BLOCK 0x122
|
||||
#define DBG_VM_PAGE_SLEEP 0x123
|
||||
#define DBG_VM_PAGE_EXPEDITE 0x124
|
||||
#define DBG_VM_PAGE_EXPEDITE_NO_MEMORY 0x125
|
||||
#define DBG_VM_PAGE_GRAB 0x126
|
||||
#define DBG_VM_PAGE_RELEASE 0x127
|
||||
#define DBG_VM_COMPRESSOR_COMPACT_AND_SWAP 0x128
|
||||
#define DBG_VM_COMPRESSOR_DELAYED_COMPACT 0x129
|
||||
#define DBG_VM_OBJECT_SLEEP 0x12a
|
||||
#define DBG_VM_PAGE_WAKEUP 0x12b
|
||||
#define DBG_VM_PAGE_WAKEUP_DONE 0x12c
|
||||
#define DBG_VM_PRESSURE_EVENT 0x130
|
||||
#define DBG_VM_EXECVE 0x131
|
||||
#define DBG_VM_WAKEUP_COMPACTOR_SWAPPER 0x132
|
||||
#define DBG_VM_UPL_REQUEST 0x133
|
||||
#define DBG_VM_IOPL_REQUEST 0x134
|
||||
#define DBG_VM_KERN_REQUEST 0x135
|
||||
#define DBG_VM_DATA_WRITE 0x140
|
||||
#define DBG_VM_PRESSURE_LEVEL_CHANGE 0x141
|
||||
#define DBG_VM_PHYS_WRITE_ACCT 0x142
|
||||
#define DBG_VM_MAP_LOOKUP_ENTRY_FAILURE 0x143
|
||||
#define VM_DISCONNECT_ALL_PAGE_MAPPINGS 0x00
|
||||
#define VM_DISCONNECT_TASK_PAGE_MAPPINGS 0x01
|
||||
#define VM_REAL_FAULT_ADDR_INTERNAL 0x02
|
||||
#define VM_REAL_FAULT_ADDR_PURGABLE 0x03
|
||||
#define VM_REAL_FAULT_ADDR_EXTERNAL 0x04
|
||||
#define VM_REAL_FAULT_ADDR_SHAREDCACHE 0x05
|
||||
#define VM_REAL_FAULT_FAST 0x06
|
||||
#define VM_REAL_FAULT_SLOW 0x07
|
||||
#define VM_MAP_LOOKUP_OBJECT 0x08
|
||||
#define DBG_ZERO_FILL_FAULT 0x01
|
||||
#define DBG_PAGEIN_FAULT 0x02
|
||||
#define DBG_COW_FAULT 0x03
|
||||
#define DBG_CACHE_HIT_FAULT 0x04
|
||||
#define DBG_NZF_PAGE_FAULT 0x05
|
||||
#define DBG_GUARD_FAULT 0x06
|
||||
#define DBG_PAGEINV_FAULT 0x07
|
||||
#define DBG_PAGEIND_FAULT 0x08
|
||||
#define DBG_COMPRESSOR_FAULT 0x09
|
||||
#define DBG_COMPRESSOR_SWAPIN_FAULT 0x0a
|
||||
#define DBG_COR_FAULT 0x0b
|
||||
#define MACH_TASK_SUSPEND 0x0
|
||||
#define MACH_TASK_RESUME 0x1
|
||||
#define MACH_THREAD_SET_VOUCHER 0x2
|
||||
@@ -1281,6 +1383,31 @@
|
||||
#define MACH_IPC_KMSG_LINK 0xb
|
||||
#define MACH_IPC_PORT_ENTRY_MODIFY 0xc
|
||||
#define MACH_IPC_DESTROY_GUARDED_DESC 0xd
|
||||
#define MACH_THREAD_SUSPEND 0xe
|
||||
#define MACH_THREAD_RESUME 0xf
|
||||
#define MACH_EXCLAVES_SWITCH 0x0
|
||||
#define MACH_EXCLAVES_XNUPROXY 0x1
|
||||
#define MACH_EXCLAVES_RPC 0x2
|
||||
#define MACH_EXCLAVES_UPCALL 0x3
|
||||
#define MACH_EXCLAVES_BOOT_TASK 0x4
|
||||
#define MACH_EXCLAVES_SCHEDULER_YIELD 0x0
|
||||
#define MACH_EXCLAVES_SCHEDULER_SPAWNED 0x1
|
||||
#define MACH_EXCLAVES_SCHEDULER_TERMINATED 0x2
|
||||
#define MACH_EXCLAVES_SCHEDULER_WAIT 0x3
|
||||
#define MACH_EXCLAVES_SCHEDULER_WAKE 0x4
|
||||
#define MACH_EXCLAVES_SCHEDULER_SUSPENDED 0x5
|
||||
#define MACH_EXCLAVES_SCHEDULER_RESUMED 0x6
|
||||
#define MACH_EXCLAVES_SCHEDULER_INTERRUPTED 0x7
|
||||
#define MACH_EXCLAVES_SCHEDULER_NOTHING_SCHEDULED 0x8
|
||||
#define MACH_EXCLAVES_SCHEDULER_ALL_EXCLAVES_BOOTED 0x9
|
||||
#define MACH_EXCLAVES_SCHEDULER_EARLY_ALLOC 0xa
|
||||
#define MACH_EPOCH_SYNC_WAIT_STALE 0x0
|
||||
#define MACH_EPOCH_SYNC_WAIT 0x1
|
||||
#define MACH_EPOCH_SYNC_WAKE_NO_WAITERS 0x2
|
||||
#define MACH_EPOCH_SYNC_WAKE_ONE 0x3
|
||||
#define MACH_EPOCH_SYNC_WAKE_ALL 0x4
|
||||
#define MACH_EPOCH_SYNC_WAKE_ONE_WITH_OWNER 0x5
|
||||
#define MACH_EPOCH_SYNC_WAKE_THREAD 0x6
|
||||
#define MACH_THREAD_GROUP_NEW 0x0
|
||||
#define MACH_THREAD_GROUP_FREE 0x1
|
||||
#define MACH_THREAD_GROUP_SET 0x2
|
||||
@@ -1423,6 +1550,13 @@
|
||||
#define HV_X86_VM_PROTECT_TRAP 0x2b
|
||||
#define HV_X86_VM_UNMAP_TRAP 0x2c
|
||||
#define HV_X86_TSC_OFFSET_SET 0x2d
|
||||
#define VM_RECLAIM_UPDATE_ACCOUNTING 0x01
|
||||
#define VM_RECLAIM_ENTRIES 0x02
|
||||
#define VM_RECLAIM_CHUNK 0x03
|
||||
#define VM_RECLAIM_ENTRY 0x04
|
||||
#define VM_RECLAIM_ALL_MEMORY 0x05
|
||||
#define VM_RECLAIM_ASYNC_MEMORY 0x06
|
||||
#define VM_RECLAIM_INIT 0x07
|
||||
#define DBG_NETIP 1
|
||||
#define DBG_NETARP 2
|
||||
#define DBG_NETUDP 3
|
||||
@@ -2108,6 +2242,7 @@
|
||||
#define XATTR_NOSECURITY 0x0008
|
||||
#define XATTR_NODEFAULT 0x0010
|
||||
#define XATTR_SHOWCOMPRESSION 0x0020
|
||||
#define XATTR_NOFOLLOW_ANY 0x0040
|
||||
#define XATTR_MAXNAMELEN 127
|
||||
#define PR_SLOWHZ 2
|
||||
#define PRC_IFDOWN 0
|
||||
@@ -2141,6 +2276,7 @@
|
||||
#define CTL_FLAG_REG_SOCK_STREAM 0x4
|
||||
#define CTL_DATA_NOWAKEUP 0x1
|
||||
#define CTL_DATA_EOR 0x2
|
||||
#define __has_safe_buffers 0
|
||||
#define __DARWIN_ONLY_64_BIT_INO_T 0
|
||||
#define __DARWIN_ONLY_UNIX_CONFORMANCE 0
|
||||
#define __DARWIN_ONLY_VERS_1050 0
|
||||
@@ -2478,7 +2614,8 @@
|
||||
#define VQ_NEARLOWDISK 0x2000
|
||||
#define VQ_DESIRED_DISK 0x4000
|
||||
#define VQ_FREE_SPACE_CHANGE 0x8000
|
||||
#define VQ_FLAG10000 0x10000
|
||||
#define VQ_PURGEABLE_SPACE_CHANGE 0x10000
|
||||
#define VQ_FLAG20000 0x20000
|
||||
#define VFS_IOATTR_FLAGS_FUA 0x00000001
|
||||
#define VFS_IOATTR_FLAGS_UNMAP 0x00000002
|
||||
#define VFS_IOATTR_FLAGS_SWAPPIN_SUPPORTED 0x00000010
|
||||
@@ -2509,7 +2646,7 @@
|
||||
#define NFSV4_MAX_FH_SIZE 128
|
||||
#define NFSV3_MAX_FH_SIZE 64
|
||||
#define NFSV2_MAX_FH_SIZE 32
|
||||
#define CRYPTEX_AUTH_STRUCT_VERSION 1
|
||||
#define CRYPTEX_AUTH_STRUCT_VERSION 2
|
||||
#define EV_FD 1
|
||||
#define EV_RE 1
|
||||
#define EV_WR 2
|
||||
@@ -2533,6 +2670,10 @@
|
||||
#define KDEBUG_LEVEL_FULL 3
|
||||
#define KDBG_FLAG_FILTERED 0x01
|
||||
#define KDBG_FLAG_NOPROCFILT 0x02
|
||||
#define __DARWIN_LITTLE_ENDIAN 1234
|
||||
#define __DARWIN_BIG_ENDIAN 4321
|
||||
#define __DARWIN_PDP_ENDIAN 3412
|
||||
#define USE_CLANG_TYPES 0
|
||||
#define __DARWIN_NULL 0
|
||||
#define UBC_PUSHDIRTY 0x01
|
||||
#define UBC_PUSHALL 0x02
|
||||
@@ -3068,7 +3209,9 @@
|
||||
#define SYS_mkfifoat 553 + 0x2000000
|
||||
#define SYS_mknodat 554 + 0x2000000
|
||||
#define SYS_ungraftdmg 555 + 0x2000000
|
||||
#define SYS_MAXSYSCALL 556 + 0x2000000
|
||||
#define SYS_coalition_policy_set 556 + 0x2000000
|
||||
#define SYS_coalition_policy_get 557 + 0x2000000
|
||||
#define SYS_MAXSYSCALL 558 + 0x2000000
|
||||
#define SYS_invalid 63 + 0x2000000
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
@@ -3116,6 +3259,7 @@
|
||||
#define SO_NET_SERVICE_TYPE 0x1116
|
||||
#define SO_NETSVC_MARKING_LEVEL 0x1119
|
||||
#define SO_RESOLVER_SIGNATURE 0x1131
|
||||
#define SO_BINDTODEVICE 0x1134
|
||||
#define NET_SERVICE_TYPE_BE 0
|
||||
#define NET_SERVICE_TYPE_BK 1
|
||||
#define NET_SERVICE_TYPE_SIG 2
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
#define __NR_io_setup 0
|
||||
#define __NR_io_destroy 1
|
||||
#define __NR_io_submit 2
|
||||
#define __NR_io_cancel 3
|
||||
#define __NR_io_getevents 4
|
||||
#define __NR_setxattr 5
|
||||
#define __NR_lsetxattr 6
|
||||
#define __NR_fsetxattr 7
|
||||
#define __NR_getxattr 8
|
||||
#define __NR_lgetxattr 9
|
||||
#define __NR_fgetxattr 10
|
||||
#define __NR_listxattr 11
|
||||
#define __NR_llistxattr 12
|
||||
#define __NR_flistxattr 13
|
||||
#define __NR_removexattr 14
|
||||
#define __NR_lremovexattr 15
|
||||
#define __NR_fremovexattr 16
|
||||
#define __NR_getcwd 17
|
||||
#define __NR_lookup_dcookie 18
|
||||
#define __NR_eventfd2 19
|
||||
#define __NR_epoll_create1 20
|
||||
#define __NR_epoll_ctl 21
|
||||
#define __NR_epoll_pwait 22
|
||||
#define __NR_dup 23
|
||||
#define __NR_dup3 24
|
||||
#define __NR_fcntl 25
|
||||
#define __NR_inotify_init1 26
|
||||
#define __NR_inotify_add_watch 27
|
||||
#define __NR_inotify_rm_watch 28
|
||||
#define __NR_ioctl 29
|
||||
#define __NR_ioprio_set 30
|
||||
#define __NR_ioprio_get 31
|
||||
#define __NR_flock 32
|
||||
#define __NR_mknodat 33
|
||||
#define __NR_mkdirat 34
|
||||
#define __NR_unlinkat 35
|
||||
#define __NR_symlinkat 36
|
||||
#define __NR_linkat 37
|
||||
#define __NR_umount2 39
|
||||
#define __NR_mount 40
|
||||
#define __NR_pivot_root 41
|
||||
#define __NR_nfsservctl 42
|
||||
#define __NR_statfs 43
|
||||
#define __NR_fstatfs 44
|
||||
#define __NR_truncate 45
|
||||
#define __NR_ftruncate 46
|
||||
#define __NR_fallocate 47
|
||||
#define __NR_faccessat 48
|
||||
#define __NR_chdir 49
|
||||
#define __NR_fchdir 50
|
||||
#define __NR_chroot 51
|
||||
#define __NR_fchmod 52
|
||||
#define __NR_fchmodat 53
|
||||
#define __NR_fchownat 54
|
||||
#define __NR_fchown 55
|
||||
#define __NR_openat 56
|
||||
#define __NR_close 57
|
||||
#define __NR_vhangup 58
|
||||
#define __NR_pipe2 59
|
||||
#define __NR_quotactl 60
|
||||
#define __NR_getdents64 61
|
||||
#define __NR_lseek 62
|
||||
#define __NR_read 63
|
||||
#define __NR_write 64
|
||||
#define __NR_readv 65
|
||||
#define __NR_writev 66
|
||||
#define __NR_pread64 67
|
||||
#define __NR_pwrite64 68
|
||||
#define __NR_preadv 69
|
||||
#define __NR_pwritev 70
|
||||
#define __NR_sendfile 71
|
||||
#define __NR_pselect6 72
|
||||
#define __NR_ppoll 73
|
||||
#define __NR_signalfd4 74
|
||||
#define __NR_vmsplice 75
|
||||
#define __NR_splice 76
|
||||
#define __NR_tee 77
|
||||
#define __NR_readlinkat 78
|
||||
#define __NR_newfstatat 79
|
||||
#define __NR_fstat 80
|
||||
#define __NR_sync 81
|
||||
#define __NR_fsync 82
|
||||
#define __NR_fdatasync 83
|
||||
#define __NR_sync_file_range 84
|
||||
#define __NR_timerfd_create 85
|
||||
#define __NR_timerfd_settime 86
|
||||
#define __NR_timerfd_gettime 87
|
||||
#define __NR_utimensat 88
|
||||
#define __NR_acct 89
|
||||
#define __NR_capget 90
|
||||
#define __NR_capset 91
|
||||
#define __NR_personality 92
|
||||
#define __NR_exit 93
|
||||
#define __NR_exit_group 94
|
||||
#define __NR_waitid 95
|
||||
#define __NR_set_tid_address 96
|
||||
#define __NR_unshare 97
|
||||
#define __NR_futex 98
|
||||
#define __NR_set_robust_list 99
|
||||
#define __NR_get_robust_list 100
|
||||
#define __NR_nanosleep 101
|
||||
#define __NR_getitimer 102
|
||||
#define __NR_setitimer 103
|
||||
#define __NR_kexec_load 104
|
||||
#define __NR_init_module 105
|
||||
#define __NR_delete_module 106
|
||||
#define __NR_timer_create 107
|
||||
#define __NR_timer_gettime 108
|
||||
#define __NR_timer_getoverrun 109
|
||||
#define __NR_timer_settime 110
|
||||
#define __NR_timer_delete 111
|
||||
#define __NR_clock_settime 112
|
||||
#define __NR_clock_gettime 113
|
||||
#define __NR_clock_getres 114
|
||||
#define __NR_clock_nanosleep 115
|
||||
#define __NR_syslog 116
|
||||
#define __NR_ptrace 117
|
||||
#define __NR_sched_setparam 118
|
||||
#define __NR_sched_setscheduler 119
|
||||
#define __NR_sched_getscheduler 120
|
||||
#define __NR_sched_getparam 121
|
||||
#define __NR_sched_setaffinity 122
|
||||
#define __NR_sched_getaffinity 123
|
||||
#define __NR_sched_yield 124
|
||||
#define __NR_sched_get_priority_max 125
|
||||
#define __NR_sched_get_priority_min 126
|
||||
#define __NR_sched_rr_get_interval 127
|
||||
#define __NR_restart_syscall 128
|
||||
#define __NR_kill 129
|
||||
#define __NR_tkill 130
|
||||
#define __NR_tgkill 131
|
||||
#define __NR_sigaltstack 132
|
||||
#define __NR_rt_sigsuspend 133
|
||||
#define __NR_rt_sigaction 134
|
||||
#define __NR_rt_sigprocmask 135
|
||||
#define __NR_rt_sigpending 136
|
||||
#define __NR_rt_sigtimedwait 137
|
||||
#define __NR_rt_sigqueueinfo 138
|
||||
#define __NR_rt_sigreturn 139
|
||||
#define __NR_setpriority 140
|
||||
#define __NR_getpriority 141
|
||||
#define __NR_reboot 142
|
||||
#define __NR_setregid 143
|
||||
#define __NR_setgid 144
|
||||
#define __NR_setreuid 145
|
||||
#define __NR_setuid 146
|
||||
#define __NR_setresuid 147
|
||||
#define __NR_getresuid 148
|
||||
#define __NR_setresgid 149
|
||||
#define __NR_getresgid 150
|
||||
#define __NR_setfsuid 151
|
||||
#define __NR_setfsgid 152
|
||||
#define __NR_times 153
|
||||
#define __NR_setpgid 154
|
||||
#define __NR_getpgid 155
|
||||
#define __NR_getsid 156
|
||||
#define __NR_setsid 157
|
||||
#define __NR_getgroups 158
|
||||
#define __NR_setgroups 159
|
||||
#define __NR_uname 160
|
||||
#define __NR_sethostname 161
|
||||
#define __NR_setdomainname 162
|
||||
#define __NR_getrlimit 163
|
||||
#define __NR_setrlimit 164
|
||||
#define __NR_getrusage 165
|
||||
#define __NR_umask 166
|
||||
#define __NR_prctl 167
|
||||
#define __NR_getcpu 168
|
||||
#define __NR_gettimeofday 169
|
||||
#define __NR_settimeofday 170
|
||||
#define __NR_adjtimex 171
|
||||
#define __NR_getpid 172
|
||||
#define __NR_getppid 173
|
||||
#define __NR_getuid 174
|
||||
#define __NR_geteuid 175
|
||||
#define __NR_getgid 176
|
||||
#define __NR_getegid 177
|
||||
#define __NR_gettid 178
|
||||
#define __NR_sysinfo 179
|
||||
#define __NR_mq_open 180
|
||||
#define __NR_mq_unlink 181
|
||||
#define __NR_mq_timedsend 182
|
||||
#define __NR_mq_timedreceive 183
|
||||
#define __NR_mq_notify 184
|
||||
#define __NR_mq_getsetattr 185
|
||||
#define __NR_msgget 186
|
||||
#define __NR_msgctl 187
|
||||
#define __NR_msgrcv 188
|
||||
#define __NR_msgsnd 189
|
||||
#define __NR_semget 190
|
||||
#define __NR_semctl 191
|
||||
#define __NR_semtimedop 192
|
||||
#define __NR_semop 193
|
||||
#define __NR_shmget 194
|
||||
#define __NR_shmctl 195
|
||||
#define __NR_shmat 196
|
||||
#define __NR_shmdt 197
|
||||
#define __NR_socket 198
|
||||
#define __NR_socketpair 199
|
||||
#define __NR_bind 200
|
||||
#define __NR_listen 201
|
||||
#define __NR_accept 202
|
||||
#define __NR_connect 203
|
||||
#define __NR_getsockname 204
|
||||
#define __NR_getpeername 205
|
||||
#define __NR_sendto 206
|
||||
#define __NR_recvfrom 207
|
||||
#define __NR_setsockopt 208
|
||||
#define __NR_getsockopt 209
|
||||
#define __NR_shutdown 210
|
||||
#define __NR_sendmsg 211
|
||||
#define __NR_recvmsg 212
|
||||
#define __NR_readahead 213
|
||||
#define __NR_brk 214
|
||||
#define __NR_munmap 215
|
||||
#define __NR_mremap 216
|
||||
#define __NR_add_key 217
|
||||
#define __NR_request_key 218
|
||||
#define __NR_keyctl 219
|
||||
#define __NR_clone 220
|
||||
#define __NR_execve 221
|
||||
#define __NR_mmap 222
|
||||
#define __NR_fadvise64 223
|
||||
#define __NR_swapon 224
|
||||
#define __NR_swapoff 225
|
||||
#define __NR_mprotect 226
|
||||
#define __NR_msync 227
|
||||
#define __NR_mlock 228
|
||||
#define __NR_munlock 229
|
||||
#define __NR_mlockall 230
|
||||
#define __NR_munlockall 231
|
||||
#define __NR_mincore 232
|
||||
#define __NR_madvise 233
|
||||
#define __NR_remap_file_pages 234
|
||||
#define __NR_mbind 235
|
||||
#define __NR_get_mempolicy 236
|
||||
#define __NR_set_mempolicy 237
|
||||
#define __NR_migrate_pages 238
|
||||
#define __NR_move_pages 239
|
||||
#define __NR_rt_tgsigqueueinfo 240
|
||||
#define __NR_perf_event_open 241
|
||||
#define __NR_accept4 242
|
||||
#define __NR_recvmmsg 243
|
||||
#define __NR_arch_specific_syscall 244
|
||||
#define __NR_wait4 260
|
||||
#define __NR_prlimit64 261
|
||||
#define __NR_fanotify_init 262
|
||||
#define __NR_fanotify_mark 263
|
||||
#define __NR_name_to_handle_at 264
|
||||
#define __NR_open_by_handle_at 265
|
||||
#define __NR_clock_adjtime 266
|
||||
#define __NR_syncfs 267
|
||||
#define __NR_setns 268
|
||||
#define __NR_sendmmsg 269
|
||||
#define __NR_process_vm_readv 270
|
||||
#define __NR_process_vm_writev 271
|
||||
#define __NR_kcmp 272
|
||||
#define __NR_finit_module 273
|
||||
#define __NR_sched_setattr 274
|
||||
#define __NR_sched_getattr 275
|
||||
#define __NR_renameat2 276
|
||||
#define __NR_seccomp 277
|
||||
#define __NR_getrandom 278
|
||||
#define __NR_memfd_create 279
|
||||
#define __NR_bpf 280
|
||||
#define __NR_execveat 281
|
||||
#define __NR_userfaultfd 282
|
||||
#define __NR_membarrier 283
|
||||
#define __NR_mlock2 284
|
||||
#define __NR_copy_file_range 285
|
||||
#define __NR_preadv2 286
|
||||
#define __NR_pwritev2 287
|
||||
#define __NR_pkey_mprotect 288
|
||||
#define __NR_pkey_alloc 289
|
||||
#define __NR_pkey_free 290
|
||||
#define __NR_statx 291
|
||||
#define __NR_io_pgetevents 292
|
||||
#define __NR_rseq 293
|
||||
#define __NR_kexec_file_load 294
|
||||
#define __NR_pidfd_send_signal 424
|
||||
#define __NR_io_uring_setup 425
|
||||
#define __NR_io_uring_enter 426
|
||||
#define __NR_io_uring_register 427
|
||||
#define __NR_open_tree 428
|
||||
#define __NR_move_mount 429
|
||||
#define __NR_fsopen 430
|
||||
#define __NR_fsconfig 431
|
||||
#define __NR_fsmount 432
|
||||
#define __NR_fspick 433
|
||||
#define __NR_pidfd_open 434
|
||||
#define __NR_clone3 435
|
||||
#define __NR_close_range 436
|
||||
#define __NR_openat2 437
|
||||
#define __NR_pidfd_getfd 438
|
||||
#define __NR_faccessat2 439
|
||||
#define __NR_process_madvise 440
|
||||
#define __NR_epoll_pwait2 441
|
||||
#define __NR_mount_setattr 442
|
||||
#define __NR_landlock_create_ruleset 444
|
||||
#define __NR_landlock_add_rule 445
|
||||
#define __NR_landlock_restrict_self 446
|
||||
|
||||
#define __NR_sysriscv __NR_arch_specific_syscall
|
||||
#define __NR_riscv_flush_icache (__NR_sysriscv + 15)
|
||||
@@ -0,0 +1,4 @@
|
||||
// https://git.musl-libc.org/cgit/musl/plain/arch/riscv64/bits/syscall.h.in
|
||||
#define __riscv64__
|
||||
#include <riscv64/syscalls.h>
|
||||
#include <common.h>
|
||||
@@ -44,6 +44,7 @@
|
||||
#define SYS_clone2 __NR_clone2
|
||||
#define SYS_clone3 __NR_clone3
|
||||
#define SYS_close __NR_close
|
||||
#define SYS_close_range __NR_close_range
|
||||
#define SYS_connect __NR_connect
|
||||
#define SYS_copy_file_range __NR_copy_file_range
|
||||
#define SYS_creat __NR_creat
|
||||
@@ -58,6 +59,7 @@
|
||||
#define SYS_epoll_ctl __NR_epoll_ctl
|
||||
#define SYS_epoll_ctl_old __NR_epoll_ctl_old
|
||||
#define SYS_epoll_pwait __NR_epoll_pwait
|
||||
#define SYS_epoll_pwait2 __NR_epoll_pwait2
|
||||
#define SYS_epoll_wait __NR_epoll_wait
|
||||
#define SYS_epoll_wait_old __NR_epoll_wait_old
|
||||
#define SYS_eventfd __NR_eventfd
|
||||
@@ -69,6 +71,7 @@
|
||||
#define SYS_exit __NR_exit
|
||||
#define SYS_exit_group __NR_exit_group
|
||||
#define SYS_faccessat __NR_faccessat
|
||||
#define SYS_faccessat2 __NR_faccessat2
|
||||
#define SYS_fadvise64 __NR_fadvise64
|
||||
#define SYS_fadvise64_64 __NR_fadvise64_64
|
||||
#define SYS_fallocate __NR_fallocate
|
||||
@@ -191,6 +194,9 @@
|
||||
#define SYS_kexec_load __NR_kexec_load
|
||||
#define SYS_keyctl __NR_keyctl
|
||||
#define SYS_kill __NR_kill
|
||||
#define SYS_landlock_add_rule __NR_landlock_add_rule
|
||||
#define SYS_landlock_create_ruleset __NR_landlock_create_ruleset
|
||||
#define SYS_landlock_restrict_self __NR_landlock_restrict_self
|
||||
#define SYS_lchown __NR_lchown
|
||||
#define SYS_lchown32 __NR_lchown32
|
||||
#define SYS_lgetxattr __NR_lgetxattr
|
||||
@@ -228,6 +234,7 @@
|
||||
#define SYS_mmap2 __NR_mmap2
|
||||
#define SYS_modify_ldt __NR_modify_ldt
|
||||
#define SYS_mount __NR_mount
|
||||
#define SYS_mount_setattr __NR_mount_setattr
|
||||
#define SYS_move_mount __NR_move_mount
|
||||
#define SYS_move_pages __NR_move_pages
|
||||
#define SYS_mprotect __NR_mprotect
|
||||
@@ -402,6 +409,7 @@
|
||||
#define SYS_preadv __NR_preadv
|
||||
#define SYS_preadv2 __NR_preadv2
|
||||
#define SYS_prlimit64 __NR_prlimit64
|
||||
#define SYS_process_madvise __NR_process_madvise
|
||||
#define SYS_process_vm_readv __NR_process_vm_readv
|
||||
#define SYS_process_vm_writev __NR_process_vm_writev
|
||||
#define SYS_prof __NR_prof
|
||||
@@ -440,6 +448,7 @@
|
||||
#define SYS_reserved221 __NR_reserved221
|
||||
#define SYS_reserved82 __NR_reserved82
|
||||
#define SYS_restart_syscall __NR_restart_syscall
|
||||
#define SYS_riscv_flush_icache __NR_riscv_flush_icache
|
||||
#define SYS_rmdir __NR_rmdir
|
||||
#define SYS_rseq __NR_rseq
|
||||
#define SYS_rtas __NR_rtas
|
||||
@@ -572,6 +581,7 @@
|
||||
#define SYS_sys_kexec_load __NR_sys_kexec_load
|
||||
#define SYS_syslog __NR_syslog
|
||||
#define SYS_sysmips __NR_sysmips
|
||||
#define SYS_sysriscv __NR_sysriscv
|
||||
#define SYS_sys_setaltroot __NR_sys_setaltroot
|
||||
#define SYS_tee __NR_tee
|
||||
#define SYS_tgkill __NR_tgkill
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -8,6 +8,6 @@ functions.py:
|
||||
wget https://raw.githubusercontent.com/zachriggle/functions/master/functions.py
|
||||
|
||||
generate_darwin:
|
||||
python generate_darwin.py "$(ROOT)"
|
||||
python3 generate_darwin.py "$(ROOT)"
|
||||
|
||||
.phony: all
|
||||
@@ -1,16 +1,16 @@
|
||||
|
||||
# ./pwnlib/data/includes/darwin/aarch64.h
|
||||
# ./pwnlib/constants/darwin/aarch64.py
|
||||
|
||||
# https://github.com/nullgemm/instant_macos_sdk (old sdk here, please use real macos device)
|
||||
# https://github.com/joseluisq/macosx-sdks (old sdk here, please use real macos device)
|
||||
# /Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/sys/
|
||||
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
|
||||
# In the future, you should change the version of `MacOSX14.sdk`
|
||||
sdk_path = Path('/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/sys/')
|
||||
# In the future, you should change the version of `MacOSX15.sdk`
|
||||
sdk_path = Path('/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/sys/')
|
||||
if not sdk_path.exists():
|
||||
print('missing MacOSX sdk')
|
||||
exit(1)
|
||||
|
||||
+1
-1
@@ -652,7 +652,7 @@ class DynELF(object):
|
||||
break
|
||||
|
||||
if name:
|
||||
self.status('Skipping %s' % name)
|
||||
self.status('Skipping %r' % name)
|
||||
|
||||
cur = leak.field(cur, LinkMap.l_next)
|
||||
else:
|
||||
|
||||
+25
-5
@@ -238,8 +238,8 @@ class Corefile(ELF):
|
||||
Registers can be accessed directly, e.g. via ``core_obj.eax`` and enumerated
|
||||
via :data:`Corefile.registers`.
|
||||
|
||||
Memory can be accessed directly via :meth:`.read` or :meth:`.write`, and also
|
||||
via :meth:`.pack` or :meth:`.unpack` or even :meth:`.string`.
|
||||
Memory can be accessed directly via :meth:`pwnlib.elf.elf.ELF.read` or :meth:`pwnlib.elf.elf.ELF.write`, and also
|
||||
via :meth:`pwnlib.elf.elf.ELF.pack` or :meth:`pwnlib.elf.elf.ELF.unpack` or even :meth:`.string`.
|
||||
|
||||
Arguments:
|
||||
core: Path to the core file. Alternately, may be a :class:`.process` instance,
|
||||
@@ -376,8 +376,8 @@ class Corefile(ELF):
|
||||
>>> core.exe.data[0:4]
|
||||
b'\x7fELF'
|
||||
|
||||
It also supports all of the features of :class:`ELF`, so you can :meth:`.read`
|
||||
or :meth:`.write` or even the helpers like :meth:`.pack` or :meth:`.unpack`.
|
||||
It also supports all of the features of :class:`ELF`, so you can :meth:`pwnlib.elf.elf.ELF.read`
|
||||
or :meth:`pwnlib.elf.elf.ELF.write` or even the helpers like :meth:`pwnlib.elf.elf.ELF.pack` or :meth:`pwnlib.elf.elf.ELF.unpack`.
|
||||
|
||||
Don't forget to call :meth:`.ELF.save` to save the changes to disk.
|
||||
|
||||
@@ -555,6 +555,9 @@ class Corefile(ELF):
|
||||
# Pointer to the entry point
|
||||
self.at_entry = 0
|
||||
|
||||
# Pointer to the vdso
|
||||
self.at_sysinfo_ehdr = None
|
||||
|
||||
try:
|
||||
super(Corefile, self).__init__(*a, **kw)
|
||||
except IOError:
|
||||
@@ -611,6 +614,8 @@ class Corefile(ELF):
|
||||
|
||||
if not self.stack and self.mappings:
|
||||
self.stack = self.mappings[-1].stop
|
||||
if self.mappings[-1].start == 0xffffffffff600000 and len(self.mappings) > 1:
|
||||
self.stack = self.mappings[-2].stop
|
||||
|
||||
if self.stack and self.mappings:
|
||||
for mapping in self.mappings:
|
||||
@@ -1329,6 +1334,10 @@ class CorefileFinder(object):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Convert bytes-like object to string
|
||||
if isinstance(data, bytes):
|
||||
data = data.decode('utf-8')
|
||||
|
||||
return data
|
||||
|
||||
def systemd_coredump_corefile(self):
|
||||
@@ -1506,7 +1515,18 @@ class CorefileFinder(object):
|
||||
# should be unique enough that we can just glob.
|
||||
|
||||
boot_id = read('/proc/sys/kernel/random/boot_id').strip().decode()
|
||||
path = self.exe.replace('/', '_')
|
||||
|
||||
# Use the absolute path of the executable
|
||||
# Apport uses the executable's path to determine the core dump filename
|
||||
#
|
||||
# Reference source:
|
||||
# https://github.com/canonical/apport/blob/4bbb179b8f92989bf7c1ee3692074f35d70ef3e8/data/apport#L110
|
||||
# https://github.com/canonical/apport/blob/4bbb179b8f92989bf7c1ee3692074f35d70ef3e8/apport/fileutils.py#L599
|
||||
#
|
||||
# Apport calls `get_core_path` with `options.executable_path`, which corresponds to
|
||||
# the executable's pathname, as specified by the `%E` placeholder
|
||||
# in the core pattern (see `man core` and `apport --help`).
|
||||
path = os.path.abspath(self.exe).replace('/', '_').replace('.', '_')
|
||||
|
||||
# Format the name
|
||||
corefile_name = 'core.{path}.{uid}.{boot_id}.{pid}.*'.format(
|
||||
|
||||
+135
-86
@@ -52,6 +52,7 @@ from collections import namedtuple, defaultdict
|
||||
from elftools.elf.constants import P_FLAGS
|
||||
from elftools.elf.constants import SHN_INDICES
|
||||
from elftools.elf.descriptions import describe_e_type
|
||||
from elftools.elf.dynamic import DynamicSection
|
||||
from elftools.elf.elffile import ELFFile
|
||||
from elftools.elf.enums import ENUM_GNU_PROPERTY_X86_FEATURE_1_FLAGS
|
||||
from elftools.elf.gnuversions import GNUVerDefSection
|
||||
@@ -358,12 +359,21 @@ class ELF(ELFFile):
|
||||
self._populate_functions()
|
||||
self._populate_kernel_version()
|
||||
|
||||
self._print_checksec = checksec
|
||||
if checksec:
|
||||
self._describe()
|
||||
|
||||
self._libs = None
|
||||
self._maps = None
|
||||
|
||||
def close(self):
|
||||
"""close() -> None
|
||||
|
||||
Close the ELF file and release all resources associated with it.
|
||||
"""
|
||||
super(ELF, self).close()
|
||||
self.file.close()
|
||||
|
||||
@staticmethod
|
||||
@LocalContext
|
||||
def from_assembly(assembly, *a, **kw):
|
||||
@@ -705,29 +715,57 @@ class ELF(ELFFile):
|
||||
|
||||
@property
|
||||
def libs(self):
|
||||
"""Dictionary of {path: address} for every library loaded for this ELF."""
|
||||
"""Dictionary of ``{path: address}`` for every library loaded for this ELF.
|
||||
|
||||
.. warning::
|
||||
|
||||
Getting this attribute actually runs the executable.
|
||||
Make sure that you trust the binary you are exploiting.
|
||||
If it adds itself as ``DT_NEEDED``, has overlapping segments,
|
||||
ambiguous headers, or employs text relocations, it can run arbitrary
|
||||
code even though you are just inspecting it.
|
||||
Running is the only reliable way to ensure all the libraries are
|
||||
loaded from the correct paths, because some of them may change
|
||||
loading logic.
|
||||
|
||||
Exploitability first noticed at CWTE CTF 2025.
|
||||
"""
|
||||
if self._libs is None:
|
||||
self._populate_libraries()
|
||||
return self._libs
|
||||
|
||||
@property
|
||||
def maps(self):
|
||||
"""Dictionary of {name: address} for every mapping in this ELF's address space."""
|
||||
"""Dictionary of ``{name: address}`` for every mapping in this ELF's address space.
|
||||
|
||||
.. warning::
|
||||
|
||||
Getting this attribute actually runs the executable.
|
||||
Make sure that you trust the binary you are exploiting
|
||||
(see :attr:`.ELF.libs`).
|
||||
"""
|
||||
if self._maps is None:
|
||||
self._populate_libraries()
|
||||
return self._maps
|
||||
|
||||
@property
|
||||
def libc(self):
|
||||
""":class:`.ELF`: If this :class:`.ELF` imports any libraries which contain ``'libc[.-]``,
|
||||
""":class:`.ELF`: If this :class:`.ELF` imports any libraries which contain ``/libc[.-]``,
|
||||
and we can determine the appropriate path to it on the local
|
||||
system, returns a new :class:`.ELF` object pertaining to that library.
|
||||
Prints the `checksec` output of the library if it was printed for the original ELF too.
|
||||
|
||||
If not found, the value will be :const:`None`.
|
||||
|
||||
.. warning::
|
||||
|
||||
Getting this attribute actually runs the executable.
|
||||
Make sure that you trust the binary you are exploiting
|
||||
(see :attr:`.ELF.libs`).
|
||||
"""
|
||||
for lib in self.libs:
|
||||
if '/libc.' in lib or '/libc-' in lib:
|
||||
return ELF(lib)
|
||||
if ('/libc.' in lib or '/libc-' in lib) and lib != self.path:
|
||||
return ELF(lib, self._print_checksec)
|
||||
|
||||
def _populate_libraries(self):
|
||||
"""
|
||||
@@ -841,6 +879,13 @@ class ELF(ELFFile):
|
||||
log.warn_once("Injected /proc/self/maps code did not execute correctly")
|
||||
return {}
|
||||
|
||||
# Sometimes the original binary already fail to run, for example, in case glibc mismatches.
|
||||
try:
|
||||
int(data.split('-', 1)[0], 16)
|
||||
except ValueError:
|
||||
log.warn_once("Cannot execute `%s` to get /proc/self/maps", self.path)
|
||||
return {}
|
||||
|
||||
# Swap in the original ELF name
|
||||
data = data.replace(path, self.path)
|
||||
|
||||
@@ -908,10 +953,9 @@ class ELF(ELFFile):
|
||||
continue
|
||||
|
||||
for symbol in _iter_symbols(section):
|
||||
value = symbol.entry.st_value
|
||||
if not value:
|
||||
if not symbol.name or symbol.entry.st_shndx == 'SHN_UNDEF':
|
||||
continue
|
||||
self.symbols[symbol.name] = value
|
||||
self.symbols[symbol.name] = symbol.entry.st_value
|
||||
|
||||
def _populate_synthetic_symbols(self):
|
||||
"""Adds symbols from the GOT and PLT to the symbols dictionary.
|
||||
@@ -1597,7 +1641,7 @@ class ELF(ELFFile):
|
||||
dt = None
|
||||
dynamic = self.get_section_by_name('.dynamic')
|
||||
|
||||
if not dynamic:
|
||||
if not dynamic or not isinstance(dynamic, DynamicSection):
|
||||
return None
|
||||
|
||||
try:
|
||||
@@ -1780,131 +1824,136 @@ class ELF(ELFFile):
|
||||
\\* Hardware limitations are ignored.
|
||||
|
||||
If ``READ_IMPLIES_EXEC`` is set, then `all readable pages are executable`__.
|
||||
.. __: https://github.com/torvalds/linux/blob/v6.3/fs/binfmt_elf.c#L1008-L1009
|
||||
.. code-block:: c
|
||||
|
||||
if (elf_read_implies_exec(loc->elf_ex, executable_stack))
|
||||
current->personality |= READ_IMPLIES_EXEC;
|
||||
.. __: https://github.com/torvalds/linux/blob/v6.3/fs/binfmt_elf.c#L1008-L1009
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (elf_read_implies_exec(loc->elf_ex, executable_stack))
|
||||
current->personality |= READ_IMPLIES_EXEC;
|
||||
|
||||
.. [#x86_5.7]
|
||||
`source <https://github.com/torvalds/linux/blob/v5.7/arch/x86/include/asm/elf.h#L285-L286>`__
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
#define elf_read_implies_exec(ex, executable_stack) \\
|
||||
(executable_stack != EXSTACK_DISABLE_X)
|
||||
#define elf_read_implies_exec(ex, executable_stack) \\
|
||||
(executable_stack != EXSTACK_DISABLE_X)
|
||||
|
||||
.. [#x86_5.8]
|
||||
`source <https://github.com/torvalds/linux/blob/v5.8/arch/x86/include/asm/elf.h#L305-L306>`__
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
#define elf_read_implies_exec(ex, executable_stack) \\
|
||||
(mmap_is_ia32() && executable_stack == EXSTACK_DEFAULT)
|
||||
#define elf_read_implies_exec(ex, executable_stack) \\
|
||||
(mmap_is_ia32() && executable_stack == EXSTACK_DEFAULT)
|
||||
|
||||
`mmap_is_ia32()`__:
|
||||
.. __: https://github.com/torvalds/linux/blob/v5.8/arch/x86/include/asm/elf.h#L318-L321
|
||||
.. code-block:: c
|
||||
`mmap_is_ia32()`__:
|
||||
|
||||
/*
|
||||
* True on X86_32 or when emulating IA32 on X86_64
|
||||
*/
|
||||
static inline int mmap_is_ia32(void)
|
||||
.. __: https://github.com/torvalds/linux/blob/v5.8/arch/x86/include/asm/elf.h#L318-L321
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*
|
||||
* True on X86_32 or when emulating IA32 on X86_64
|
||||
*/
|
||||
static inline int mmap_is_ia32(void)
|
||||
|
||||
.. [#arm_5.7]
|
||||
`source <https://github.com/torvalds/linux/blob/v5.7/arch/arm/kernel/elf.c#L85-L92>`__
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
int arm_elf_read_implies_exec(int executable_stack)
|
||||
{
|
||||
if (executable_stack != EXSTACK_DISABLE_X)
|
||||
return 1;
|
||||
if (cpu_architecture() < CPU_ARCH_ARMv6)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
int arm_elf_read_implies_exec(int executable_stack)
|
||||
{
|
||||
if (executable_stack != EXSTACK_DISABLE_X)
|
||||
return 1;
|
||||
if (cpu_architecture() < CPU_ARCH_ARMv6)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. [#arm_5.8]
|
||||
`source <https://github.com/torvalds/linux/blob/v5.8/arch/arm/kernel/elf.c#L104-L111>`__
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
int arm_elf_read_implies_exec(int executable_stack)
|
||||
{
|
||||
if (executable_stack == EXSTACK_DEFAULT)
|
||||
return 1;
|
||||
if (cpu_architecture() < CPU_ARCH_ARMv6)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
int arm_elf_read_implies_exec(int executable_stack)
|
||||
{
|
||||
if (executable_stack == EXSTACK_DEFAULT)
|
||||
return 1;
|
||||
if (cpu_architecture() < CPU_ARCH_ARMv6)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. [#mips_5.17]
|
||||
`source <https://github.com/torvalds/linux/blob/v5.17/arch/mips/kernel/elf.c#L329-L342>`__
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
int mips_elf_read_implies_exec(void *elf_ex, int exstack)
|
||||
{
|
||||
if (exstack != EXSTACK_DISABLE_X) {
|
||||
/* The binary doesn't request a non-executable stack */
|
||||
return 1;
|
||||
}
|
||||
if (!cpu_has_rixi) {
|
||||
/* The CPU doesn't support non-executable memory */
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
int mips_elf_read_implies_exec(void *elf_ex, int exstack)
|
||||
{
|
||||
if (exstack != EXSTACK_DISABLE_X) {
|
||||
/* The binary doesn't request a non-executable stack */
|
||||
return 1;
|
||||
}
|
||||
if (!cpu_has_rixi) {
|
||||
/* The CPU doesn't support non-executable memory */
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
.. [#mips_5.18]
|
||||
`source <https://github.com/torvalds/linux/blob/v5.18/arch/mips/kernel/elf.c#L329-L336>`__
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
int mips_elf_read_implies_exec(void *elf_ex, int exstack)
|
||||
{
|
||||
/*
|
||||
* Set READ_IMPLIES_EXEC only on non-NX systems that
|
||||
* do not request a specific state via PT_GNU_STACK.
|
||||
*/
|
||||
return (!cpu_has_rixi && exstack == EXSTACK_DEFAULT);
|
||||
}
|
||||
int mips_elf_read_implies_exec(void *elf_ex, int exstack)
|
||||
{
|
||||
/*
|
||||
* Set READ_IMPLIES_EXEC only on non-NX systems that
|
||||
* do not request a specific state via PT_GNU_STACK.
|
||||
*/
|
||||
return (!cpu_has_rixi && exstack == EXSTACK_DEFAULT);
|
||||
}
|
||||
|
||||
.. [#powerpc]
|
||||
`source <https://github.com/torvalds/linux/blob/v6.3/arch/powerpc/include/asm/elf.h#L82-L108>`__
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
#ifdef __powerpc64__
|
||||
/* stripped */
|
||||
# define elf_read_implies_exec(ex, exec_stk) (is_32bit_task() ? \\
|
||||
(exec_stk == EXSTACK_DEFAULT) : 0)
|
||||
#else
|
||||
# define elf_read_implies_exec(ex, exec_stk) (exec_stk == EXSTACK_DEFAULT)
|
||||
#endif /* __powerpc64__ */
|
||||
#ifdef __powerpc64__
|
||||
/* stripped */
|
||||
# define elf_read_implies_exec(ex, exec_stk) (is_32bit_task() ? \\
|
||||
(exec_stk == EXSTACK_DEFAULT) : 0)
|
||||
#else
|
||||
# define elf_read_implies_exec(ex, exec_stk) (exec_stk == EXSTACK_DEFAULT)
|
||||
#endif /* __powerpc64__ */
|
||||
|
||||
.. [#ia64]
|
||||
`source <https://github.com/torvalds/linux/blob/v6.3/arch/ia64/include/asm/elf.h#L203-L204>`__
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
#define elf_read_implies_exec(ex, executable_stack) \\
|
||||
((executable_stack!=EXSTACK_DISABLE_X) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0)
|
||||
#define elf_read_implies_exec(ex, executable_stack) \\
|
||||
((executable_stack!=EXSTACK_DISABLE_X) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0)
|
||||
|
||||
EF_IA_64_LINUX_EXECUTABLE_STACK__:
|
||||
.. __: https://github.com/torvalds/linux/blob/v6.3/arch/ia64/include/asm/elf.h#L33
|
||||
EF_IA_64_LINUX_EXECUTABLE_STACK__:
|
||||
|
||||
.. code-block:: c
|
||||
.. __: https://github.com/torvalds/linux/blob/v6.3/arch/ia64/include/asm/elf.h#L33
|
||||
|
||||
#define EF_IA_64_LINUX_EXECUTABLE_STACK 0x1 /* is stack (& heap) executable by default? */
|
||||
.. code-block:: c
|
||||
|
||||
#define EF_IA_64_LINUX_EXECUTABLE_STACK 0x1 /* is stack (& heap) executable by default? */
|
||||
|
||||
.. [#the_rest]
|
||||
`source <https://github.com/torvalds/linux/blob/v6.3/include/linux/elf.h#L13>`__
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
# define elf_read_implies_exec(ex, have_pt_gnu_stack) 0
|
||||
# define elf_read_implies_exec(ex, have_pt_gnu_stack) 0
|
||||
"""
|
||||
if not self.executable:
|
||||
return True
|
||||
@@ -2074,7 +2123,7 @@ class ELF(ELFFile):
|
||||
"NX:".ljust(12) + {
|
||||
True: green("NX enabled"),
|
||||
False: red("NX disabled"),
|
||||
None: yellow("NX unknown - GNU_STACK missing"),
|
||||
None: yellow("NX enabled on new kernels"),
|
||||
}[self.nx],
|
||||
"PIE:".ljust(12) + {
|
||||
True: green("PIE enabled"),
|
||||
@@ -2340,7 +2389,7 @@ class ELF(ELFFile):
|
||||
|
||||
@staticmethod
|
||||
def set_runpath(exepath, runpath):
|
||||
r"""set_runpath(str, str) -> ELF
|
||||
r"""set_runpath(exepath, runpath) -> ELF
|
||||
|
||||
Patches the RUNPATH of the ELF to the given path using the `patchelf utility <https://github.com/NixOS/patchelf>`_.
|
||||
|
||||
@@ -2375,7 +2424,7 @@ class ELF(ELFFile):
|
||||
|
||||
@staticmethod
|
||||
def set_interpreter(exepath, interpreter_path):
|
||||
r"""set_interpreter(str, str) -> ELF
|
||||
r"""set_interpreter(exepath, interpreter_path) -> ELF
|
||||
|
||||
Patches the interpreter of the ELF to the given binary using the `patchelf utility <https://github.com/NixOS/patchelf>`_.
|
||||
|
||||
@@ -2409,7 +2458,7 @@ class ELF(ELFFile):
|
||||
|
||||
@staticmethod
|
||||
def patch_custom_libraries(exe_path, custom_library_path, create_copy=True, suffix='_remotelibc'):
|
||||
r"""patch_custom_libraries(str, str, bool, str) -> ELF
|
||||
r"""patch_custom_libraries(exe_path, custom_library_path, create_copy=True, suffix='_remotelibc') -> ELF
|
||||
|
||||
Looks for the interpreter binary in the given path and patches the binary to use
|
||||
it if available. Also patches the RUNPATH to the given path using the `patchelf utility <https://github.com/NixOS/patchelf>`_.
|
||||
|
||||
+13
-3
@@ -65,16 +65,26 @@ def __ensure_memory_to_run_unicorn():
|
||||
from mmap import mmap, MAP_ANON, MAP_PRIVATE, PROT_EXEC, PROT_READ, PROT_WRITE
|
||||
|
||||
mm = mmap(
|
||||
-1, 1024 * 1024 * 1024, MAP_PRIVATE | MAP_ANON, PROT_WRITE | PROT_READ | PROT_EXEC
|
||||
-1, 1024 * 1024 * 1024, MAP_PRIVATE | MAP_ANON, PROT_WRITE | PROT_READ
|
||||
)
|
||||
mm.close()
|
||||
except OSError:
|
||||
raise OSError("Cannot allocate 1GB memory to run Unicorn Engine")
|
||||
except ImportError:
|
||||
# Can only mmap files on Windows, would need to use VirtualAlloc.
|
||||
pass
|
||||
|
||||
|
||||
def prepare_unicorn_and_context(elf, got, address, data):
|
||||
import unicorn as U
|
||||
|
||||
if elf.arch in ('mips', 'mips64'):
|
||||
# Unicorn 2.1.3 and 2.1.4 have a crashing bug when trying to emulate MIPS.
|
||||
# https://github.com/unicorn-engine/unicorn/issues/2134
|
||||
if U.UC_VERSION_MAJOR == 2 and U.UC_VERSION_MINOR == 1 and U.UC_VERSION_PATCH in (3, 4):
|
||||
raise OSError("Unicorn Engine 2.1.3 and 2.1.4 have a crashing bug when emulating MIPS, please install an earlier or later version: https://github.com/unicorn-engine/unicorn/issues/2134")
|
||||
|
||||
|
||||
__ensure_memory_to_run_unicorn()
|
||||
|
||||
# Instantiate the emulator with the correct arguments for the current
|
||||
@@ -166,8 +176,8 @@ def emulate_plt_instructions_inner(uc, elf, got, pc, data):
|
||||
return False
|
||||
|
||||
hooks = [
|
||||
uc.hook_add(U.UC_HOOK_MEM_READ | U.UC_HOOK_MEM_READ_UNMAPPED,
|
||||
hook_mem, stopped_addr),
|
||||
uc.hook_add(U.UC_HOOK_MEM_READ, hook_mem, stopped_addr),
|
||||
uc.hook_add(U.UC_HOOK_MEM_READ_UNMAPPED, hook_mem, stopped_addr),
|
||||
]
|
||||
|
||||
# callback for tracing instructions
|
||||
|
||||
@@ -132,7 +132,7 @@ class AsciiShellcodeEncoder(Encoder):
|
||||
Examples:
|
||||
|
||||
>>> context.update(arch='i386', os='linux')
|
||||
>>> vocab = bytearray(b'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~')
|
||||
>>> vocab = bytearray(b'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~')
|
||||
>>> encoders.i386.ascii_shellcode.encode._get_allocator(300, vocab)
|
||||
bytearray(b'TX-!!!!-!_``-t~~~P\\%!!!!%@@@@')
|
||||
"""
|
||||
@@ -178,7 +178,7 @@ class AsciiShellcodeEncoder(Encoder):
|
||||
Examples:
|
||||
|
||||
>>> context.update(arch='i386', os='linux')
|
||||
>>> vocab = bytearray(b'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~')
|
||||
>>> vocab = bytearray(b'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~')
|
||||
>>> a, b = encoders.i386.ascii_shellcode.encode._find_negatives(vocab)
|
||||
>>> a & b
|
||||
0
|
||||
@@ -212,7 +212,7 @@ class AsciiShellcodeEncoder(Encoder):
|
||||
|
||||
>>> context.update(arch='i386', os='linux')
|
||||
>>> sc = bytearray(b'ABCDEFGHIGKLMNOPQRSTUVXYZ')
|
||||
>>> vocab = bytearray(b'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~')
|
||||
>>> vocab = bytearray(b'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~')
|
||||
>>> encoders.i386.ascii_shellcode.encode._get_subtractions(sc, vocab)
|
||||
bytearray(b'-(!!!-~NNNP-!=;:-f~~~-~~~~P-!!!!-edee-~~~~P-!!!!-eddd-~~~~P-!!!!-egdd-~~~~P-!!!!-eadd-~~~~P-!!!!-eddd-~~~~P')
|
||||
"""
|
||||
@@ -255,7 +255,7 @@ class AsciiShellcodeEncoder(Encoder):
|
||||
Examples:
|
||||
|
||||
>>> context.update(arch='i386', os='linux')
|
||||
>>> vocab = bytearray(b'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~')
|
||||
>>> vocab = bytearray(b'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~')
|
||||
>>> print(encoders.i386.ascii_shellcode.encode._calc_subtractions(bytearray(b'\x10'*4), bytearray(b'\x11'*4), vocab))
|
||||
[bytearray(b'!!!!'), bytearray(b'`___'), bytearray(b'~~~~')]
|
||||
>>> print(encoders.i386.ascii_shellcode.encode._calc_subtractions(bytearray(b'\x11\x12\x13\x14'), bytearray(b'\x15\x16\x17\x18'), vocab))
|
||||
|
||||
@@ -41,7 +41,7 @@ decoders = {
|
||||
b'\xff\xff\x08\x21', # addi t0,t0,-1
|
||||
b'\xff\xff\x10\x05', # bltzal t0,14 <next>
|
||||
b'\x82\x82\x08\x28', # slti t0,zero,-32126
|
||||
b'\xe2\xff\xfd\x23', # addi sp,ra,-30
|
||||
b'\xe0\xff\xfd\x23', # addi sp,ra,-32
|
||||
b'\x27\x58\x60\x01', # nor t3,t3,zero
|
||||
b'\x21\xc8\xeb\x03', # addu t9,ra,t3
|
||||
b'\x82\x82\x17\x28', # slti s7,zero,-32126
|
||||
@@ -72,7 +72,7 @@ decoders = {
|
||||
b'\x21\x08\xff\xff', # addi t0,t0,-1
|
||||
b'\x05\x10\xff\xff', # bltzal t0,14 <next>
|
||||
b'\x28\x08\x82\x82', # slti t0,zero,-32126
|
||||
b'\x23\xfd\xff\xe2', # addi sp,ra,-30
|
||||
b'\x23\xfd\xff\xe0', # addi sp,ra,-32
|
||||
b'\x01\x60\x58\x27', # nor t3,t3,zero
|
||||
b'\x03\xeb\xc8\x21', # addu t9,ra,t3
|
||||
b'\x28\x17\x82\x82', # slti s7,zero,-32126
|
||||
|
||||
+14
-2
@@ -156,6 +156,18 @@ class FileStructure(object):
|
||||
_wide_data: 0xdeadbeef
|
||||
unknown2: 0x0
|
||||
vtable: 0x0}
|
||||
|
||||
Bytes fields are padded to the correct field size.
|
||||
For example, unknown2 is 56 bytes on i386, so a short value gets
|
||||
zero-padded to 56, not to context.bytes (4):
|
||||
|
||||
>>> context.clear(arch='i386')
|
||||
>>> fileStr2 = FileStructure(null=0)
|
||||
>>> fileStr2.vtable = 0x561859f0
|
||||
>>> old_len = len(bytes(fileStr2))
|
||||
>>> fileStr2.unknown2 = b'AB'
|
||||
>>> len(bytes(fileStr2)) == old_len
|
||||
True
|
||||
"""
|
||||
|
||||
vars_=[]
|
||||
@@ -186,7 +198,7 @@ class FileStructure(object):
|
||||
structure = b''
|
||||
for val in self.vars_:
|
||||
if isinstance(getattr(self, val), bytes):
|
||||
structure += getattr(self, val).ljust(context.bytes, b'\x00')
|
||||
structure += getattr(self, val).ljust(self.length[val], b'\x00')
|
||||
else:
|
||||
if self.length[val] > 0:
|
||||
structure += pack(getattr(self, val), self.length[val]*8)
|
||||
@@ -215,7 +227,7 @@ class FileStructure(object):
|
||||
structure = b''
|
||||
for val in self.vars_:
|
||||
if isinstance(getattr(self, val), bytes):
|
||||
structure += getattr(self, val).ljust(context.bytes, b'\x00')
|
||||
structure += getattr(self, val).ljust(self.length[val], b'\x00')
|
||||
else:
|
||||
structure += pack(getattr(self, val), self.length[val]*8)
|
||||
if val == v:
|
||||
|
||||
+15
-1
@@ -841,6 +841,12 @@ def fmtstr_payload(offset, writes, numbwritten=0, write_size='byte', write_size_
|
||||
The overflows argument is a format-string-length to output-amount tradeoff:
|
||||
Larger values for ``overflows`` produce shorter format strings that generate more output at runtime.
|
||||
|
||||
The writes argument is a dictionary with address/value pairs like ``{addr: value, addr2: value2}``.
|
||||
If the value is an ``int`` datatype, it will be automatically casted into a bytestring with the length of a ``long`` (8 bytes in 64-bit, 4 bytes in 32-bit).
|
||||
If a specific number of bytes is intended to be written (such as only a single byte, single short, or single int and not an entire long),
|
||||
then provide a bytestring like ``b'\x37\x13'`` or ``p16(0x1337)``.
|
||||
Note that the ``write_size`` argument does not determine **total** bytes written, only the size of each consecutive write.
|
||||
|
||||
Arguments:
|
||||
offset(int): the first formatter's offset you control
|
||||
writes(dict): dict with addr, value ``{addr: value, addr2: value2}``
|
||||
@@ -857,6 +863,8 @@ def fmtstr_payload(offset, writes, numbwritten=0, write_size='byte', write_size_
|
||||
>>> context.clear(arch = 'amd64')
|
||||
>>> fmtstr_payload(1, {0x0: 0x1337babe}, write_size='int')
|
||||
b'%322419390c%4$llnaaaabaa\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
>>> fmtstr_payload(1, {0x0: p32(0x1337babe)}, write_size='int')
|
||||
b'%322419390c%3$na\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
>>> fmtstr_payload(1, {0x0: 0x1337babe}, write_size='short')
|
||||
b'%47806c%5$lln%22649c%6$hnaaaabaa\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00'
|
||||
>>> fmtstr_payload(1, {0x0: 0x1337babe}, write_size='byte')
|
||||
@@ -872,6 +880,8 @@ def fmtstr_payload(offset, writes, numbwritten=0, write_size='byte', write_size_
|
||||
b'%19c%12$hhn%36c%13$hhn%131c%14$hhn%4c%15$hhn\x03\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00'
|
||||
>>> fmtstr_payload(1, {0x0: 0x00000001}, write_size='byte')
|
||||
b'c%3$naaa\x00\x00\x00\x00'
|
||||
>>> fmtstr_payload(1, {0x0: b'\x01'}, write_size='byte')
|
||||
b'c%3$hhna\x00\x00\x00\x00'
|
||||
>>> fmtstr_payload(1, {0x0: b"\xff\xff\x04\x11\x00\x00\x00\x00"}, write_size='short')
|
||||
b'%327679c%7$lln%18c%8$hhn\x00\x00\x00\x00\x03\x00\x00\x00'
|
||||
>>> fmtstr_payload(10, {0x404048 : 0xbadc0ffe, 0x40403c : 0xdeadbeef}, no_dollars=True)
|
||||
@@ -999,7 +1009,7 @@ class FmtStr(object):
|
||||
|
||||
Arguments:
|
||||
addr(int): the address where you want to write
|
||||
data(int): the data that you want to write ``addr``
|
||||
data(int or bytes): the data that you want to write ``addr``
|
||||
|
||||
Returns:
|
||||
None
|
||||
@@ -1013,6 +1023,10 @@ class FmtStr(object):
|
||||
>>> f.write(0x08040506, 0x1337babe)
|
||||
>>> f.execute_writes()
|
||||
b'%19c%16$hhn%36c%17$hhn%131c%18$hhn%4c%19$hhn\t\x05\x04\x08\x08\x05\x04\x08\x07\x05\x04\x08\x06\x05\x04\x08'
|
||||
>>> f2 = FmtStr(send_fmt_payload, offset=5)
|
||||
>>> f2.write(0x08040506, p16(0x1337))
|
||||
>>> f2.execute_writes()
|
||||
b'%19c%11$hhn%36c%12$hhnaa\x07\x05\x04\x08\x06\x05\x04\x08'
|
||||
|
||||
"""
|
||||
self.writes[addr] = data
|
||||
+135
-73
@@ -143,7 +143,6 @@ from __future__ import division
|
||||
|
||||
import os
|
||||
import platform
|
||||
import psutil
|
||||
import random
|
||||
import re
|
||||
import six
|
||||
@@ -283,7 +282,7 @@ def _execve_script(argv, executable, env, ssh):
|
||||
return tmp.name
|
||||
|
||||
|
||||
def _gdbserver_args(pid=None, path=None, args=None, which=None, env=None, python_wrapper_script=None):
|
||||
def _gdbserver_args(pid=None, path=None, port=0, gdbserver_args=None, args=None, which=None, env=None, python_wrapper_script=None):
|
||||
"""_gdbserver_args(pid=None, path=None, args=None, which=None, env=None) -> list
|
||||
|
||||
Sets up a listening gdbserver, to either connect to the specified
|
||||
@@ -292,6 +291,8 @@ def _gdbserver_args(pid=None, path=None, args=None, which=None, env=None, python
|
||||
Arguments:
|
||||
pid(int): Process ID to attach to
|
||||
path(str): Process to launch
|
||||
port(int): Port to use for gdbserver, default: random
|
||||
gdbserver_args(list): List of additional arguments to pass to gdbserver
|
||||
args(list): List of arguments to provide on the debugger command line
|
||||
which(callaable): Function to find the path of a binary.
|
||||
env(dict): Environment variables to pass to the program
|
||||
@@ -300,6 +301,11 @@ def _gdbserver_args(pid=None, path=None, args=None, which=None, env=None, python
|
||||
Returns:
|
||||
A list of arguments to invoke gdbserver.
|
||||
"""
|
||||
if gdbserver_args is None:
|
||||
gdbserver_args = list()
|
||||
elif not isinstance(gdbserver_args, (list, tuple)):
|
||||
gdbserver_args = [gdbserver_args]
|
||||
|
||||
if [pid, path, args].count(None) != 2:
|
||||
log.error("Must specify exactly one of pid, path, or args")
|
||||
|
||||
@@ -323,7 +329,7 @@ def _gdbserver_args(pid=None, path=None, args=None, which=None, env=None, python
|
||||
|
||||
orig_args = args
|
||||
|
||||
gdbserver_args = [gdbserver, '--multi']
|
||||
gdbserver_args = [gdbserver, '--multi'] + gdbserver_args
|
||||
if context.aslr:
|
||||
gdbserver_args += ['--no-disable-randomization']
|
||||
else:
|
||||
@@ -346,12 +352,8 @@ def _gdbserver_args(pid=None, path=None, args=None, which=None, env=None, python
|
||||
gdbserver_args += ['--wrapper', python_wrapper_script, '--']
|
||||
elif env is not None:
|
||||
gdbserver_args += ['--wrapper', which('env'), '-i'] + env_args + ['--']
|
||||
# --no-startup-with-shell is required for forking shells like SHELL=/bin/fish
|
||||
# https://github.com/Gallopsled/pwntools/issues/2377
|
||||
else:
|
||||
gdbserver_args += ['--no-startup-with-shell']
|
||||
|
||||
gdbserver_args += ['localhost:0']
|
||||
gdbserver_args += ['localhost:%d' % port]
|
||||
gdbserver_args += args
|
||||
|
||||
return gdbserver_args
|
||||
@@ -416,7 +418,7 @@ def _get_runner(ssh=None):
|
||||
else: return tubes.process.process
|
||||
|
||||
@LocalContext
|
||||
def debug(args, gdbscript=None, exe=None, ssh=None, env=None, sysroot=None, api=False, **kwargs):
|
||||
def debug(args, gdbscript=None, gdb_args=None, exe=None, ssh=None, env=None, port=0, gdbserver_args=None, sysroot=None, api=False, **kwargs):
|
||||
r"""
|
||||
Launch a GDB server with the specified command line,
|
||||
and launches GDB to attach to it.
|
||||
@@ -424,9 +426,12 @@ def debug(args, gdbscript=None, exe=None, ssh=None, env=None, sysroot=None, api=
|
||||
Arguments:
|
||||
args(list): Arguments to the process, similar to :class:`.process`.
|
||||
gdbscript(str): GDB script to run.
|
||||
gdb_args(list): List of additional arguments to pass to GDB.
|
||||
exe(str): Path to the executable on disk
|
||||
env(dict): Environment to start the binary in
|
||||
ssh(:class:`.ssh`): Remote ssh session to use to launch the process.
|
||||
port(int): Gdb port to use, default: random
|
||||
gdbserver_args(list): List of additional arguments to pass to gdbserver
|
||||
sysroot(str): Set an alternate system root. The system root is used to
|
||||
load absolute shared library symbol files. This is useful to instruct
|
||||
gdb to load a local version of binaries/libraries instead of downloading
|
||||
@@ -534,35 +539,6 @@ def debug(args, gdbscript=None, exe=None, ssh=None, env=None, sysroot=None, api=
|
||||
>>> os.remove("./local-libc.so") # cleanup
|
||||
|
||||
|
||||
Using GDB Python API:
|
||||
|
||||
.. doctest::
|
||||
:skipif: is_python2
|
||||
|
||||
Debug a new process
|
||||
|
||||
>>> io = gdb.debug(['echo', 'foo'], api=True)
|
||||
|
||||
Stop at 'write'
|
||||
|
||||
>>> bp = io.gdb.Breakpoint('write', temporary=True)
|
||||
>>> io.gdb.continue_and_wait()
|
||||
|
||||
Dump 'count'
|
||||
|
||||
>>> count = io.gdb.parse_and_eval('$rdx')
|
||||
>>> long = io.gdb.lookup_type('long')
|
||||
>>> int(count.cast(long))
|
||||
4
|
||||
|
||||
Resume the program
|
||||
|
||||
>>> io.gdb.continue_nowait()
|
||||
>>> io.recvline()
|
||||
b'foo\n'
|
||||
>>> io.close()
|
||||
|
||||
|
||||
Using SSH:
|
||||
|
||||
You can use :func:`debug` to spawn new processes on remote machines as well,
|
||||
@@ -602,6 +578,52 @@ def debug(args, gdbscript=None, exe=None, ssh=None, env=None, sysroot=None, api=
|
||||
>>> io.recvline()
|
||||
b'$ \n'
|
||||
>>> io.close()
|
||||
|
||||
|
||||
Using GDB Python API:
|
||||
|
||||
.. doctest::
|
||||
:skipif: is_python2
|
||||
|
||||
Debug a new process
|
||||
|
||||
>>> io = gdb.debug(['echo', 'foo'], api=True)
|
||||
|
||||
or using ssh
|
||||
|
||||
>>> shell = ssh('travis', 'example.pwnme', password='demopass')
|
||||
>>> ssh_io = gdb.debug(['/bin/echo', 'foo'], ssh=shell, api=True)
|
||||
|
||||
Stop at 'write'
|
||||
|
||||
>>> bp = io.gdb.Breakpoint('write', temporary=True)
|
||||
>>> io.gdb.continue_and_wait()
|
||||
>>> ssh_bp = ssh_io.gdb.Breakpoint('write', temporary=True)
|
||||
>>> ssh_io.gdb.continue_and_wait()
|
||||
|
||||
Dump 'count'
|
||||
|
||||
>>> count = io.gdb.parse_and_eval('$rdx')
|
||||
>>> long = io.gdb.lookup_type('long')
|
||||
>>> int(count.cast(long))
|
||||
4
|
||||
>>> count = ssh_io.gdb.parse_and_eval('$rdx')
|
||||
>>> long = ssh_io.gdb.lookup_type('long')
|
||||
>>> int(count.cast(long))
|
||||
4
|
||||
|
||||
Resume the program
|
||||
|
||||
>>> io.gdb.continue_nowait()
|
||||
>>> io.recvline()
|
||||
b'foo\n'
|
||||
>>> io.close()
|
||||
|
||||
>>> ssh_io.gdb.continue_nowait()
|
||||
>>> ssh_io.recvline()
|
||||
b'foo\n'
|
||||
>>> ssh_io.close()
|
||||
>>> shell.close()
|
||||
"""
|
||||
if isinstance(args, six.integer_types + (tubes.process.process, tubes.ssh.ssh_channel)):
|
||||
log.error("Use gdb.attach() to debug a running process")
|
||||
@@ -615,8 +637,8 @@ def debug(args, gdbscript=None, exe=None, ssh=None, env=None, sysroot=None, api=
|
||||
which = _get_which(ssh)
|
||||
gdbscript = gdbscript or ''
|
||||
|
||||
if api and runner is not tubes.process.process:
|
||||
raise ValueError('GDB Python API is supported only for local processes')
|
||||
if api and runner is not tubes.process.process and not ssh:
|
||||
raise ValueError('GDB Python API is supported only for local and ssh processes')
|
||||
|
||||
args, env = misc.normalize_argv_env(args, env, log)
|
||||
if env:
|
||||
@@ -632,7 +654,7 @@ def debug(args, gdbscript=None, exe=None, ssh=None, env=None, sysroot=None, api=
|
||||
|
||||
if ssh or context.native or (context.os == 'android'):
|
||||
if len(args) > 0 and which(packing._decode(args[0])) == packing._decode(exe):
|
||||
args = _gdbserver_args(args=args, which=which, env=env)
|
||||
args = _gdbserver_args(gdbserver_args=gdbserver_args, args=args, port=port, which=which, env=env)
|
||||
|
||||
else:
|
||||
# GDBServer is limited in it's ability to manipulate argv[0]
|
||||
@@ -640,9 +662,9 @@ def debug(args, gdbscript=None, exe=None, ssh=None, env=None, sysroot=None, api=
|
||||
# ``execve`` calls.
|
||||
# Therefore, we use a wrapper script to execute the target binary
|
||||
script = _execve_script(args, executable=exe, env=env, ssh=ssh)
|
||||
args = _gdbserver_args(args=args, which=which, env=env, python_wrapper_script=script)
|
||||
args = _gdbserver_args(gdbserver_args=gdbserver_args, args=args, port=port, which=which, env=env, python_wrapper_script=script)
|
||||
else:
|
||||
qemu_port = random.randint(1024, 65535)
|
||||
qemu_port = port if port != 0 else random.randint(1024, 65535)
|
||||
qemu_user = qemu.user_path()
|
||||
sysroot = sysroot or qemu.ld_prefix(env=env)
|
||||
if not qemu_user:
|
||||
@@ -671,9 +693,11 @@ def debug(args, gdbscript=None, exe=None, ssh=None, env=None, sysroot=None, api=
|
||||
# Set the .executable on the process object.
|
||||
gdbserver.executable = exe
|
||||
|
||||
# Find what port we need to connect to
|
||||
if ssh or context.native or (context.os == 'android'):
|
||||
port = _gdbserver_port(gdbserver, ssh)
|
||||
gdb_port = _gdbserver_port(gdbserver, ssh)
|
||||
if port != 0 and port != gdb_port:
|
||||
log.error("gdbserver port (%d) doesn't equals set port (%d)" % (gdb_port, port))
|
||||
port = gdb_port
|
||||
else:
|
||||
port = qemu_port
|
||||
|
||||
@@ -681,19 +705,20 @@ def debug(args, gdbscript=None, exe=None, ssh=None, env=None, sysroot=None, api=
|
||||
if not ssh and context.os == 'android':
|
||||
host = context.adb_host
|
||||
|
||||
tmp = attach((host, port), exe=exe, gdbscript=gdbscript, ssh=ssh, sysroot=sysroot, api=api)
|
||||
tmp = attach((host, port), exe=exe, gdbscript=gdbscript, gdb_args=gdb_args, ssh=ssh, sysroot=sysroot, api=api)
|
||||
if api:
|
||||
_, gdb = tmp
|
||||
gdbserver.gdb = gdb
|
||||
|
||||
# gdbserver outputs a message when a client connects
|
||||
garbage = gdbserver.recvline(timeout=1)
|
||||
|
||||
# Some versions of gdbserver output an additional message
|
||||
try:
|
||||
garbage2 = gdbserver.recvline_startswith(b"Remote debugging from host ", timeout=2)
|
||||
except EOFError:
|
||||
pass
|
||||
message = b"Remote debugging from host "
|
||||
if not garbage.startswith(message):
|
||||
try:
|
||||
garbage2 = gdbserver.recvline_startswith(message, timeout=2)
|
||||
except EOFError:
|
||||
pass
|
||||
|
||||
return gdbserver
|
||||
|
||||
@@ -720,6 +745,12 @@ def binary():
|
||||
>>> gdb.binary() # doctest: +SKIP
|
||||
'/usr/bin/gdb'
|
||||
"""
|
||||
if context.gdb_binary:
|
||||
gdb = misc.which(context.gdb_binary)
|
||||
if not gdb:
|
||||
log.warn_once('Path to gdb binary `{}` not found'.format(context.gdb_binary))
|
||||
return gdb
|
||||
|
||||
gdb = misc.which('pwntools-gdb') or misc.which('gdb')
|
||||
|
||||
if not context.native:
|
||||
@@ -920,6 +951,8 @@ def attach(target, gdbscript = '', exe = None, gdb_args = None, ssh = None, sysr
|
||||
Process name. The youngest process is selected.
|
||||
:obj:`tuple`
|
||||
Host, port pair of a listening ``gdbserver``
|
||||
Tries to look up the target exe from the ``gdbserver`` commandline,
|
||||
requires explicit ``exe`` argument if the target exe is not in the commandline.
|
||||
:class:`.process`
|
||||
Process to connect to
|
||||
:class:`.sock`
|
||||
@@ -1004,6 +1037,30 @@ def attach(target, gdbscript = '', exe = None, gdb_args = None, ssh = None, sysr
|
||||
>>> io.sendline(b'echo Hello from bash && exit')
|
||||
>>> io.recvall()
|
||||
b'Hello from bash\n'
|
||||
>>> server.close()
|
||||
|
||||
Attach to a gdbserver / gdbstub running on the local machine
|
||||
by specifying the host and port tuple it is listening on.
|
||||
(gdbserver always listens on 0.0.0.0)
|
||||
|
||||
>>> gdbserver = process(['gdbserver', '1.2.3.4:12345', '/bin/bash'])
|
||||
>>> gdbserver.recvline_contains(b'Listening on port', timeout=10)
|
||||
b'Listening on port 12345'
|
||||
>>> pid = gdb.attach(('0.0.0.0', 12345), gdbscript='''
|
||||
... tbreak main
|
||||
... commands
|
||||
... call puts("Hello from gdbserver debugger!")
|
||||
... continue
|
||||
... end
|
||||
... ''')
|
||||
>>> gdbserver.recvline(timeout=10) # doctest: +ELLIPSIS
|
||||
b'Remote debugging from host 127.0.0.1, ...\n'
|
||||
>>> gdbserver.recvline(timeout=10)
|
||||
b'Hello from gdbserver debugger!\n'
|
||||
>>> gdbserver.sendline(b'echo Hello from bash && exit')
|
||||
>>> gdbserver.recvline(timeout=10)
|
||||
b'Hello from bash\n'
|
||||
>>> gdbserver.close()
|
||||
|
||||
Attach to processes running on a remote machine via an SSH :class:`.ssh` process
|
||||
|
||||
@@ -1173,7 +1230,7 @@ def attach(target, gdbscript = '', exe = None, gdb_args = None, ssh = None, sysr
|
||||
cmd += [exe]
|
||||
|
||||
if pid and not context.os == 'android':
|
||||
cmd += [str(pid)]
|
||||
cmd += ['-p', str(pid)]
|
||||
|
||||
if context.os == 'android' and pid:
|
||||
runner = _get_runner()
|
||||
@@ -1221,7 +1278,7 @@ def attach(target, gdbscript = '', exe = None, gdb_args = None, ssh = None, sysr
|
||||
gdb_pid = misc.run_in_new_terminal(cmd, preexec_fn = preexec_fn)
|
||||
|
||||
if pid and context.native:
|
||||
proc.wait_for_debugger(pid, gdb_pid)
|
||||
gdb_pid = proc.wait_for_debugger(pid, gdb_pid)
|
||||
|
||||
if not api:
|
||||
return gdb_pid
|
||||
@@ -1245,7 +1302,7 @@ def attach(target, gdbscript = '', exe = None, gdb_args = None, ssh = None, sysr
|
||||
else:
|
||||
# Check to see if RPyC is installed at all in GDB
|
||||
rpyc_check = [gdb_binary, '--nx', '-batch', '-ex',
|
||||
'python import rpyc; import sys; sys.exit(123)']
|
||||
'python import rpyc; import gdb; gdb.execute("quit 123")']
|
||||
|
||||
if 123 != tubes.process.process(rpyc_check).poll(block=True):
|
||||
log.error('Failed to connect to GDB: rpyc is not installed')
|
||||
@@ -1464,28 +1521,33 @@ def corefile(process):
|
||||
'contain all of the data in the process.\n'
|
||||
'Upgrade to GDB >= 7.11 for better core-dumps.' % binary())
|
||||
|
||||
# This is effectively the same as what the 'gcore' binary does
|
||||
gdb_args = ['-batch',
|
||||
'-q',
|
||||
'-nx',
|
||||
'-ex', 'set pagination off',
|
||||
'-ex', 'set height 0',
|
||||
'-ex', 'set width 0',
|
||||
'-ex', 'set use-coredump-filter on',
|
||||
'-ex', 'generate-core-file %s' % corefile_path,
|
||||
'-ex', 'detach']
|
||||
# This is effectively the same as what the 'gcore' binary does.
|
||||
# Run GDB directly instead of going through attach(), which has to
|
||||
# race GDB to observe the tracer before it already detached again.
|
||||
cmd = [binary(),
|
||||
'-batch',
|
||||
'-q',
|
||||
'-nx',
|
||||
'-ex', 'set pagination off',
|
||||
'-ex', 'set height 0',
|
||||
'-ex', 'set width 0',
|
||||
'-ex', 'set use-coredump-filter on',
|
||||
'-ex', 'attach %d' % process.pid,
|
||||
'-ex', 'generate-core-file %s' % corefile_path,
|
||||
'-ex', 'detach']
|
||||
|
||||
with context.local(terminal = ['sh', '-c']):
|
||||
with context.quiet:
|
||||
pid = attach(process, gdb_args=gdb_args)
|
||||
log.debug("Got GDB pid %d", pid)
|
||||
try:
|
||||
psutil.Process(pid).wait()
|
||||
except psutil.Error:
|
||||
pass
|
||||
with context.quiet:
|
||||
gdb = tubes.process.process(cmd, stdout=tubes.process.PIPE)
|
||||
gdb.wait_for_close(timeout=60)
|
||||
timed_out = gdb.poll() is None
|
||||
output = gdb.recvallS(timeout=0)
|
||||
|
||||
if timed_out:
|
||||
log.error("GDB did not finish dumping process %d within 60 seconds", process.pid)
|
||||
|
||||
if not os.path.exists(corefile_path):
|
||||
log.error("Could not generate a corefile for process %d", process.pid)
|
||||
log.error("Could not generate a corefile for process %d (maybe check /proc/sys/kernel/yama/ptrace_scope)\n%s",
|
||||
process.pid, output)
|
||||
|
||||
return elf.corefile.Core(corefile_path)
|
||||
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ class PwntoolsLexer(RegexLexer):
|
||||
'whitespace': [
|
||||
(r'\n', Text),
|
||||
(r'\s+', Text),
|
||||
(r'/\*.*?\*/', Comment),
|
||||
(r'(?ms)/\*.*?\*/', Comment),
|
||||
(r';.*$', Comment)
|
||||
],
|
||||
'punctuation': [
|
||||
|
||||
+379
-109
@@ -8,12 +8,15 @@ import os
|
||||
import time
|
||||
import six
|
||||
import tempfile
|
||||
import struct
|
||||
import sys
|
||||
|
||||
from pwnlib.context import context
|
||||
from pwnlib.elf import ELF
|
||||
from pwnlib.filesystem.path import Path
|
||||
from pwnlib.log import getLogger
|
||||
from pwnlib.tubes.process import process
|
||||
from pwnlib.util.fiddling import enhex
|
||||
from pwnlib.util.fiddling import enhex, unhex
|
||||
from pwnlib.util.hashes import sha1filehex, sha256filehex, md5filehex
|
||||
from pwnlib.util.misc import read
|
||||
from pwnlib.util.misc import which
|
||||
@@ -22,13 +25,49 @@ from pwnlib.util.web import wget
|
||||
|
||||
log = getLogger(__name__)
|
||||
|
||||
HASHES = {
|
||||
'build_id': lambda path: enhex(ELF(path, checksec=False).buildid or b''),
|
||||
|
||||
def _turbofast_extract_build_id(path):
|
||||
"""
|
||||
Elf_External_Note:
|
||||
|
||||
0x00 +--------+
|
||||
| namesz | <- Size of entry's owner string
|
||||
0x04 +--------+
|
||||
| descsz | <- Size of the note descriptor
|
||||
0x08 +--------+
|
||||
| type | <- Interpretation of the descriptor
|
||||
0x0c +--------+
|
||||
| name | <- Start of the name+desc data
|
||||
... +--------
|
||||
| desc |
|
||||
... +--------+
|
||||
"""
|
||||
data = read(path, 0x1000)
|
||||
# search NT_GNU_BUILD_ID and b"GNU\x00" (type+name)
|
||||
idx = data.find(unhex("03000000474e5500"))
|
||||
if idx == -1:
|
||||
return enhex(ELF(path, checksec=False).buildid or b'')
|
||||
descsz, = struct.unpack("<L", data[idx-4: idx])
|
||||
return enhex(data[idx+8: idx+8+descsz])
|
||||
|
||||
|
||||
TYPES = {
|
||||
'libs_id': None,
|
||||
'build_id': _turbofast_extract_build_id,
|
||||
'sha1': sha1filehex,
|
||||
'sha256': sha256filehex,
|
||||
'md5': md5filehex,
|
||||
}
|
||||
|
||||
# mapping for search result (same as libc.rip)
|
||||
MAP_TYPES = {
|
||||
'libs_id': 'id',
|
||||
'build_id': 'buildid'
|
||||
}
|
||||
|
||||
DEBUGINFOD_SERVERS = [
|
||||
'https://debuginfod.ubuntu.com/',
|
||||
'https://debuginfod.debian.net/',
|
||||
'https://debuginfod.elfutils.org/',
|
||||
]
|
||||
|
||||
@@ -36,18 +75,25 @@ if 'DEBUGINFOD_URLS' in os.environ:
|
||||
urls = os.environ['DEBUGINFOD_URLS'].split(' ')
|
||||
DEBUGINFOD_SERVERS = urls + DEBUGINFOD_SERVERS
|
||||
|
||||
# Allow to override url with a caching proxy in CI
|
||||
LIBC_RIP_URL = os.environ.get("PWN_LIBCRIP_URL", "https://libc.rip").rstrip("/")
|
||||
GITLAB_LIBCDB_URL = os.environ.get("PWN_GITLAB_LIBCDB_URL", "https://gitlab.com").rstrip("/")
|
||||
|
||||
# Retry failed lookups after some time
|
||||
NEGATIVE_CACHE_EXPIRY = 60 * 60 * 24 * 7 # 1 week
|
||||
|
||||
# https://gitlab.com/libcdb/libcdb wasn't updated after 2019,
|
||||
# but still is a massive database of older libc binaries.
|
||||
def provider_libcdb(hex_encoded_id, hash_type):
|
||||
def provider_libcdb(hex_encoded_id, search_type):
|
||||
if search_type == 'libs_id':
|
||||
return None
|
||||
|
||||
# Deferred import because it's slow
|
||||
import requests
|
||||
from six.moves import urllib
|
||||
|
||||
# Build the URL using the requested hash type
|
||||
url_base = "https://gitlab.com/libcdb/libcdb/raw/master/hashes/%s/" % hash_type
|
||||
url_base = "{}/libcdb/libcdb/raw/master/hashes/{}/".format(GITLAB_LIBCDB_URL, search_type)
|
||||
url = urllib.parse.urljoin(url_base, hex_encoded_id)
|
||||
|
||||
data = b""
|
||||
@@ -57,7 +103,7 @@ def provider_libcdb(hex_encoded_id, hash_type):
|
||||
data = wget(url, timeout=20)
|
||||
|
||||
if not data:
|
||||
log.warn_once("Could not fetch libc for %s %s from libcdb", hash_type, hex_encoded_id)
|
||||
log.warn_once("Could not fetch libc for %s %s from libcdb", search_type, hex_encoded_id)
|
||||
break
|
||||
|
||||
# GitLab serves up symlinks with
|
||||
@@ -65,36 +111,53 @@ def provider_libcdb(hex_encoded_id, hash_type):
|
||||
url = os.path.dirname(url) + '/'
|
||||
url = urllib.parse.urljoin(url.encode('utf-8'), data)
|
||||
except requests.RequestException as e:
|
||||
log.warn_once("Failed to fetch libc for %s %s from libcdb: %s", hash_type, hex_encoded_id, e)
|
||||
log.warn_once("Failed to fetch libc for %s %s from libcdb: %s", search_type, hex_encoded_id, e)
|
||||
return data
|
||||
|
||||
def query_libc_rip(params):
|
||||
# Deferred import because it's slow
|
||||
import requests
|
||||
|
||||
url = "https://libc.rip/api/find"
|
||||
try:
|
||||
result = requests.post(url, json=params, timeout=20)
|
||||
result.raise_for_status()
|
||||
if result.status_code != 200:
|
||||
log.debug("Error: %s", result.text)
|
||||
url = "{}/api/find".format(LIBC_RIP_URL)
|
||||
# Handle pagination transparently and fetch all results
|
||||
offset = 0
|
||||
count = 1
|
||||
results = []
|
||||
while offset < count:
|
||||
try:
|
||||
pagination_params = {'offset': offset, 'limit': 100}
|
||||
log.debug("Querying libc.rip at %s (pagination %s) with parameters: %s", url, pagination_params, params)
|
||||
result = requests.post(url, params=pagination_params, json=params, timeout=20)
|
||||
result.raise_for_status()
|
||||
if result.status_code != 200:
|
||||
log.debug("Error: %s", result.text)
|
||||
return None
|
||||
imm_results = result.json()
|
||||
# non-paginated result. old libc-database API?
|
||||
if not isinstance(imm_results, dict):
|
||||
return imm_results
|
||||
results.extend(imm_results.get('results', []))
|
||||
count = imm_results.get('total', 0)
|
||||
offset += imm_results['count']
|
||||
if not imm_results['has_more']:
|
||||
break
|
||||
except requests.RequestException as e:
|
||||
log.warn_once("Failed to fetch libc info from libc.rip: %s", e)
|
||||
return None
|
||||
return result.json()
|
||||
except requests.RequestException as e:
|
||||
log.warn_once("Failed to fetch libc info from libc.rip: %s", e)
|
||||
return None
|
||||
return results
|
||||
|
||||
# https://libc.rip/
|
||||
def provider_libc_rip(hex_encoded_id, hash_type):
|
||||
def provider_libc_rip(search_target, search_type):
|
||||
# Build the request for the hash type
|
||||
# https://github.com/niklasb/libc-database/blob/master/searchengine/api.yml
|
||||
if hash_type == 'build_id':
|
||||
hash_type = 'buildid'
|
||||
params = {hash_type: hex_encoded_id}
|
||||
if search_type in MAP_TYPES.keys():
|
||||
search_type = MAP_TYPES[search_type]
|
||||
|
||||
params = {search_type: search_target}
|
||||
|
||||
libc_match = query_libc_rip(params)
|
||||
if not libc_match:
|
||||
log.warn_once("Could not find libc info for %s %s on libc.rip", hash_type, hex_encoded_id)
|
||||
log.warn_once("Could not find libc info for %s %s on libc.rip", search_type, search_target)
|
||||
return None
|
||||
|
||||
if len(libc_match) > 1:
|
||||
@@ -103,16 +166,17 @@ def provider_libc_rip(hex_encoded_id, hash_type):
|
||||
|
||||
url = libc_match[0]['download_url']
|
||||
log.debug("Downloading data from libc.rip: %s", url)
|
||||
url = url.replace("https://libc.rip", LIBC_RIP_URL)
|
||||
data = wget(url, timeout=20)
|
||||
|
||||
if not data:
|
||||
log.warn_once("Could not fetch libc binary for %s %s from libc.rip", hash_type, hex_encoded_id)
|
||||
log.warn_once("Could not fetch libc binary for %s %s from libc.rip", search_type, search_target)
|
||||
return None
|
||||
return data
|
||||
|
||||
# Check if the local system libc matches the requested hash.
|
||||
def provider_local_system(hex_encoded_id, hash_type):
|
||||
if hash_type == 'id':
|
||||
def provider_local_system(hex_encoded_id, search_type):
|
||||
if search_type == 'libs_id':
|
||||
return None
|
||||
shell_path = os.environ.get('SHELL', None) or '/bin/sh'
|
||||
if not os.path.exists(shell_path):
|
||||
@@ -122,32 +186,118 @@ def provider_local_system(hex_encoded_id, hash_type):
|
||||
if not local_libc:
|
||||
log.debug('Cannot lookup libc from shell %r. Skipping local system libc matching.', shell_path)
|
||||
return None
|
||||
if HASHES[hash_type](local_libc.path) == hex_encoded_id:
|
||||
if TYPES[search_type](local_libc.path) == hex_encoded_id:
|
||||
return local_libc.data
|
||||
return None
|
||||
|
||||
PROVIDERS = [provider_local_system, provider_libcdb, provider_libc_rip]
|
||||
# Offline search https://github.com/niklasb/libc-database for hash type
|
||||
def provider_local_database(search_target, search_type):
|
||||
if not context.local_libcdb:
|
||||
return None
|
||||
|
||||
def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True):
|
||||
assert hash_type in HASHES, hash_type
|
||||
localdb = Path(context.local_libcdb)
|
||||
if not localdb.is_dir():
|
||||
return None
|
||||
|
||||
# Handle the specific search type 'libs_id'
|
||||
if search_type == 'libs_id':
|
||||
libc_list = list(localdb.rglob("%s.so" % search_target))
|
||||
if len(libc_list) == 0:
|
||||
return None
|
||||
return read(libc_list[0])
|
||||
|
||||
log.debug("Searching local libc database, %s: %s", search_type, search_target)
|
||||
for libc_path in localdb.rglob("*.so"):
|
||||
if search_target == TYPES[search_type](libc_path):
|
||||
return read(libc_path)
|
||||
|
||||
return None
|
||||
|
||||
def query_local_database(params):
|
||||
if not context.local_libcdb or not params.get("symbols"):
|
||||
return None
|
||||
|
||||
localdb = Path(context.local_libcdb)
|
||||
if not localdb.is_dir():
|
||||
return None
|
||||
|
||||
res = []
|
||||
query_syms = params["symbols"]
|
||||
|
||||
# Loop through each '.symbols' file in the local database
|
||||
# Make sure `Path.rglod` order stable
|
||||
for symbol_file in sorted(localdb.rglob("*.symbols"), key=lambda x: x.as_posix()):
|
||||
libc_syms = _parse_libc_symbol(symbol_file)
|
||||
|
||||
matched = 0
|
||||
for name, addr in query_syms.items():
|
||||
if isinstance(addr, str):
|
||||
addr = int(addr, 16)
|
||||
|
||||
# Compare last 12 bits
|
||||
if libc_syms.get(name) and (libc_syms.get(name) & 0xfff) == (addr & 0xfff):
|
||||
matched += 1
|
||||
else:
|
||||
# aborting this loop once there was a mismatch.
|
||||
break
|
||||
|
||||
# Check if all symbols have been matched
|
||||
if matched == len(query_syms):
|
||||
libs_id = symbol_file.stem
|
||||
libc_path = symbol_file.parent / ("%s.so" % libs_id)
|
||||
libs_url = read(symbol_file.parent / ("%s.url" % libs_id)).decode().strip()
|
||||
res.append(_pack_libs_info(libc_path, libs_id, libs_url, libc_syms))
|
||||
|
||||
return res
|
||||
|
||||
PROVIDERS = {
|
||||
"offline": [provider_local_system, provider_local_database],
|
||||
"online": [provider_libcdb, provider_libc_rip]
|
||||
}
|
||||
|
||||
def search_by_hash(search_target, search_type='build_id', unstrip=True, offline_only=False):
|
||||
"""search_by_hash(str, str, bool, bool) -> str
|
||||
Arguments:
|
||||
search_target(str):
|
||||
Use for searching the libc. This could be a hex encoded ID (`hex_encoded_id`) or a library
|
||||
name (`libs_id`). Depending on `search_type`, this can represent different types of encoded
|
||||
values or names.
|
||||
search_type(str):
|
||||
The type of the search to be performed, it should be one of the keys in the `TYPES` dictionary.
|
||||
unstrip(bool):
|
||||
Try to fetch debug info for the libc and apply it to the downloaded file.
|
||||
offline_only(bool):
|
||||
If True, restricts the search to offline providers only (local database). If False, it will also
|
||||
search online providers. Default is False.
|
||||
|
||||
Returns:
|
||||
The path to the cached directory containing the downloaded libraries.
|
||||
"""
|
||||
assert search_type in TYPES, search_type
|
||||
|
||||
# Ensure that the libcdb cache directory exists
|
||||
cache, cache_valid = _check_elf_cache('libcdb', hex_encoded_id, hash_type)
|
||||
cache, cache_valid = _check_elf_cache('libcdb', search_target, search_type)
|
||||
if cache_valid:
|
||||
if unstrip:
|
||||
unstrip_libc(cache)
|
||||
return cache
|
||||
|
||||
# We searched for this buildid before, but didn't find anything.
|
||||
if cache is None:
|
||||
return None
|
||||
|
||||
providers = PROVIDERS["offline"]
|
||||
if not offline_only:
|
||||
providers += PROVIDERS["online"]
|
||||
|
||||
# Run through all available libc database providers to see if we have a match.
|
||||
for provider in PROVIDERS:
|
||||
data = provider(hex_encoded_id, hash_type)
|
||||
for provider in providers:
|
||||
data = provider(search_target, search_type)
|
||||
if data and data.startswith(b'\x7FELF'):
|
||||
break
|
||||
|
||||
if not data:
|
||||
log.warn_once("Could not find libc for %s %s anywhere", hash_type, hex_encoded_id)
|
||||
log.warn_once("Could not find libc for %s %s anywhere", search_type, search_target)
|
||||
|
||||
# Save whatever we got to the cache
|
||||
write(cache, data or b'')
|
||||
@@ -162,41 +312,7 @@ def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True):
|
||||
|
||||
return cache
|
||||
|
||||
def _search_debuginfo_by_hash(base_url, hex_encoded_id):
|
||||
# Deferred import because it's slow
|
||||
import requests
|
||||
from six.moves import urllib
|
||||
|
||||
# Check if we tried this buildid before.
|
||||
cache, cache_valid = _check_elf_cache('libcdb_dbg', hex_encoded_id, 'build_id')
|
||||
if cache_valid:
|
||||
return cache
|
||||
|
||||
# We searched for this buildid before, but didn't find anything.
|
||||
if cache is None:
|
||||
return None
|
||||
|
||||
# Try to find separate debuginfo.
|
||||
url = '/buildid/{}/debuginfo'.format(hex_encoded_id)
|
||||
url = urllib.parse.urljoin(base_url, url)
|
||||
data = b""
|
||||
log.debug("Downloading data from debuginfod: %s", url)
|
||||
try:
|
||||
data = wget(url, timeout=20)
|
||||
except requests.RequestException as e:
|
||||
log.warn_once("Failed to fetch libc debuginfo for build_id %s from %s: %s", hex_encoded_id, base_url, e)
|
||||
|
||||
# Save whatever we got to the cache
|
||||
write(cache, data or b'')
|
||||
|
||||
# Return ``None`` if we did not get a valid ELF file
|
||||
if not data or not data.startswith(b'\x7FELF'):
|
||||
log.warn_once("Could not fetch libc debuginfo for build_id %s from %s", hex_encoded_id, base_url)
|
||||
return None
|
||||
|
||||
return cache
|
||||
|
||||
def _check_elf_cache(cache_type, hex_encoded_id, hash_type):
|
||||
def _check_elf_cache(cache_type, search_target, search_type):
|
||||
"""
|
||||
Check if there already is an ELF file for this hash in the cache.
|
||||
|
||||
@@ -209,14 +325,14 @@ def _check_elf_cache(cache_type, hex_encoded_id, hash_type):
|
||||
True
|
||||
"""
|
||||
# Ensure that the cache directory exists
|
||||
cache_dir = os.path.join(context.cache_dir, cache_type, hash_type)
|
||||
cache_dir = os.path.join(context.cache_dir, cache_type, search_type)
|
||||
|
||||
if not os.path.isdir(cache_dir):
|
||||
os.makedirs(cache_dir)
|
||||
|
||||
# If we already downloaded the file, and it looks even passingly like
|
||||
# a valid ELF file, return it.
|
||||
cache = os.path.join(cache_dir, hex_encoded_id)
|
||||
cache = os.path.join(cache_dir, search_target)
|
||||
|
||||
if not os.path.exists(cache):
|
||||
return cache, False
|
||||
@@ -228,7 +344,7 @@ def _check_elf_cache(cache_type, hex_encoded_id, hash_type):
|
||||
# Retry failed lookups after some time
|
||||
if time.time() > os.path.getmtime(cache) + NEGATIVE_CACHE_EXPIRY:
|
||||
return cache, False
|
||||
log.info_once("Skipping invalid cached ELF %s", hex_encoded_id)
|
||||
log.info_once("Skipping invalid cached ELF %s", search_target)
|
||||
return None, False
|
||||
|
||||
log.info_once("Using cached data from %r", cache)
|
||||
@@ -254,15 +370,15 @@ def unstrip_libc(filename):
|
||||
>>> libc = ELF(filename)
|
||||
>>> 'main_arena' in libc.symbols
|
||||
False
|
||||
>>> unstrip_libc(filename)
|
||||
>>> unstrip_libc(filename) # doctest: +SKIP
|
||||
True
|
||||
>>> libc = ELF(filename)
|
||||
>>> hex(libc.symbols.main_arena)
|
||||
>>> hex(libc.symbols.main_arena) # doctest: +SKIP
|
||||
'0x219c80'
|
||||
>>> unstrip_libc(pwnlib.data.elf.get('test-x86'))
|
||||
False
|
||||
>>> filename = search_by_build_id('d1704d25fbbb72fa95d517b883131828c0883fe9', unstrip=True)
|
||||
>>> 'main_arena' in ELF(filename).symbols
|
||||
>>> 'main_arena' in ELF(filename).symbols # doctest: +SKIP
|
||||
True
|
||||
"""
|
||||
if not which('eu-unstrip'):
|
||||
@@ -274,18 +390,51 @@ def unstrip_libc(filename):
|
||||
log.warn_once('Given libc does not have a buildid. Cannot look for debuginfo to unstrip.')
|
||||
return False
|
||||
|
||||
if libc.debuginfo:
|
||||
log.debug('Given libc already contains debug information. Skipping unstrip.')
|
||||
return True
|
||||
|
||||
log.debug('Trying debuginfod servers: %r', DEBUGINFOD_SERVERS)
|
||||
|
||||
for server_url in DEBUGINFOD_SERVERS:
|
||||
libc_dbg = _search_debuginfo_by_hash(server_url, enhex(libc.buildid))
|
||||
if libc_dbg:
|
||||
break
|
||||
else:
|
||||
log.warn_once('Couldn\'t find debug info for libc with build_id %s on any debuginfod server.', enhex(libc.buildid))
|
||||
return False
|
||||
# Deferred import because it's slow
|
||||
import requests
|
||||
from six.moves import urllib
|
||||
|
||||
hex_encoded_id = enhex(libc.buildid)
|
||||
|
||||
# Check if we tried this buildid before.
|
||||
cache, cache_valid = _check_elf_cache('libcdb_dbg', hex_encoded_id, 'build_id')
|
||||
if not cache_valid:
|
||||
# Cached negative result so we don't look for missing debug info everytime.
|
||||
if cache is None:
|
||||
return False
|
||||
else:
|
||||
for server_url in DEBUGINFOD_SERVERS:
|
||||
# Try to find separate debuginfo.
|
||||
url = '/buildid/{}/debuginfo'.format(hex_encoded_id)
|
||||
url = urllib.parse.urljoin(server_url, url)
|
||||
data = b""
|
||||
log.debug("Downloading data from debuginfod: %s", url)
|
||||
try:
|
||||
data = wget(url, timeout=20)
|
||||
|
||||
# Try next server if we didn't get a valid ELF file
|
||||
if not data or not data.startswith(b'\x7FELF'):
|
||||
log.warn_once("Could not fetch libc debuginfo for build_id %s from %s", hex_encoded_id, server_url)
|
||||
continue
|
||||
break
|
||||
except requests.RequestException as e:
|
||||
log.warn_once("Failed to fetch libc debuginfo for build_id %s from %s: %s", hex_encoded_id, server_url, e)
|
||||
else:
|
||||
write(cache, data or b'')
|
||||
log.warn_once('Couldn\'t find debug info for libc with build_id %s on any debuginfod server.', enhex(libc.buildid))
|
||||
return False
|
||||
|
||||
# Save whatever we got to the cache
|
||||
write(cache, data or b'')
|
||||
|
||||
# Add debug info to given libc binary inplace.
|
||||
p = process(['eu-unstrip', '-o', filename, filename, libc_dbg])
|
||||
p = process(['eu-unstrip', '-o', filename, filename, cache])
|
||||
output = p.recvall()
|
||||
p.close()
|
||||
|
||||
@@ -354,7 +503,7 @@ def _extract_tarfile(cache_dir, data_filename, tarball):
|
||||
|
||||
def _extract_debfile(cache_dir, package_filename, package):
|
||||
# Extract data.tar in the .deb archive.
|
||||
if six.PY2:
|
||||
if sys.version_info < (3, 6):
|
||||
if not which('ar'):
|
||||
log.error('Missing command line tool "ar" to extract .deb archive. Please install "ar" first.')
|
||||
|
||||
@@ -401,7 +550,9 @@ def _find_libc_package_lib_url(libc):
|
||||
libc_match = query_libc_rip({'buildid': enhex(libc.buildid)})
|
||||
if libc_match is not None:
|
||||
for match in libc_match:
|
||||
yield match['libs_url']
|
||||
# Allow to override url with a caching proxy in CI
|
||||
ubuntu_archive_url = os.environ.get('PWN_UBUNTU_ARCHIVE_URL', 'http://archive.ubuntu.com').rstrip('/')
|
||||
yield match['libs_url'].replace('http://archive.ubuntu.com', ubuntu_archive_url)
|
||||
|
||||
# Check launchpad.net if it's an Ubuntu libc
|
||||
# GNU C Library (Ubuntu GLIBC 2.36-0ubuntu4)
|
||||
@@ -518,7 +669,7 @@ def _handle_multiple_matching_libcs(matching_libcs):
|
||||
selected_index = options("Select the libc version to use:", [libc['id'] for libc in matching_libcs])
|
||||
return matching_libcs[selected_index]
|
||||
|
||||
def search_by_symbol_offsets(symbols, select_index=None, unstrip=True, return_as_list=False):
|
||||
def search_by_symbol_offsets(symbols, select_index=None, unstrip=True, offline_only=False, search_type='build_id', return_as_list=False, return_raw=False):
|
||||
"""
|
||||
Lookup possible matching libc versions based on leaked function addresses.
|
||||
|
||||
@@ -537,9 +688,16 @@ def search_by_symbol_offsets(symbols, select_index=None, unstrip=True, return_as
|
||||
The libc to select if there are multiple matches (starting at 1).
|
||||
unstrip(bool):
|
||||
Try to fetch debug info for the libc and apply it to the downloaded file.
|
||||
offline_only(bool):
|
||||
When pass `offline_only=True`, restricts search mode to offline sources only,
|
||||
disable online lookup. Defaults to `False`, and enable both offline and online providers.
|
||||
search_type(str):
|
||||
An option to select searched hash.
|
||||
return_as_list(bool):
|
||||
Return a list of build ids of all matching libc versions
|
||||
instead of a path to a downloaded file.
|
||||
return_raw(bool):
|
||||
Return raw list of matched libc.
|
||||
|
||||
Returns:
|
||||
Path to the downloaded library on disk, or :const:`None`.
|
||||
@@ -555,38 +713,94 @@ def search_by_symbol_offsets(symbols, select_index=None, unstrip=True, return_as
|
||||
>>> matched_libcs = search_by_symbol_offsets({'__libc_start_main_ret': '7f89ad926550'}, return_as_list=True)
|
||||
>>> len(matched_libcs) > 1
|
||||
True
|
||||
>>> for buildid in matched_libcs: # doctest +SKIP
|
||||
... libc = ELF(search_by_build_id(buildid)) # doctest +SKIP
|
||||
>>> for buildid in matched_libcs: # doctest: +SKIP
|
||||
... libc = ELF(search_by_build_id(buildid)) # doctest: +SKIP
|
||||
"""
|
||||
assert search_type in TYPES, search_type
|
||||
|
||||
for symbol, address in symbols.items():
|
||||
if isinstance(address, int):
|
||||
symbols[symbol] = hex(address)
|
||||
|
||||
params = {'symbols': symbols}
|
||||
log.debug('Request: %s', params)
|
||||
matching_libcs = query_libc_rip(params)
|
||||
log.debug('Result: %s', matching_libcs)
|
||||
if matching_libcs is None or len(matching_libcs) == 0:
|
||||
log.warn_once("No matching libc for symbols %r on libc.rip", symbols)
|
||||
|
||||
offline_matching = query_local_database(params)
|
||||
online_matching = query_libc_rip(params) if not offline_only else None
|
||||
|
||||
if offline_matching is None:
|
||||
offline_matching = []
|
||||
if online_matching is None:
|
||||
online_matching = []
|
||||
|
||||
# Aggregate and deduplicate matches from both sources
|
||||
matching_libcs = {}
|
||||
for libc in offline_matching + online_matching:
|
||||
if libc['id'] not in matching_libcs:
|
||||
matching_libcs[libc['id']] = libc
|
||||
|
||||
log.debug('Offline search result: %s', offline_matching)
|
||||
if not offline_only:
|
||||
log.debug('Online search result: %s', online_matching)
|
||||
|
||||
# Check if no matches are found
|
||||
if len(matching_libcs) == 0:
|
||||
log.warn_once("No matching libc for symbols %r", symbols)
|
||||
return None
|
||||
|
||||
matching_list = list(matching_libcs.values())
|
||||
|
||||
if return_as_list:
|
||||
return [libc['buildid'] for libc in matching_libcs]
|
||||
return [libc['buildid'] for libc in matching_list]
|
||||
|
||||
if len(matching_libcs) == 1:
|
||||
return search_by_build_id(matching_libcs[0]['buildid'], unstrip=unstrip)
|
||||
if return_raw:
|
||||
return matching_list
|
||||
|
||||
mapped_type = MAP_TYPES.get(search_type, search_type)
|
||||
|
||||
# If there's only one match, return it directly
|
||||
if len(matching_list) == 1:
|
||||
return search_by_hash(matching_list[0][mapped_type], search_type=search_type, unstrip=unstrip, offline_only=offline_only)
|
||||
|
||||
# If a specific index is provided, validate it and return the selected libc
|
||||
if select_index is not None:
|
||||
if select_index > 0 and select_index <= len(matching_libcs):
|
||||
return search_by_build_id(matching_libcs[select_index - 1]['buildid'], unstrip=unstrip)
|
||||
if select_index > 0 and select_index <= len(matching_list):
|
||||
return search_by_hash(matching_list[select_index - 1][mapped_type], search_type=search_type, unstrip=unstrip, offline_only=offline_only)
|
||||
else:
|
||||
log.error('Invalid selected libc index. %d is not in the range of 1-%d.', select_index, len(matching_libcs))
|
||||
log.error('Invalid selected libc index. %d is not in the range of 1-%d.', select_index, len(matching_list))
|
||||
return None
|
||||
|
||||
selected_libc = _handle_multiple_matching_libcs(matching_libcs)
|
||||
return search_by_build_id(selected_libc['buildid'], unstrip=unstrip)
|
||||
# Handle multiple matches interactively if no index is specified
|
||||
selected_libc = _handle_multiple_matching_libcs(matching_list)
|
||||
return search_by_hash(selected_libc[mapped_type], search_type=search_type, unstrip=unstrip, offline_only=offline_only)
|
||||
|
||||
def search_by_build_id(hex_encoded_id, unstrip=True):
|
||||
def search_by_libs_id(libs_id, unstrip=True, offline_only=False):
|
||||
"""
|
||||
Given a Libs ID, attempt to download a matching libc from libcdb.
|
||||
|
||||
Arguments:
|
||||
libs_id(str):
|
||||
Libs ID (e.g. ``'libc6_...'``) of the library
|
||||
unstrip(bool):
|
||||
Try to fetch debug info for the libc and apply it to the downloaded file.
|
||||
offline_only(bool):
|
||||
When pass ``offline_only=True``, restricts search mode to offline sources only,
|
||||
disable online lookup. Defaults to :const:`False`, and enable both offline and online providers.
|
||||
|
||||
Returns:
|
||||
Path to the downloaded library on disk, or :const:`None`.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> None == search_by_libs_id('XX')
|
||||
True
|
||||
>>> filename = search_by_libs_id('libc6_2.31-3_amd64')
|
||||
>>> hex(ELF(filename).symbols.read)
|
||||
'0xeef40'
|
||||
"""
|
||||
return search_by_hash(libs_id, 'libs_id', unstrip, offline_only)
|
||||
|
||||
def search_by_build_id(hex_encoded_id, unstrip=True, offline_only=False):
|
||||
"""
|
||||
Given a hex-encoded Build ID, attempt to download a matching libc from libcdb.
|
||||
|
||||
@@ -595,6 +809,9 @@ def search_by_build_id(hex_encoded_id, unstrip=True):
|
||||
Hex-encoded Build ID (e.g. 'ABCDEF...') of the library
|
||||
unstrip(bool):
|
||||
Try to fetch debug info for the libc and apply it to the downloaded file.
|
||||
offline_only(bool):
|
||||
When pass `offline_only=True`, restricts search mode to offline sources only,
|
||||
disable online lookup. Defaults to `False`, and enable both offline and online providers.
|
||||
|
||||
Returns:
|
||||
Path to the downloaded library on disk, or :const:`None`.
|
||||
@@ -610,9 +827,9 @@ def search_by_build_id(hex_encoded_id, unstrip=True):
|
||||
>>> hex(ELF(filename).symbols.read)
|
||||
'0xeef40'
|
||||
"""
|
||||
return search_by_hash(hex_encoded_id, 'build_id', unstrip)
|
||||
return search_by_hash(hex_encoded_id, 'build_id', unstrip, offline_only)
|
||||
|
||||
def search_by_md5(hex_encoded_id, unstrip=True):
|
||||
def search_by_md5(hex_encoded_id, unstrip=True, offline_only=False):
|
||||
"""
|
||||
Given a hex-encoded md5sum, attempt to download a matching libc from libcdb.
|
||||
|
||||
@@ -621,6 +838,9 @@ def search_by_md5(hex_encoded_id, unstrip=True):
|
||||
Hex-encoded md5sum (e.g. 'ABCDEF...') of the library
|
||||
unstrip(bool):
|
||||
Try to fetch debug info for the libc and apply it to the downloaded file.
|
||||
offline_only(bool):
|
||||
When pass `offline_only=True`, restricts search mode to offline sources only,
|
||||
disable online lookup. Defaults to `False`, and enable both offline and online providers.
|
||||
|
||||
Returns:
|
||||
Path to the downloaded library on disk, or :const:`None`.
|
||||
@@ -636,9 +856,9 @@ def search_by_md5(hex_encoded_id, unstrip=True):
|
||||
>>> hex(ELF(filename).symbols.read)
|
||||
'0xeef40'
|
||||
"""
|
||||
return search_by_hash(hex_encoded_id, 'md5', unstrip)
|
||||
return search_by_hash(hex_encoded_id, 'md5', unstrip, offline_only)
|
||||
|
||||
def search_by_sha1(hex_encoded_id, unstrip=True):
|
||||
def search_by_sha1(hex_encoded_id, unstrip=True, offline_only=False):
|
||||
"""
|
||||
Given a hex-encoded sha1, attempt to download a matching libc from libcdb.
|
||||
|
||||
@@ -647,6 +867,9 @@ def search_by_sha1(hex_encoded_id, unstrip=True):
|
||||
Hex-encoded sha1sum (e.g. 'ABCDEF...') of the library
|
||||
unstrip(bool):
|
||||
Try to fetch debug info for the libc and apply it to the downloaded file.
|
||||
offline_only(bool):
|
||||
When pass `offline_only=True`, restricts search mode to offline sources only,
|
||||
disable online lookup. Defaults to `False`, and enable both offline and online providers.
|
||||
|
||||
Returns:
|
||||
Path to the downloaded library on disk, or :const:`None`.
|
||||
@@ -662,10 +885,9 @@ def search_by_sha1(hex_encoded_id, unstrip=True):
|
||||
>>> hex(ELF(filename).symbols.read)
|
||||
'0xeef40'
|
||||
"""
|
||||
return search_by_hash(hex_encoded_id, 'sha1', unstrip)
|
||||
return search_by_hash(hex_encoded_id, 'sha1', unstrip, offline_only)
|
||||
|
||||
|
||||
def search_by_sha256(hex_encoded_id, unstrip=True):
|
||||
def search_by_sha256(hex_encoded_id, unstrip=True, offline_only=False):
|
||||
"""
|
||||
Given a hex-encoded sha256, attempt to download a matching libc from libcdb.
|
||||
|
||||
@@ -674,6 +896,9 @@ def search_by_sha256(hex_encoded_id, unstrip=True):
|
||||
Hex-encoded sha256sum (e.g. 'ABCDEF...') of the library
|
||||
unstrip(bool):
|
||||
Try to fetch debug info for the libc and apply it to the downloaded file.
|
||||
offline_only(bool):
|
||||
When pass `offline_only=True`, restricts search mode to offline sources only,
|
||||
disable online lookup. Defaults to `False`, and enable both offline and online providers.
|
||||
|
||||
Returns:
|
||||
Path to the downloaded library on disk, or :const:`None`.
|
||||
@@ -689,9 +914,54 @@ def search_by_sha256(hex_encoded_id, unstrip=True):
|
||||
>>> hex(ELF(filename).symbols.read)
|
||||
'0xeef40'
|
||||
"""
|
||||
return search_by_hash(hex_encoded_id, 'sha256', unstrip)
|
||||
return search_by_hash(hex_encoded_id, 'sha256', unstrip, offline_only)
|
||||
|
||||
def _parse_libc_symbol(path):
|
||||
"""
|
||||
Parse symbols file to `dict`, the format is same as https://github.com/niklasb/libc-database/
|
||||
"""
|
||||
|
||||
syms = {}
|
||||
|
||||
with open(path, "r") as fd:
|
||||
for x in fd:
|
||||
name, addr = x.split(" ")
|
||||
syms[name] = int(addr, 16)
|
||||
|
||||
return syms
|
||||
|
||||
def _pack_libs_info(path, libs_id, libs_url, syms):
|
||||
"""
|
||||
The JSON format is the same as libc.rip, and the "download_url" field is by default an empty string,
|
||||
as it's not required in offline mode.
|
||||
"""
|
||||
|
||||
info = {}
|
||||
|
||||
info["id"] = libs_id
|
||||
info["libs_url"] = libs_url
|
||||
info["download_url"] = ""
|
||||
|
||||
for search_type, hash_func in TYPES.items():
|
||||
# pass libs_id
|
||||
if search_type == 'libs_id':
|
||||
continue
|
||||
|
||||
# replace search_type
|
||||
if search_type in MAP_TYPES.keys():
|
||||
search_type = MAP_TYPES[search_type]
|
||||
|
||||
info[search_type] = hash_func(path)
|
||||
|
||||
default_symbol_list = [
|
||||
"__libc_start_main_ret", "dup2", "printf", "puts", "read", "system", "str_bin_sh"
|
||||
]
|
||||
|
||||
info["symbols"] = {}
|
||||
for name in default_symbol_list:
|
||||
info["symbols"][name] = hex(syms[name])
|
||||
|
||||
return info
|
||||
|
||||
|
||||
def get_build_id_offsets():
|
||||
@@ -746,4 +1016,4 @@ def get_build_id_offsets():
|
||||
}.get(context.arch, [])
|
||||
|
||||
|
||||
__all__ = ['get_build_id_offsets', 'search_by_build_id', 'search_by_sha1', 'search_by_sha256', 'search_by_md5', 'unstrip_libc', 'search_by_symbol_offsets', 'download_libraries']
|
||||
__all__ = ['get_build_id_offsets', 'search_by_build_id', 'search_by_sha1', 'search_by_sha256', 'search_by_md5', 'search_by_libs_id', 'unstrip_libc', 'search_by_symbol_offsets', 'download_libraries']
|
||||
+2
-1
@@ -546,7 +546,8 @@ class Handler(logging.StreamHandler):
|
||||
|
||||
# if the record originates from a `Progress` object and term handling
|
||||
# is enabled we can have animated spinners! so check that
|
||||
if progress is None or not term.term_mode:
|
||||
# Don't show spinners if the output is being redirected
|
||||
if progress is None or not term.term_mode or not os.path.sameopenfile(context.log_console.fileno(), term.term.fd.fileno()):
|
||||
super(Handler, self).emit(record)
|
||||
return
|
||||
|
||||
|
||||
+2
-1
@@ -105,6 +105,7 @@ def archname():
|
||||
('powerpc64', 'little'): 'ppc64le',
|
||||
('thumb', 'little'): 'arm',
|
||||
('thumb', 'big'): 'armeb',
|
||||
('aarch64', 'big'): 'aarch64_be',
|
||||
}.get((context.arch, context.endian), context.arch)
|
||||
|
||||
@LocalContext
|
||||
@@ -139,7 +140,7 @@ def user_path():
|
||||
def ld_prefix(path=None, env=None):
|
||||
"""Returns the linker prefix for the selected qemu-user binary
|
||||
|
||||
>>> pwnlib.qemu.ld_prefix(arch='arm')
|
||||
>>> pwnlib.qemu.ld_prefix(arch='arm') # doctest: +SKIP
|
||||
'/etc/qemu-binfmt/arm'
|
||||
"""
|
||||
if context.os == 'baremetal':
|
||||
|
||||
+51
-16
@@ -15,7 +15,7 @@ from pwnlib.log import getLogger
|
||||
|
||||
log = getLogger(__name__)
|
||||
|
||||
def check_cycle(reg, assignments):
|
||||
def check_cycle(reg, assignments, mapping=None):
|
||||
"""Walk down the assignment list of a register,
|
||||
return the path walked if it is encountered again.
|
||||
|
||||
@@ -37,31 +37,38 @@ def check_cycle(reg, assignments):
|
||||
>>> check_cycle('a', {'a': 'b', 'b': 'c', 'c': 'd', 'd': 'a'})
|
||||
['a', 'b', 'c', 'd']
|
||||
"""
|
||||
return check_cycle_(reg, assignments, [])
|
||||
if mapping is None:
|
||||
mapping = {}
|
||||
return check_cycle_(reg, assignments, [], mapping)
|
||||
|
||||
def check_cycle_(reg, assignments, path):
|
||||
target = assignments[reg]
|
||||
def check_cycle_(reg, assignments, path, mapping):
|
||||
target = assignments.get(reg)
|
||||
if target is None:
|
||||
real_reg = mapping.get(reg, reg)
|
||||
reg, target = next((k, v) for k,v in assignments.items() if mapping.get(k, k) == real_reg)
|
||||
path.append(reg)
|
||||
|
||||
real_target = mapping.get(target, target)
|
||||
|
||||
# No cycle, some other value (e.g. 1)
|
||||
if target not in assignments:
|
||||
if all(real_target != mapping.get(k, k) for k in assignments):
|
||||
return []
|
||||
|
||||
# Found a cycle
|
||||
if target in path:
|
||||
if any(real_target == mapping.get(k, k) for k in path):
|
||||
# Does the cycle *start* with target?
|
||||
# This determines whether the original register is
|
||||
# in the cycle, or just depends on registers in one.
|
||||
if target == path[0]:
|
||||
if real_target == mapping.get(path[0], path[0]):
|
||||
return path
|
||||
|
||||
# Just depends on one.
|
||||
return []
|
||||
|
||||
# Recurse
|
||||
return check_cycle_(target, assignments, path)
|
||||
return check_cycle_(target, assignments, path, mapping)
|
||||
|
||||
def extract_dependencies(reg, assignments):
|
||||
def extract_dependencies(reg, assignments, mapping=None):
|
||||
"""Return a list of all registers which directly
|
||||
depend on the specified register.
|
||||
|
||||
@@ -77,7 +84,9 @@ def extract_dependencies(reg, assignments):
|
||||
['b', 'c']
|
||||
"""
|
||||
# sorted() is only for determinism
|
||||
return sorted([k for k,v in assignments.items() if v == reg])
|
||||
if mapping is None:
|
||||
mapping = {}
|
||||
return sorted([k for k,v in assignments.items() if mapping.get(v, v) == mapping.get(reg, reg)])
|
||||
|
||||
|
||||
def resolve_order(reg, deps):
|
||||
@@ -110,7 +119,7 @@ def depends_on_cycle(reg, assignments, in_cycles):
|
||||
reg = assignments.get(reg, None)
|
||||
return False
|
||||
|
||||
def regsort(in_out, all_regs, tmp = None, xchg = True, randomize = None):
|
||||
def regsort(in_out, all_regs, mapping = None, tmp = None, xchg = True, randomize = None):
|
||||
"""
|
||||
Sorts register dependencies.
|
||||
|
||||
@@ -181,6 +190,15 @@ def regsort(in_out, all_regs, tmp = None, xchg = True, randomize = None):
|
||||
|
||||
>>> regsort({'a': 1, 'b': 2}, R)
|
||||
[('mov', 'a', 1), ('mov', 'b', 2)]
|
||||
>>> M = {'ax': 'eax', 'eax': 'eax', 'ebx': 'ebx'}
|
||||
|
||||
Registers which are assigned one of their own aliases
|
||||
are dropped, like same-name self-assignments.
|
||||
|
||||
>>> regsort({'ax': 'eax'}, M)
|
||||
[]
|
||||
>>> regsort({'ax': 'eax'}, M, xchg=False)
|
||||
[]
|
||||
>>> regsort({'a': 'b', 'b': 'a'}, R)
|
||||
[('xchg', 'a', 'b')]
|
||||
>>> regsort({'a': 'b', 'b': 'a'}, R, tmp='X') #doctest: +NORMALIZE_WHITESPACE
|
||||
@@ -233,16 +251,24 @@ def regsort(in_out, all_regs, tmp = None, xchg = True, randomize = None):
|
||||
if randomize is None:
|
||||
randomize = context.randomize
|
||||
|
||||
if mapping is None:
|
||||
if hasattr(all_regs, 'keys'):
|
||||
mapping = all_regs
|
||||
else:
|
||||
mapping = {}
|
||||
|
||||
sentinel = object()
|
||||
|
||||
# Drop all registers which will be set to themselves.
|
||||
#
|
||||
# For example, {'eax': 'eax'}
|
||||
in_out = {k:v for k,v in in_out.items() if k != v}
|
||||
# This must go through the mapping, so that {'ax': 'eax'} is
|
||||
# recognized as a self-assignment as well.
|
||||
in_out = {k:v for k,v in in_out.items() if mapping.get(k, k) != mapping.get(v, v)}
|
||||
|
||||
# Collapse constant values
|
||||
#
|
||||
# For eaxmple, {'eax': 0, 'ebx': 0} => {'eax': 0, 'ebx': 'eax'}
|
||||
# For example, {'eax': 0, 'ebx': 0} => {'eax': 0, 'ebx': 'eax'}
|
||||
v_k = defaultdict(list)
|
||||
for k,v in sorted(in_out.items()):
|
||||
if v not in all_regs and v != 0:
|
||||
@@ -263,7 +289,9 @@ def regsort(in_out, all_regs, tmp = None, xchg = True, randomize = None):
|
||||
# which are also 'outputs'.
|
||||
#
|
||||
# For example, {'eax': 1, 'ebx': 2, 'ecx': 'edx'}
|
||||
if not any(v in in_out for k,v in in_out.items()):
|
||||
inps = {mapping.get(k, k) for k in in_out}
|
||||
outs = {mapping.get(v, v) for v in in_out.values()}
|
||||
if not inps & outs:
|
||||
result = [('mov', k,in_out[k]) for k in sorted(in_out)]
|
||||
|
||||
if randomize:
|
||||
@@ -280,7 +308,7 @@ def regsort(in_out, all_regs, tmp = None, xchg = True, randomize = None):
|
||||
# Output: {'A': [], 'B': ['A', 'C'], 'C': []}
|
||||
#
|
||||
# In this case, both A and C must be set before B.
|
||||
deps = {r: extract_dependencies(r, in_out) for r in in_out}
|
||||
deps = {r: extract_dependencies(r, in_out, mapping) for r in in_out}
|
||||
|
||||
# Final result which will be returned
|
||||
result = []
|
||||
@@ -299,7 +327,7 @@ def regsort(in_out, all_regs, tmp = None, xchg = True, randomize = None):
|
||||
|
||||
while cycle_candidates:
|
||||
reg = cycle_candidates[0]
|
||||
cycle = check_cycle(reg, in_out)
|
||||
cycle = check_cycle(reg, in_out, mapping)
|
||||
|
||||
if cycle:
|
||||
if randomize:
|
||||
@@ -395,6 +423,10 @@ def regsort(in_out, all_regs, tmp = None, xchg = True, randomize = None):
|
||||
|
||||
if tmp:
|
||||
for cycle in cycles:
|
||||
if len(cycle) == 1:
|
||||
[reg] = cycle
|
||||
result.append(('mov', reg, in_out[reg]))
|
||||
continue
|
||||
|
||||
first = cycle[0]
|
||||
last = cycle[-1]
|
||||
@@ -411,6 +443,9 @@ def regsort(in_out, all_regs, tmp = None, xchg = True, randomize = None):
|
||||
else:
|
||||
for cycle in cycles:
|
||||
size = len(cycle)
|
||||
if size == 1:
|
||||
[reg] = cycle
|
||||
result.append(('mov', reg, in_out[reg]))
|
||||
for i in range(size-1):
|
||||
result.append(('xchg', cycle[i], cycle[(i+1) % size]))
|
||||
|
||||
|
||||
@@ -219,11 +219,24 @@ class Ret2dlresolvePayload(object):
|
||||
elf (ELF): Binary to search
|
||||
symbol (str): Function to search for
|
||||
args (list): List of arguments to pass to the function
|
||||
data_addr (int|None): The address where the payload will
|
||||
be written to. If not provided, a suitable address will
|
||||
be chosen automatically (recommended).
|
||||
resolution_addr (int|None): The address where the location
|
||||
of the resolved symbol will be written to. If not provided
|
||||
will be equal to data_addr.
|
||||
|
||||
Returns:
|
||||
A ``Ret2dlresolvePayload`` object which can be passed to ``rop.ret2dlresolve``
|
||||
A ``Ret2dlresolvePayload`` object. It can be passed to ``rop.ret2dlresolve``
|
||||
for automatic exploitation.
|
||||
|
||||
If that is not suitable the object generates useful values (.reloc_index
|
||||
and .payload) which can be used to aid manual exploitation. In this case
|
||||
it is recommended to set .resolution_addr to the GOT address of an easily
|
||||
callable function (do not set it when passing the object to
|
||||
rop.ret2dlresolve).
|
||||
"""
|
||||
def __init__(self, elf, symbol, args, data_addr=None):
|
||||
def __init__(self, elf, symbol, args, data_addr=None, resolution_addr=None):
|
||||
self.elf = elf
|
||||
self.elf_load_address_fixup = self.elf.address - self.elf.load_addr
|
||||
self.strtab = elf.dynamic_value_by_tag("DT_STRTAB") + self.elf_load_address_fixup
|
||||
@@ -236,6 +249,7 @@ class Ret2dlresolvePayload(object):
|
||||
self.unreliable = False
|
||||
|
||||
self.data_addr = data_addr if data_addr is not None else self._get_recommended_address()
|
||||
self.resolution_addr = resolution_addr if resolution_addr is not None else self.data_addr
|
||||
|
||||
# Will be set when built
|
||||
self.reloc_index = -1
|
||||
@@ -302,11 +316,11 @@ class Ret2dlresolvePayload(object):
|
||||
# ElfRel
|
||||
rel_addr = self.jmprel + self.reloc_index * ElfRel.size
|
||||
rel_type = 7
|
||||
rel = ElfRel(r_offset=self.data_addr, r_info=(index<<ELF_R_SYM_SHIFT)+rel_type)
|
||||
rel = ElfRel(r_offset=self.resolution_addr, r_info=(index<<ELF_R_SYM_SHIFT)+rel_type)
|
||||
|
||||
# When a program's PIE is enabled, r_offset should be the relative address, not the absolute address
|
||||
if self.elf.pie:
|
||||
rel = ElfRel(r_offset=self.data_addr - (self.elf.load_addr + self.elf_load_address_fixup), r_info=(index<<ELF_R_SYM_SHIFT)+rel_type)
|
||||
rel = ElfRel(r_offset=self.resolution_addr - (self.elf.load_addr + self.elf_load_address_fixup), r_info=(index<<ELF_R_SYM_SHIFT)+rel_type)
|
||||
|
||||
self.payload = fit({
|
||||
symbol_name_addr - self.data_addr: symbol_name,
|
||||
@@ -325,6 +339,7 @@ class Ret2dlresolvePayload(object):
|
||||
log.debug("Symbol name addr: %s", hex(symbol_name_addr))
|
||||
log.debug("Version index addr: %s", hex(ver_addr))
|
||||
log.debug("Data addr: %s", hex(self.data_addr))
|
||||
log.debug("Resolution addr: %s", hex(self.resolution_addr))
|
||||
if not self.elf.memory[ver_addr]:
|
||||
log.warn("Ret2dlresolve is likely impossible in this ELF "
|
||||
"(too big gap between text and writable sections).\n"
|
||||
|
||||
+13
-7
@@ -390,6 +390,7 @@ from pwnlib.rop.call import Unresolved
|
||||
from pwnlib.rop.gadgets import Gadget
|
||||
from pwnlib.util import lists
|
||||
from pwnlib.util import packing
|
||||
from pwnlib.util import safeeval
|
||||
from pwnlib.util.cyclic import cyclic
|
||||
from pwnlib.util.packing import pack
|
||||
from pwnlib.util.misc import python_2_bytes_compatible
|
||||
@@ -841,7 +842,7 @@ class ROP(object):
|
||||
"""
|
||||
if isinstance(object, enums):
|
||||
return str(object)
|
||||
if isinstance(object, six.integer_types):
|
||||
if isinstance(object, six.integer_types) and object:
|
||||
return self.unresolve(object)
|
||||
if isinstance(object, (bytes, six.text_type)):
|
||||
return repr(object)
|
||||
@@ -1272,7 +1273,7 @@ class ROP(object):
|
||||
filename = self.__get_cachefile_name(elf)
|
||||
if filename is None or not os.path.exists(filename):
|
||||
return None
|
||||
gadgets = eval(open(filename).read())
|
||||
gadgets = safeeval.const(open(filename).read())
|
||||
gadgets = {k - elf.load_addr + elf.address:v for k, v in gadgets.items()}
|
||||
log.info_once('Loaded %s cached gadgets for %r', len(gadgets), elf.file.name)
|
||||
return gadgets
|
||||
@@ -1391,6 +1392,8 @@ class ROP(object):
|
||||
if pop.match(insn):
|
||||
regs.append(pop.match(insn).group(1))
|
||||
sp_move += context.bytes
|
||||
if 'sp' in insn:
|
||||
sp_move += 9999999
|
||||
elif add.match(insn):
|
||||
arg = int(add.match(insn).group(1), 16)
|
||||
sp_move += arg
|
||||
@@ -1418,7 +1421,7 @@ class ROP(object):
|
||||
if not set(['rsp', 'esp']) & set(regs):
|
||||
self.pivots[sp_move] = addr
|
||||
|
||||
leave = self.search(regs=frame_regs, order='regs')
|
||||
leave = self.search(regs=frame_regs, order='leav')
|
||||
if leave and leave.regs != frame_regs:
|
||||
leave = None
|
||||
self.leave = leave
|
||||
@@ -1451,7 +1454,7 @@ class ROP(object):
|
||||
pointer is adjusted.
|
||||
regs(list): Minimum list of registers which are popped off the
|
||||
stack.
|
||||
order(str): Either the string 'size' or 'regs'. Decides how to
|
||||
order(str): Either the string 'size', 'leav' or 'regs'. Decides how to
|
||||
order multiple gadgets the fulfill the requirements.
|
||||
|
||||
The search will try to minimize the number of bytes popped more than
|
||||
@@ -1459,7 +1462,9 @@ class ROP(object):
|
||||
the address.
|
||||
|
||||
If ``order == 'size'``, then gadgets are compared lexicographically
|
||||
by ``(total_moves, total_regs, addr)``, otherwise by ``(total_regs, total_moves, addr)``.
|
||||
by ``(total_moves, total_regs, addr)``, if ``order == 'regs'``,
|
||||
then by ``(total_regs, total_moves, addr)``. ``order == 'leav'``
|
||||
is specifically for ``leave`` insn.
|
||||
|
||||
Returns:
|
||||
A :class:`.Gadget` object
|
||||
@@ -1471,8 +1476,9 @@ class ROP(object):
|
||||
# Search for an exact match, save the closest match
|
||||
key = {
|
||||
'size': lambda g: (g.move, len(g.regs), g.address),
|
||||
'regs': lambda g: (len(g.regs), g.move, g.address)
|
||||
}[order]
|
||||
'regs': lambda g: (len(g.regs), g.move, g.address),
|
||||
'leav': lambda g: ('leave' not in g.insns, len(g.regs), g.address)
|
||||
}[order] # False is prior than True
|
||||
|
||||
try:
|
||||
result = min(matches, key=key)
|
||||
|
||||
+5
-5
@@ -185,7 +185,7 @@ registers = {
|
||||
80: 'r13', 88: 'r14', 96: 'r15', 104: 'rdi', 112: 'rsi', 120: 'rbp', 128: 'rbx',
|
||||
136: 'rdx', 144: 'rax', 152: 'rcx', 160: 'rsp', 168: 'rip', 176: 'eflags',
|
||||
184: 'csgsfs', 192: 'err', 200: 'trapno', 208: 'oldmask', 216: 'cr2',
|
||||
224: '&fpstate', 232: '__reserved', 240: 'sigmask'},
|
||||
224: '&fpstate', 232: '__reserved', 296: 'sigmask'},
|
||||
# Reference : http://lxr.free-electrons.com/source/arch/arm/include/uapi/asm/sigcontext.h#L15
|
||||
'arm' : {0: 'uc_flags', 4: 'uc_link', 8: 'uc_stack.ss_sp', 12: 'uc_stack.ss_flags',
|
||||
16: 'uc_stack.ss_size', 20: 'trap_no', 24: 'error_code', 28: 'oldmask', 32: 'r0',
|
||||
@@ -270,15 +270,15 @@ class SigreturnFrame(dict):
|
||||
>>> context.clear(arch='amd64')
|
||||
>>> s = SigreturnFrame()
|
||||
>>> unpack_many(bytes(s))
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0]
|
||||
>>> assert len(s) == 248
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
>>> assert len(s) == 304
|
||||
>>> s.rax = 0xa
|
||||
>>> s.rdi = 0x00601000
|
||||
>>> s.rsi = 0x1000
|
||||
>>> s.rdx = 0x7
|
||||
>>> assert len(bytes(s)) == 248
|
||||
>>> assert len(bytes(s)) == 304
|
||||
>>> unpack_many(bytes(s))
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6295552, 4096, 0, 0, 7, 10, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0]
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6295552, 4096, 0, 0, 7, 10, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
Crafting a SigreturnFrame that calls mprotect on i386
|
||||
|
||||
|
||||
@@ -170,21 +170,47 @@ tether = sys.modules[__name__]
|
||||
# Create the module structure
|
||||
shellcraft = module(__name__, '')
|
||||
|
||||
class LazyImporter:
|
||||
def find_module(self, fullname, path=None):
|
||||
if not fullname.startswith('pwnlib.shellcraft.'):
|
||||
return None
|
||||
|
||||
parts = fullname.split('.')[2:]
|
||||
cur = shellcraft
|
||||
for part in parts:
|
||||
cur = getattr(cur, part, None)
|
||||
if not isinstance(cur, ModuleType):
|
||||
if sys.version_info >= (3, 4):
|
||||
import importlib.abc
|
||||
import importlib.util
|
||||
class LazyImporter(importlib.abc.MetaPathFinder, importlib.abc.Loader):
|
||||
def find_spec(self, fullname, path=None, target=None):
|
||||
if not fullname.startswith('pwnlib.shellcraft.'):
|
||||
return None
|
||||
|
||||
return self
|
||||
parts = fullname.split('.')[2:]
|
||||
cur = shellcraft
|
||||
for part in parts:
|
||||
cur = getattr(cur, part, None)
|
||||
if not isinstance(cur, ModuleType):
|
||||
return None
|
||||
|
||||
def load_module(self, fullname):
|
||||
return sys.modules[fullname]
|
||||
return importlib.util.spec_from_loader(fullname, self)
|
||||
|
||||
def create_module(self, spec):
|
||||
# The submodule was already built and registered in sys.modules by
|
||||
# the getattr walk in find_spec, so hand that object back instead
|
||||
# of letting the import system make a fresh empty module.
|
||||
return sys.modules.get(spec.name)
|
||||
|
||||
def exec_module(self, module):
|
||||
pass
|
||||
else:
|
||||
class LazyImporter:
|
||||
def find_module(self, fullname, path=None):
|
||||
if not fullname.startswith('pwnlib.shellcraft.'):
|
||||
return None
|
||||
|
||||
parts = fullname.split('.')[2:]
|
||||
cur = shellcraft
|
||||
for part in parts:
|
||||
cur = getattr(cur, part, None)
|
||||
if not isinstance(cur, ModuleType):
|
||||
return None
|
||||
|
||||
return self
|
||||
|
||||
def load_module(self, fullname):
|
||||
return sys.modules[fullname]
|
||||
|
||||
sys.meta_path.append(LazyImporter())
|
||||
@@ -73,7 +73,42 @@ sparc += list(map('i{}'.format, range(5)))
|
||||
sparc += ["pc", "sp", "fp", "psr" ]
|
||||
sparc = list(map('%{}'.format, sparc))
|
||||
|
||||
riscv = {
|
||||
'x0' : 0, 'zero': 0,
|
||||
'x1' : 1, 'ra': 1,
|
||||
'x2' : 2, 'sp': 2,
|
||||
'x3' : 3, 'gp': 3,
|
||||
'x4' : 4, 'tp': 4,
|
||||
'x5' : 5, 't0': 5,
|
||||
'x6' : 6, 't1': 6,
|
||||
'x7' : 7, 't2': 7,
|
||||
'x8' : 8, 's0': 8, 'fp': 8,
|
||||
'x9' : 9, 's1': 9,
|
||||
'x10': 10, 'a0': 10,
|
||||
'x11': 11, 'a1': 11,
|
||||
'x12': 12, 'a2': 12,
|
||||
'x13': 13, 'a3': 13,
|
||||
'x14': 14, 'a4': 14,
|
||||
'x15': 15, 'a5': 15,
|
||||
'x16': 16, 'a6': 16,
|
||||
'x17': 17, 'a7': 17,
|
||||
'x18': 18, 's2': 18,
|
||||
'x19': 19, 's3': 19,
|
||||
'x20': 20, 's4': 20,
|
||||
'x21': 21, 's5': 21,
|
||||
'x22': 22, 's6': 22,
|
||||
'x23': 23, 's7': 23,
|
||||
'x24': 24, 's8': 24,
|
||||
'x25': 25, 's9': 25,
|
||||
'x26': 26, 's10': 26,
|
||||
'x27': 27, 's11': 27,
|
||||
'x28': 28, 't3': 28,
|
||||
'x29': 29, 't4': 29,
|
||||
'x30': 30, 't5': 30,
|
||||
'x31': 31, 't6': 31,
|
||||
}
|
||||
|
||||
riscv_list = list(riscv)
|
||||
|
||||
# x86/amd64 registers in decreasing size
|
||||
i386_ordered = [
|
||||
@@ -81,10 +116,10 @@ i386_ordered = [
|
||||
['rbx', 'ebx', 'bx', 'bl'],
|
||||
['rcx', 'ecx', 'cx', 'cl'],
|
||||
['rdx', 'edx', 'dx', 'dl'],
|
||||
['rdi', 'edi', 'di'],
|
||||
['rsi', 'esi', 'si'],
|
||||
['rbp', 'ebp', 'bp'],
|
||||
['rsp', 'esp', 'sp'],
|
||||
['rdi', 'edi', 'di', 'dil'],
|
||||
['rsi', 'esi', 'si', 'sil'],
|
||||
['rbp', 'ebp', 'bp', 'bpl'],
|
||||
['rsp', 'esp', 'sp', 'spl'],
|
||||
['r8', 'r8d', 'r8w', 'r8b'],
|
||||
['r9', 'r9d', 'r9w', 'r9b'],
|
||||
['r10', 'r10d', 'r10w', 'r10b'],
|
||||
@@ -215,7 +250,9 @@ def current():
|
||||
'thumb': arm,
|
||||
'aarch64': aarch64,
|
||||
'mips': mips_list,
|
||||
'powerpc': powerpc
|
||||
'powerpc': powerpc,
|
||||
'riscv32': riscv,
|
||||
'riscv64': riscv,
|
||||
}[context.arch]
|
||||
|
||||
# def is_register(sz):
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
Creates a new socket
|
||||
</%docstring>
|
||||
<%
|
||||
sockaddr, length, address_family = sockaddr('127.0.0.1', 1, network)
|
||||
if network == 'ipv4':
|
||||
sockaddr, length, address_family = sockaddr('127.0.0.1', 1, network)
|
||||
elif network == 'ipv6':
|
||||
sockaddr, length, address_family = sockaddr('::1', 1, network)
|
||||
socktype = {
|
||||
'tcp': SOCK_STREAM,
|
||||
'udp': SOCK_DGRAM
|
||||
|
||||
@@ -16,4 +16,4 @@ ${memcpy_loop}:
|
||||
ldrb w3, [x1], #1
|
||||
strb w3, [x0], #1
|
||||
subs x2, x2, #1
|
||||
bge ${memcpy_loop}
|
||||
bgt ${memcpy_loop}
|
||||
@@ -6,7 +6,10 @@
|
||||
Creates a new socket
|
||||
</%docstring>
|
||||
<%
|
||||
sockaddr, length, address_family = sockaddr('127.0.0.1', 1, network)
|
||||
if network == 'ipv4':
|
||||
sockaddr, length, address_family = sockaddr('127.0.0.1', 1, network)
|
||||
elif network == 'ipv6':
|
||||
sockaddr, length, address_family = sockaddr('::1', 1, network)
|
||||
socktype = {
|
||||
'tcp': SOCK_STREAM,
|
||||
'udp': SOCK_DGRAM
|
||||
|
||||
@@ -51,8 +51,8 @@ Example:
|
||||
xor eax, eax
|
||||
mov ax, 0xc0c0
|
||||
>>> print(shellcraft.amd64.mov('rdi', 0xff).rstrip())
|
||||
mov edi, 0x1010101 /* 255 == 0xff */
|
||||
xor edi, 0x10101fe
|
||||
xor edi, edi
|
||||
mov dil, 0xff
|
||||
>>> print(shellcraft.amd64.mov('rax', 0xdead00ff).rstrip())
|
||||
mov eax, 0x1010101 /* 3735879935 == 0xdead00ff */
|
||||
xor eax, 0xdfac01fe
|
||||
|
||||
@@ -55,7 +55,7 @@ if isinstance(eax, six.integer_types) and isinstance(edx, six.integer_types) and
|
||||
cdq = True
|
||||
reg_context.pop('rdx')
|
||||
|
||||
sorted_regs = regsort(reg_context, registers.amd64)
|
||||
sorted_regs = regsort(reg_context, registers.amd64, registers.native64)
|
||||
%>
|
||||
% if not sorted_regs:
|
||||
/* setregs noop */
|
||||
|
||||
@@ -1,24 +1,30 @@
|
||||
<%
|
||||
from pwnlib.shellcraft import amd64, pretty
|
||||
from pwnlib.shellcraft import amd64, common, pretty
|
||||
from pwnlib.util.packing import u64, _need_bytes
|
||||
%>
|
||||
<%docstring>Find the address of an exported function in a dll
|
||||
by manually iterating through the PE export table.
|
||||
|
||||
The dll must be `b'kernel32.dll'` or `b'ntdll.dll'` at the moment.
|
||||
Behavior is undefined if the function is not found.
|
||||
|
||||
Args:
|
||||
function_name (str): The name of the function to find.
|
||||
dll(str): The name of the DLL to find the function in.
|
||||
function_name (bytes): The name of the function to find.
|
||||
dll(bytes): The name of the DLL to find the function in.
|
||||
dest (str): The register to load the function address into.
|
||||
</%docstring>
|
||||
<%page args="function_name,dll='kernel32.dll',dest='rax'"/>
|
||||
<%page args="function_name,dll=b'kernel32.dll',dest='rax'"/>
|
||||
<%
|
||||
function_name = _need_bytes(function_name)
|
||||
dll = _need_bytes(dll)
|
||||
if len(function_name) > 8:
|
||||
raise ValueError('function_name must be <= 8 bytes')
|
||||
assert dll == b'kernel32.dll'
|
||||
assert dll in (b'kernel32.dll', b'ntdll.dll')
|
||||
find_function_loop = common.label('find_function').strip()
|
||||
%>
|
||||
% if dll == b'kernel32.dll':
|
||||
${amd64.windows.kernel32base('rbx')} /* rbx = kernel32.dll PE base */
|
||||
% elif dll == b'ntdll.dll':
|
||||
${amd64.windows.ntdllbase('rbx')} /* rbx = ntdll.dll PE base */
|
||||
% endif
|
||||
mov r8d, [rbx + 0x3c]
|
||||
mov rdx, r8
|
||||
add rdx, rbx
|
||||
@@ -26,25 +32,42 @@ assert dll == b'kernel32.dll'
|
||||
add rdx, r9
|
||||
mov r8d, [rdx]
|
||||
add r8, rbx /* r8 = export table */
|
||||
mov esi, [r8 + 0x20]
|
||||
add rsi, rbx /* rsi = names table */
|
||||
xor rcx, rcx
|
||||
mov edx, [r8 + 0x20]
|
||||
add rdx, rbx /* rdx = names table */
|
||||
% if len(function_name) <= 8:
|
||||
mov r9, ${pretty(u64(function_name.ljust(8, b'\x00')))}
|
||||
% else:
|
||||
${amd64.pushstr(function_name)}
|
||||
mov r9, rsp
|
||||
% endif
|
||||
push r8
|
||||
xor r8, r8
|
||||
|
||||
/* Loop through the names table */
|
||||
FindFunction:
|
||||
inc rcx
|
||||
mov eax, [rsi + rcx * 4]
|
||||
${find_function_loop}:
|
||||
inc r8
|
||||
mov eax, [rdx + r8 * 4]
|
||||
add rax, rbx
|
||||
## TODO: implement strcmp properly for function names > 8 bytes
|
||||
## strcmp
|
||||
% if len(function_name) <= 8:
|
||||
cmp qword ptr [rax], r9
|
||||
jnz FindFunction
|
||||
% else:
|
||||
${amd64.setregs({
|
||||
'rdi': 'rax',
|
||||
'rsi': 'r9',
|
||||
'rcx': len(function_name),
|
||||
})}
|
||||
repe cmpsb
|
||||
movzx rax, byte ptr [rsi-1]
|
||||
movzx rcx, byte ptr [rdi-1]
|
||||
sub rax, rcx
|
||||
% endif
|
||||
jnz ${find_function_loop}
|
||||
|
||||
## Assume we find the function, we'll crash walking past the
|
||||
## end of the names table otherwise.
|
||||
mov rcx, r8
|
||||
pop r8
|
||||
mov esi, [r8 + 0x24]
|
||||
add rsi, rbx /* rsi = ordinals table */
|
||||
mov cx, [rsi + rcx * 2]
|
||||
@@ -52,4 +75,4 @@ assert dll == b'kernel32.dll'
|
||||
add rsi, rbx /* rsi = address table */
|
||||
mov eax, [rsi + rcx * 4]
|
||||
add rax, rbx /* rax = function address */
|
||||
mov ${dest}, rax
|
||||
${amd64.mov(dest, 'rax')}
|
||||
@@ -11,7 +11,7 @@ Args:
|
||||
dll(str): The name of the DLL to find the function in.
|
||||
dest (str): The register to load the function address into.
|
||||
</%docstring>
|
||||
<%page args="function_name,dll='kernel32.dll',dest='rax'"/>
|
||||
<%page args="function_name,dll=b'kernel32.dll',dest='rax'"/>
|
||||
<%
|
||||
function_name = _need_bytes(function_name)
|
||||
dll = _need_bytes(dll)
|
||||
@@ -25,4 +25,4 @@ assert dll == b'kernel32.dll'
|
||||
sub rsp, 0x30
|
||||
call rdi
|
||||
add rsp, ${pretty(0x30+align(8, len(function_name)))}
|
||||
mov ${dest}, rax
|
||||
${amd64.mov(dest, 'rax')}
|
||||
@@ -16,4 +16,4 @@ ${memcpy_loop}:
|
||||
ldrb r3, [r1], #1
|
||||
strb r3, [r0], #1
|
||||
subs r2, r2, #1
|
||||
bge ${memcpy_loop}
|
||||
bgt ${memcpy_loop}
|
||||
@@ -0,0 +1,101 @@
|
||||
<%
|
||||
import collections
|
||||
import pwnlib.abi
|
||||
import pwnlib.constants
|
||||
import pwnlib.shellcraft
|
||||
import six
|
||||
%>
|
||||
<%docstring>close_range(vararg_0, vararg_1, vararg_2, vararg_3, vararg_4) -> str
|
||||
|
||||
Invokes the syscall close_range.
|
||||
|
||||
See 'man 2 close_range' for more information.
|
||||
|
||||
Arguments:
|
||||
vararg(int): vararg
|
||||
Returns:
|
||||
long
|
||||
</%docstring>
|
||||
<%page args="vararg_0=None, vararg_1=None, vararg_2=None, vararg_3=None, vararg_4=None"/>
|
||||
<%
|
||||
abi = pwnlib.abi.ABI.syscall()
|
||||
stack = abi.stack
|
||||
regs = abi.register_arguments[1:]
|
||||
allregs = pwnlib.shellcraft.registers.current()
|
||||
|
||||
can_pushstr = []
|
||||
can_pushstr_array = []
|
||||
|
||||
argument_names = ['vararg_0', 'vararg_1', 'vararg_2', 'vararg_3', 'vararg_4']
|
||||
argument_values = [vararg_0, vararg_1, vararg_2, vararg_3, vararg_4]
|
||||
|
||||
# Load all of the arguments into their destination registers / stack slots.
|
||||
register_arguments = dict()
|
||||
stack_arguments = collections.OrderedDict()
|
||||
string_arguments = dict()
|
||||
dict_arguments = dict()
|
||||
array_arguments = dict()
|
||||
syscall_repr = []
|
||||
|
||||
for name, arg in zip(argument_names, argument_values):
|
||||
if arg is not None:
|
||||
syscall_repr.append('%s=%s' % (name, pwnlib.shellcraft.pretty(arg, False)))
|
||||
|
||||
# If the argument itself (input) is a register...
|
||||
if arg in allregs:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[index] = arg
|
||||
|
||||
# The argument is not a register. It is a string value, and we
|
||||
# are expecting a string value
|
||||
elif name in can_pushstr and isinstance(arg, (six.binary_type, six.text_type)):
|
||||
if isinstance(arg, six.text_type):
|
||||
arg = arg.encode('utf-8')
|
||||
string_arguments[name] = arg
|
||||
|
||||
# The argument is not a register. It is a dictionary, and we are
|
||||
# expecting K:V paris.
|
||||
elif name in can_pushstr_array and isinstance(arg, dict):
|
||||
array_arguments[name] = ['%s=%s' % (k,v) for (k,v) in arg.items()]
|
||||
|
||||
# The arguent is not a register. It is a list, and we are expecting
|
||||
# a list of arguments.
|
||||
elif name in can_pushstr_array and isinstance(arg, (list, tuple)):
|
||||
array_arguments[name] = arg
|
||||
|
||||
# The argument is not a register, string, dict, or list.
|
||||
# It could be a constant string ('O_RDONLY') for an integer argument,
|
||||
# an actual integer value, or a constant.
|
||||
else:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[target] = arg
|
||||
|
||||
# Some syscalls have different names on various architectures.
|
||||
# Determine which syscall number to use for the current architecture.
|
||||
for syscall in ['SYS_close_range']:
|
||||
if hasattr(pwnlib.constants, syscall):
|
||||
break
|
||||
else:
|
||||
raise Exception("Could not locate any syscalls: %r" % syscalls)
|
||||
%>
|
||||
/* close_range(${', '.join(syscall_repr)}) */
|
||||
%for name, arg in string_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr(arg, append_null=(b'\x00' not in arg))}
|
||||
${pwnlib.shellcraft.mov(regs[argument_names.index(name)], abi.stack)}
|
||||
%endfor
|
||||
%for name, arg in array_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr_array(regs[argument_names.index(name)], arg)}
|
||||
%endfor
|
||||
%for name, arg in stack_arguments.items():
|
||||
${pwnlib.shellcraft.push(arg)}
|
||||
%endfor
|
||||
${pwnlib.shellcraft.setregs(register_arguments)}
|
||||
${pwnlib.shellcraft.syscall(syscall)}
|
||||
@@ -0,0 +1,101 @@
|
||||
<%
|
||||
import collections
|
||||
import pwnlib.abi
|
||||
import pwnlib.constants
|
||||
import pwnlib.shellcraft
|
||||
import six
|
||||
%>
|
||||
<%docstring>epoll_pwait2(vararg_0, vararg_1, vararg_2, vararg_3, vararg_4) -> str
|
||||
|
||||
Invokes the syscall epoll_pwait2.
|
||||
|
||||
See 'man 2 epoll_pwait2' for more information.
|
||||
|
||||
Arguments:
|
||||
vararg(int): vararg
|
||||
Returns:
|
||||
long
|
||||
</%docstring>
|
||||
<%page args="vararg_0=None, vararg_1=None, vararg_2=None, vararg_3=None, vararg_4=None"/>
|
||||
<%
|
||||
abi = pwnlib.abi.ABI.syscall()
|
||||
stack = abi.stack
|
||||
regs = abi.register_arguments[1:]
|
||||
allregs = pwnlib.shellcraft.registers.current()
|
||||
|
||||
can_pushstr = []
|
||||
can_pushstr_array = []
|
||||
|
||||
argument_names = ['vararg_0', 'vararg_1', 'vararg_2', 'vararg_3', 'vararg_4']
|
||||
argument_values = [vararg_0, vararg_1, vararg_2, vararg_3, vararg_4]
|
||||
|
||||
# Load all of the arguments into their destination registers / stack slots.
|
||||
register_arguments = dict()
|
||||
stack_arguments = collections.OrderedDict()
|
||||
string_arguments = dict()
|
||||
dict_arguments = dict()
|
||||
array_arguments = dict()
|
||||
syscall_repr = []
|
||||
|
||||
for name, arg in zip(argument_names, argument_values):
|
||||
if arg is not None:
|
||||
syscall_repr.append('%s=%s' % (name, pwnlib.shellcraft.pretty(arg, False)))
|
||||
|
||||
# If the argument itself (input) is a register...
|
||||
if arg in allregs:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[index] = arg
|
||||
|
||||
# The argument is not a register. It is a string value, and we
|
||||
# are expecting a string value
|
||||
elif name in can_pushstr and isinstance(arg, (six.binary_type, six.text_type)):
|
||||
if isinstance(arg, six.text_type):
|
||||
arg = arg.encode('utf-8')
|
||||
string_arguments[name] = arg
|
||||
|
||||
# The argument is not a register. It is a dictionary, and we are
|
||||
# expecting K:V paris.
|
||||
elif name in can_pushstr_array and isinstance(arg, dict):
|
||||
array_arguments[name] = ['%s=%s' % (k,v) for (k,v) in arg.items()]
|
||||
|
||||
# The arguent is not a register. It is a list, and we are expecting
|
||||
# a list of arguments.
|
||||
elif name in can_pushstr_array and isinstance(arg, (list, tuple)):
|
||||
array_arguments[name] = arg
|
||||
|
||||
# The argument is not a register, string, dict, or list.
|
||||
# It could be a constant string ('O_RDONLY') for an integer argument,
|
||||
# an actual integer value, or a constant.
|
||||
else:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[target] = arg
|
||||
|
||||
# Some syscalls have different names on various architectures.
|
||||
# Determine which syscall number to use for the current architecture.
|
||||
for syscall in ['SYS_epoll_pwait2']:
|
||||
if hasattr(pwnlib.constants, syscall):
|
||||
break
|
||||
else:
|
||||
raise Exception("Could not locate any syscalls: %r" % syscalls)
|
||||
%>
|
||||
/* epoll_pwait2(${', '.join(syscall_repr)}) */
|
||||
%for name, arg in string_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr(arg, append_null=(b'\x00' not in arg))}
|
||||
${pwnlib.shellcraft.mov(regs[argument_names.index(name)], abi.stack)}
|
||||
%endfor
|
||||
%for name, arg in array_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr_array(regs[argument_names.index(name)], arg)}
|
||||
%endfor
|
||||
%for name, arg in stack_arguments.items():
|
||||
${pwnlib.shellcraft.push(arg)}
|
||||
%endfor
|
||||
${pwnlib.shellcraft.setregs(register_arguments)}
|
||||
${pwnlib.shellcraft.syscall(syscall)}
|
||||
@@ -0,0 +1,101 @@
|
||||
<%
|
||||
import collections
|
||||
import pwnlib.abi
|
||||
import pwnlib.constants
|
||||
import pwnlib.shellcraft
|
||||
import six
|
||||
%>
|
||||
<%docstring>faccessat2(vararg_0, vararg_1, vararg_2, vararg_3, vararg_4) -> str
|
||||
|
||||
Invokes the syscall faccessat2.
|
||||
|
||||
See 'man 2 faccessat2' for more information.
|
||||
|
||||
Arguments:
|
||||
vararg(int): vararg
|
||||
Returns:
|
||||
long
|
||||
</%docstring>
|
||||
<%page args="vararg_0=None, vararg_1=None, vararg_2=None, vararg_3=None, vararg_4=None"/>
|
||||
<%
|
||||
abi = pwnlib.abi.ABI.syscall()
|
||||
stack = abi.stack
|
||||
regs = abi.register_arguments[1:]
|
||||
allregs = pwnlib.shellcraft.registers.current()
|
||||
|
||||
can_pushstr = []
|
||||
can_pushstr_array = []
|
||||
|
||||
argument_names = ['vararg_0', 'vararg_1', 'vararg_2', 'vararg_3', 'vararg_4']
|
||||
argument_values = [vararg_0, vararg_1, vararg_2, vararg_3, vararg_4]
|
||||
|
||||
# Load all of the arguments into their destination registers / stack slots.
|
||||
register_arguments = dict()
|
||||
stack_arguments = collections.OrderedDict()
|
||||
string_arguments = dict()
|
||||
dict_arguments = dict()
|
||||
array_arguments = dict()
|
||||
syscall_repr = []
|
||||
|
||||
for name, arg in zip(argument_names, argument_values):
|
||||
if arg is not None:
|
||||
syscall_repr.append('%s=%s' % (name, pwnlib.shellcraft.pretty(arg, False)))
|
||||
|
||||
# If the argument itself (input) is a register...
|
||||
if arg in allregs:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[index] = arg
|
||||
|
||||
# The argument is not a register. It is a string value, and we
|
||||
# are expecting a string value
|
||||
elif name in can_pushstr and isinstance(arg, (six.binary_type, six.text_type)):
|
||||
if isinstance(arg, six.text_type):
|
||||
arg = arg.encode('utf-8')
|
||||
string_arguments[name] = arg
|
||||
|
||||
# The argument is not a register. It is a dictionary, and we are
|
||||
# expecting K:V paris.
|
||||
elif name in can_pushstr_array and isinstance(arg, dict):
|
||||
array_arguments[name] = ['%s=%s' % (k,v) for (k,v) in arg.items()]
|
||||
|
||||
# The arguent is not a register. It is a list, and we are expecting
|
||||
# a list of arguments.
|
||||
elif name in can_pushstr_array and isinstance(arg, (list, tuple)):
|
||||
array_arguments[name] = arg
|
||||
|
||||
# The argument is not a register, string, dict, or list.
|
||||
# It could be a constant string ('O_RDONLY') for an integer argument,
|
||||
# an actual integer value, or a constant.
|
||||
else:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[target] = arg
|
||||
|
||||
# Some syscalls have different names on various architectures.
|
||||
# Determine which syscall number to use for the current architecture.
|
||||
for syscall in ['SYS_faccessat2']:
|
||||
if hasattr(pwnlib.constants, syscall):
|
||||
break
|
||||
else:
|
||||
raise Exception("Could not locate any syscalls: %r" % syscalls)
|
||||
%>
|
||||
/* faccessat2(${', '.join(syscall_repr)}) */
|
||||
%for name, arg in string_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr(arg, append_null=(b'\x00' not in arg))}
|
||||
${pwnlib.shellcraft.mov(regs[argument_names.index(name)], abi.stack)}
|
||||
%endfor
|
||||
%for name, arg in array_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr_array(regs[argument_names.index(name)], arg)}
|
||||
%endfor
|
||||
%for name, arg in stack_arguments.items():
|
||||
${pwnlib.shellcraft.push(arg)}
|
||||
%endfor
|
||||
${pwnlib.shellcraft.setregs(register_arguments)}
|
||||
${pwnlib.shellcraft.syscall(syscall)}
|
||||
@@ -0,0 +1,101 @@
|
||||
<%
|
||||
import collections
|
||||
import pwnlib.abi
|
||||
import pwnlib.constants
|
||||
import pwnlib.shellcraft
|
||||
import six
|
||||
%>
|
||||
<%docstring>landlock_add_rule(vararg_0, vararg_1, vararg_2, vararg_3, vararg_4) -> str
|
||||
|
||||
Invokes the syscall landlock_add_rule.
|
||||
|
||||
See 'man 2 landlock_add_rule' for more information.
|
||||
|
||||
Arguments:
|
||||
vararg(int): vararg
|
||||
Returns:
|
||||
long
|
||||
</%docstring>
|
||||
<%page args="vararg_0=None, vararg_1=None, vararg_2=None, vararg_3=None, vararg_4=None"/>
|
||||
<%
|
||||
abi = pwnlib.abi.ABI.syscall()
|
||||
stack = abi.stack
|
||||
regs = abi.register_arguments[1:]
|
||||
allregs = pwnlib.shellcraft.registers.current()
|
||||
|
||||
can_pushstr = []
|
||||
can_pushstr_array = []
|
||||
|
||||
argument_names = ['vararg_0', 'vararg_1', 'vararg_2', 'vararg_3', 'vararg_4']
|
||||
argument_values = [vararg_0, vararg_1, vararg_2, vararg_3, vararg_4]
|
||||
|
||||
# Load all of the arguments into their destination registers / stack slots.
|
||||
register_arguments = dict()
|
||||
stack_arguments = collections.OrderedDict()
|
||||
string_arguments = dict()
|
||||
dict_arguments = dict()
|
||||
array_arguments = dict()
|
||||
syscall_repr = []
|
||||
|
||||
for name, arg in zip(argument_names, argument_values):
|
||||
if arg is not None:
|
||||
syscall_repr.append('%s=%s' % (name, pwnlib.shellcraft.pretty(arg, False)))
|
||||
|
||||
# If the argument itself (input) is a register...
|
||||
if arg in allregs:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[index] = arg
|
||||
|
||||
# The argument is not a register. It is a string value, and we
|
||||
# are expecting a string value
|
||||
elif name in can_pushstr and isinstance(arg, (six.binary_type, six.text_type)):
|
||||
if isinstance(arg, six.text_type):
|
||||
arg = arg.encode('utf-8')
|
||||
string_arguments[name] = arg
|
||||
|
||||
# The argument is not a register. It is a dictionary, and we are
|
||||
# expecting K:V paris.
|
||||
elif name in can_pushstr_array and isinstance(arg, dict):
|
||||
array_arguments[name] = ['%s=%s' % (k,v) for (k,v) in arg.items()]
|
||||
|
||||
# The arguent is not a register. It is a list, and we are expecting
|
||||
# a list of arguments.
|
||||
elif name in can_pushstr_array and isinstance(arg, (list, tuple)):
|
||||
array_arguments[name] = arg
|
||||
|
||||
# The argument is not a register, string, dict, or list.
|
||||
# It could be a constant string ('O_RDONLY') for an integer argument,
|
||||
# an actual integer value, or a constant.
|
||||
else:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[target] = arg
|
||||
|
||||
# Some syscalls have different names on various architectures.
|
||||
# Determine which syscall number to use for the current architecture.
|
||||
for syscall in ['SYS_landlock_add_rule']:
|
||||
if hasattr(pwnlib.constants, syscall):
|
||||
break
|
||||
else:
|
||||
raise Exception("Could not locate any syscalls: %r" % syscalls)
|
||||
%>
|
||||
/* landlock_add_rule(${', '.join(syscall_repr)}) */
|
||||
%for name, arg in string_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr(arg, append_null=(b'\x00' not in arg))}
|
||||
${pwnlib.shellcraft.mov(regs[argument_names.index(name)], abi.stack)}
|
||||
%endfor
|
||||
%for name, arg in array_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr_array(regs[argument_names.index(name)], arg)}
|
||||
%endfor
|
||||
%for name, arg in stack_arguments.items():
|
||||
${pwnlib.shellcraft.push(arg)}
|
||||
%endfor
|
||||
${pwnlib.shellcraft.setregs(register_arguments)}
|
||||
${pwnlib.shellcraft.syscall(syscall)}
|
||||
@@ -0,0 +1,101 @@
|
||||
<%
|
||||
import collections
|
||||
import pwnlib.abi
|
||||
import pwnlib.constants
|
||||
import pwnlib.shellcraft
|
||||
import six
|
||||
%>
|
||||
<%docstring>landlock_create_ruleset(vararg_0, vararg_1, vararg_2, vararg_3, vararg_4) -> str
|
||||
|
||||
Invokes the syscall landlock_create_ruleset.
|
||||
|
||||
See 'man 2 landlock_create_ruleset' for more information.
|
||||
|
||||
Arguments:
|
||||
vararg(int): vararg
|
||||
Returns:
|
||||
long
|
||||
</%docstring>
|
||||
<%page args="vararg_0=None, vararg_1=None, vararg_2=None, vararg_3=None, vararg_4=None"/>
|
||||
<%
|
||||
abi = pwnlib.abi.ABI.syscall()
|
||||
stack = abi.stack
|
||||
regs = abi.register_arguments[1:]
|
||||
allregs = pwnlib.shellcraft.registers.current()
|
||||
|
||||
can_pushstr = []
|
||||
can_pushstr_array = []
|
||||
|
||||
argument_names = ['vararg_0', 'vararg_1', 'vararg_2', 'vararg_3', 'vararg_4']
|
||||
argument_values = [vararg_0, vararg_1, vararg_2, vararg_3, vararg_4]
|
||||
|
||||
# Load all of the arguments into their destination registers / stack slots.
|
||||
register_arguments = dict()
|
||||
stack_arguments = collections.OrderedDict()
|
||||
string_arguments = dict()
|
||||
dict_arguments = dict()
|
||||
array_arguments = dict()
|
||||
syscall_repr = []
|
||||
|
||||
for name, arg in zip(argument_names, argument_values):
|
||||
if arg is not None:
|
||||
syscall_repr.append('%s=%s' % (name, pwnlib.shellcraft.pretty(arg, False)))
|
||||
|
||||
# If the argument itself (input) is a register...
|
||||
if arg in allregs:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[index] = arg
|
||||
|
||||
# The argument is not a register. It is a string value, and we
|
||||
# are expecting a string value
|
||||
elif name in can_pushstr and isinstance(arg, (six.binary_type, six.text_type)):
|
||||
if isinstance(arg, six.text_type):
|
||||
arg = arg.encode('utf-8')
|
||||
string_arguments[name] = arg
|
||||
|
||||
# The argument is not a register. It is a dictionary, and we are
|
||||
# expecting K:V paris.
|
||||
elif name in can_pushstr_array and isinstance(arg, dict):
|
||||
array_arguments[name] = ['%s=%s' % (k,v) for (k,v) in arg.items()]
|
||||
|
||||
# The arguent is not a register. It is a list, and we are expecting
|
||||
# a list of arguments.
|
||||
elif name in can_pushstr_array and isinstance(arg, (list, tuple)):
|
||||
array_arguments[name] = arg
|
||||
|
||||
# The argument is not a register, string, dict, or list.
|
||||
# It could be a constant string ('O_RDONLY') for an integer argument,
|
||||
# an actual integer value, or a constant.
|
||||
else:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[target] = arg
|
||||
|
||||
# Some syscalls have different names on various architectures.
|
||||
# Determine which syscall number to use for the current architecture.
|
||||
for syscall in ['SYS_landlock_create_ruleset']:
|
||||
if hasattr(pwnlib.constants, syscall):
|
||||
break
|
||||
else:
|
||||
raise Exception("Could not locate any syscalls: %r" % syscalls)
|
||||
%>
|
||||
/* landlock_create_ruleset(${', '.join(syscall_repr)}) */
|
||||
%for name, arg in string_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr(arg, append_null=(b'\x00' not in arg))}
|
||||
${pwnlib.shellcraft.mov(regs[argument_names.index(name)], abi.stack)}
|
||||
%endfor
|
||||
%for name, arg in array_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr_array(regs[argument_names.index(name)], arg)}
|
||||
%endfor
|
||||
%for name, arg in stack_arguments.items():
|
||||
${pwnlib.shellcraft.push(arg)}
|
||||
%endfor
|
||||
${pwnlib.shellcraft.setregs(register_arguments)}
|
||||
${pwnlib.shellcraft.syscall(syscall)}
|
||||
@@ -0,0 +1,101 @@
|
||||
<%
|
||||
import collections
|
||||
import pwnlib.abi
|
||||
import pwnlib.constants
|
||||
import pwnlib.shellcraft
|
||||
import six
|
||||
%>
|
||||
<%docstring>landlock_restrict_self(vararg_0, vararg_1, vararg_2, vararg_3, vararg_4) -> str
|
||||
|
||||
Invokes the syscall landlock_restrict_self.
|
||||
|
||||
See 'man 2 landlock_restrict_self' for more information.
|
||||
|
||||
Arguments:
|
||||
vararg(int): vararg
|
||||
Returns:
|
||||
long
|
||||
</%docstring>
|
||||
<%page args="vararg_0=None, vararg_1=None, vararg_2=None, vararg_3=None, vararg_4=None"/>
|
||||
<%
|
||||
abi = pwnlib.abi.ABI.syscall()
|
||||
stack = abi.stack
|
||||
regs = abi.register_arguments[1:]
|
||||
allregs = pwnlib.shellcraft.registers.current()
|
||||
|
||||
can_pushstr = []
|
||||
can_pushstr_array = []
|
||||
|
||||
argument_names = ['vararg_0', 'vararg_1', 'vararg_2', 'vararg_3', 'vararg_4']
|
||||
argument_values = [vararg_0, vararg_1, vararg_2, vararg_3, vararg_4]
|
||||
|
||||
# Load all of the arguments into their destination registers / stack slots.
|
||||
register_arguments = dict()
|
||||
stack_arguments = collections.OrderedDict()
|
||||
string_arguments = dict()
|
||||
dict_arguments = dict()
|
||||
array_arguments = dict()
|
||||
syscall_repr = []
|
||||
|
||||
for name, arg in zip(argument_names, argument_values):
|
||||
if arg is not None:
|
||||
syscall_repr.append('%s=%s' % (name, pwnlib.shellcraft.pretty(arg, False)))
|
||||
|
||||
# If the argument itself (input) is a register...
|
||||
if arg in allregs:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[index] = arg
|
||||
|
||||
# The argument is not a register. It is a string value, and we
|
||||
# are expecting a string value
|
||||
elif name in can_pushstr and isinstance(arg, (six.binary_type, six.text_type)):
|
||||
if isinstance(arg, six.text_type):
|
||||
arg = arg.encode('utf-8')
|
||||
string_arguments[name] = arg
|
||||
|
||||
# The argument is not a register. It is a dictionary, and we are
|
||||
# expecting K:V paris.
|
||||
elif name in can_pushstr_array and isinstance(arg, dict):
|
||||
array_arguments[name] = ['%s=%s' % (k,v) for (k,v) in arg.items()]
|
||||
|
||||
# The arguent is not a register. It is a list, and we are expecting
|
||||
# a list of arguments.
|
||||
elif name in can_pushstr_array and isinstance(arg, (list, tuple)):
|
||||
array_arguments[name] = arg
|
||||
|
||||
# The argument is not a register, string, dict, or list.
|
||||
# It could be a constant string ('O_RDONLY') for an integer argument,
|
||||
# an actual integer value, or a constant.
|
||||
else:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[target] = arg
|
||||
|
||||
# Some syscalls have different names on various architectures.
|
||||
# Determine which syscall number to use for the current architecture.
|
||||
for syscall in ['SYS_landlock_restrict_self']:
|
||||
if hasattr(pwnlib.constants, syscall):
|
||||
break
|
||||
else:
|
||||
raise Exception("Could not locate any syscalls: %r" % syscalls)
|
||||
%>
|
||||
/* landlock_restrict_self(${', '.join(syscall_repr)}) */
|
||||
%for name, arg in string_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr(arg, append_null=(b'\x00' not in arg))}
|
||||
${pwnlib.shellcraft.mov(regs[argument_names.index(name)], abi.stack)}
|
||||
%endfor
|
||||
%for name, arg in array_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr_array(regs[argument_names.index(name)], arg)}
|
||||
%endfor
|
||||
%for name, arg in stack_arguments.items():
|
||||
${pwnlib.shellcraft.push(arg)}
|
||||
%endfor
|
||||
${pwnlib.shellcraft.setregs(register_arguments)}
|
||||
${pwnlib.shellcraft.syscall(syscall)}
|
||||
@@ -0,0 +1,101 @@
|
||||
<%
|
||||
import collections
|
||||
import pwnlib.abi
|
||||
import pwnlib.constants
|
||||
import pwnlib.shellcraft
|
||||
import six
|
||||
%>
|
||||
<%docstring>mount_setattr(vararg_0, vararg_1, vararg_2, vararg_3, vararg_4) -> str
|
||||
|
||||
Invokes the syscall mount_setattr.
|
||||
|
||||
See 'man 2 mount_setattr' for more information.
|
||||
|
||||
Arguments:
|
||||
vararg(int): vararg
|
||||
Returns:
|
||||
long
|
||||
</%docstring>
|
||||
<%page args="vararg_0=None, vararg_1=None, vararg_2=None, vararg_3=None, vararg_4=None"/>
|
||||
<%
|
||||
abi = pwnlib.abi.ABI.syscall()
|
||||
stack = abi.stack
|
||||
regs = abi.register_arguments[1:]
|
||||
allregs = pwnlib.shellcraft.registers.current()
|
||||
|
||||
can_pushstr = []
|
||||
can_pushstr_array = []
|
||||
|
||||
argument_names = ['vararg_0', 'vararg_1', 'vararg_2', 'vararg_3', 'vararg_4']
|
||||
argument_values = [vararg_0, vararg_1, vararg_2, vararg_3, vararg_4]
|
||||
|
||||
# Load all of the arguments into their destination registers / stack slots.
|
||||
register_arguments = dict()
|
||||
stack_arguments = collections.OrderedDict()
|
||||
string_arguments = dict()
|
||||
dict_arguments = dict()
|
||||
array_arguments = dict()
|
||||
syscall_repr = []
|
||||
|
||||
for name, arg in zip(argument_names, argument_values):
|
||||
if arg is not None:
|
||||
syscall_repr.append('%s=%s' % (name, pwnlib.shellcraft.pretty(arg, False)))
|
||||
|
||||
# If the argument itself (input) is a register...
|
||||
if arg in allregs:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[index] = arg
|
||||
|
||||
# The argument is not a register. It is a string value, and we
|
||||
# are expecting a string value
|
||||
elif name in can_pushstr and isinstance(arg, (six.binary_type, six.text_type)):
|
||||
if isinstance(arg, six.text_type):
|
||||
arg = arg.encode('utf-8')
|
||||
string_arguments[name] = arg
|
||||
|
||||
# The argument is not a register. It is a dictionary, and we are
|
||||
# expecting K:V paris.
|
||||
elif name in can_pushstr_array and isinstance(arg, dict):
|
||||
array_arguments[name] = ['%s=%s' % (k,v) for (k,v) in arg.items()]
|
||||
|
||||
# The arguent is not a register. It is a list, and we are expecting
|
||||
# a list of arguments.
|
||||
elif name in can_pushstr_array and isinstance(arg, (list, tuple)):
|
||||
array_arguments[name] = arg
|
||||
|
||||
# The argument is not a register, string, dict, or list.
|
||||
# It could be a constant string ('O_RDONLY') for an integer argument,
|
||||
# an actual integer value, or a constant.
|
||||
else:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[target] = arg
|
||||
|
||||
# Some syscalls have different names on various architectures.
|
||||
# Determine which syscall number to use for the current architecture.
|
||||
for syscall in ['SYS_mount_setattr']:
|
||||
if hasattr(pwnlib.constants, syscall):
|
||||
break
|
||||
else:
|
||||
raise Exception("Could not locate any syscalls: %r" % syscalls)
|
||||
%>
|
||||
/* mount_setattr(${', '.join(syscall_repr)}) */
|
||||
%for name, arg in string_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr(arg, append_null=(b'\x00' not in arg))}
|
||||
${pwnlib.shellcraft.mov(regs[argument_names.index(name)], abi.stack)}
|
||||
%endfor
|
||||
%for name, arg in array_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr_array(regs[argument_names.index(name)], arg)}
|
||||
%endfor
|
||||
%for name, arg in stack_arguments.items():
|
||||
${pwnlib.shellcraft.push(arg)}
|
||||
%endfor
|
||||
${pwnlib.shellcraft.setregs(register_arguments)}
|
||||
${pwnlib.shellcraft.syscall(syscall)}
|
||||
@@ -0,0 +1,101 @@
|
||||
<%
|
||||
import collections
|
||||
import pwnlib.abi
|
||||
import pwnlib.constants
|
||||
import pwnlib.shellcraft
|
||||
import six
|
||||
%>
|
||||
<%docstring>process_madvise(vararg_0, vararg_1, vararg_2, vararg_3, vararg_4) -> str
|
||||
|
||||
Invokes the syscall process_madvise.
|
||||
|
||||
See 'man 2 process_madvise' for more information.
|
||||
|
||||
Arguments:
|
||||
vararg(int): vararg
|
||||
Returns:
|
||||
long
|
||||
</%docstring>
|
||||
<%page args="vararg_0=None, vararg_1=None, vararg_2=None, vararg_3=None, vararg_4=None"/>
|
||||
<%
|
||||
abi = pwnlib.abi.ABI.syscall()
|
||||
stack = abi.stack
|
||||
regs = abi.register_arguments[1:]
|
||||
allregs = pwnlib.shellcraft.registers.current()
|
||||
|
||||
can_pushstr = []
|
||||
can_pushstr_array = []
|
||||
|
||||
argument_names = ['vararg_0', 'vararg_1', 'vararg_2', 'vararg_3', 'vararg_4']
|
||||
argument_values = [vararg_0, vararg_1, vararg_2, vararg_3, vararg_4]
|
||||
|
||||
# Load all of the arguments into their destination registers / stack slots.
|
||||
register_arguments = dict()
|
||||
stack_arguments = collections.OrderedDict()
|
||||
string_arguments = dict()
|
||||
dict_arguments = dict()
|
||||
array_arguments = dict()
|
||||
syscall_repr = []
|
||||
|
||||
for name, arg in zip(argument_names, argument_values):
|
||||
if arg is not None:
|
||||
syscall_repr.append('%s=%s' % (name, pwnlib.shellcraft.pretty(arg, False)))
|
||||
|
||||
# If the argument itself (input) is a register...
|
||||
if arg in allregs:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[index] = arg
|
||||
|
||||
# The argument is not a register. It is a string value, and we
|
||||
# are expecting a string value
|
||||
elif name in can_pushstr and isinstance(arg, (six.binary_type, six.text_type)):
|
||||
if isinstance(arg, six.text_type):
|
||||
arg = arg.encode('utf-8')
|
||||
string_arguments[name] = arg
|
||||
|
||||
# The argument is not a register. It is a dictionary, and we are
|
||||
# expecting K:V paris.
|
||||
elif name in can_pushstr_array and isinstance(arg, dict):
|
||||
array_arguments[name] = ['%s=%s' % (k,v) for (k,v) in arg.items()]
|
||||
|
||||
# The arguent is not a register. It is a list, and we are expecting
|
||||
# a list of arguments.
|
||||
elif name in can_pushstr_array and isinstance(arg, (list, tuple)):
|
||||
array_arguments[name] = arg
|
||||
|
||||
# The argument is not a register, string, dict, or list.
|
||||
# It could be a constant string ('O_RDONLY') for an integer argument,
|
||||
# an actual integer value, or a constant.
|
||||
else:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[target] = arg
|
||||
|
||||
# Some syscalls have different names on various architectures.
|
||||
# Determine which syscall number to use for the current architecture.
|
||||
for syscall in ['SYS_process_madvise']:
|
||||
if hasattr(pwnlib.constants, syscall):
|
||||
break
|
||||
else:
|
||||
raise Exception("Could not locate any syscalls: %r" % syscalls)
|
||||
%>
|
||||
/* process_madvise(${', '.join(syscall_repr)}) */
|
||||
%for name, arg in string_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr(arg, append_null=(b'\x00' not in arg))}
|
||||
${pwnlib.shellcraft.mov(regs[argument_names.index(name)], abi.stack)}
|
||||
%endfor
|
||||
%for name, arg in array_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr_array(regs[argument_names.index(name)], arg)}
|
||||
%endfor
|
||||
%for name, arg in stack_arguments.items():
|
||||
${pwnlib.shellcraft.push(arg)}
|
||||
%endfor
|
||||
${pwnlib.shellcraft.setregs(register_arguments)}
|
||||
${pwnlib.shellcraft.syscall(syscall)}
|
||||
@@ -0,0 +1,101 @@
|
||||
<%
|
||||
import collections
|
||||
import pwnlib.abi
|
||||
import pwnlib.constants
|
||||
import pwnlib.shellcraft
|
||||
import six
|
||||
%>
|
||||
<%docstring>riscv_flush_icache(vararg_0, vararg_1, vararg_2, vararg_3, vararg_4) -> str
|
||||
|
||||
Invokes the syscall riscv_flush_icache.
|
||||
|
||||
See 'man 2 riscv_flush_icache' for more information.
|
||||
|
||||
Arguments:
|
||||
vararg(int): vararg
|
||||
Returns:
|
||||
long
|
||||
</%docstring>
|
||||
<%page args="vararg_0=None, vararg_1=None, vararg_2=None, vararg_3=None, vararg_4=None"/>
|
||||
<%
|
||||
abi = pwnlib.abi.ABI.syscall()
|
||||
stack = abi.stack
|
||||
regs = abi.register_arguments[1:]
|
||||
allregs = pwnlib.shellcraft.registers.current()
|
||||
|
||||
can_pushstr = []
|
||||
can_pushstr_array = []
|
||||
|
||||
argument_names = ['vararg_0', 'vararg_1', 'vararg_2', 'vararg_3', 'vararg_4']
|
||||
argument_values = [vararg_0, vararg_1, vararg_2, vararg_3, vararg_4]
|
||||
|
||||
# Load all of the arguments into their destination registers / stack slots.
|
||||
register_arguments = dict()
|
||||
stack_arguments = collections.OrderedDict()
|
||||
string_arguments = dict()
|
||||
dict_arguments = dict()
|
||||
array_arguments = dict()
|
||||
syscall_repr = []
|
||||
|
||||
for name, arg in zip(argument_names, argument_values):
|
||||
if arg is not None:
|
||||
syscall_repr.append('%s=%s' % (name, pwnlib.shellcraft.pretty(arg, False)))
|
||||
|
||||
# If the argument itself (input) is a register...
|
||||
if arg in allregs:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[index] = arg
|
||||
|
||||
# The argument is not a register. It is a string value, and we
|
||||
# are expecting a string value
|
||||
elif name in can_pushstr and isinstance(arg, (six.binary_type, six.text_type)):
|
||||
if isinstance(arg, six.text_type):
|
||||
arg = arg.encode('utf-8')
|
||||
string_arguments[name] = arg
|
||||
|
||||
# The argument is not a register. It is a dictionary, and we are
|
||||
# expecting K:V paris.
|
||||
elif name in can_pushstr_array and isinstance(arg, dict):
|
||||
array_arguments[name] = ['%s=%s' % (k,v) for (k,v) in arg.items()]
|
||||
|
||||
# The arguent is not a register. It is a list, and we are expecting
|
||||
# a list of arguments.
|
||||
elif name in can_pushstr_array and isinstance(arg, (list, tuple)):
|
||||
array_arguments[name] = arg
|
||||
|
||||
# The argument is not a register, string, dict, or list.
|
||||
# It could be a constant string ('O_RDONLY') for an integer argument,
|
||||
# an actual integer value, or a constant.
|
||||
else:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[target] = arg
|
||||
|
||||
# Some syscalls have different names on various architectures.
|
||||
# Determine which syscall number to use for the current architecture.
|
||||
for syscall in ['SYS_riscv_flush_icache']:
|
||||
if hasattr(pwnlib.constants, syscall):
|
||||
break
|
||||
else:
|
||||
raise Exception("Could not locate any syscalls: %r" % syscalls)
|
||||
%>
|
||||
/* riscv_flush_icache(${', '.join(syscall_repr)}) */
|
||||
%for name, arg in string_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr(arg, append_null=(b'\x00' not in arg))}
|
||||
${pwnlib.shellcraft.mov(regs[argument_names.index(name)], abi.stack)}
|
||||
%endfor
|
||||
%for name, arg in array_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr_array(regs[argument_names.index(name)], arg)}
|
||||
%endfor
|
||||
%for name, arg in stack_arguments.items():
|
||||
${pwnlib.shellcraft.push(arg)}
|
||||
%endfor
|
||||
${pwnlib.shellcraft.setregs(register_arguments)}
|
||||
${pwnlib.shellcraft.syscall(syscall)}
|
||||
@@ -0,0 +1,101 @@
|
||||
<%
|
||||
import collections
|
||||
import pwnlib.abi
|
||||
import pwnlib.constants
|
||||
import pwnlib.shellcraft
|
||||
import six
|
||||
%>
|
||||
<%docstring>sysriscv(vararg_0, vararg_1, vararg_2, vararg_3, vararg_4) -> str
|
||||
|
||||
Invokes the syscall sysriscv.
|
||||
|
||||
See 'man 2 sysriscv' for more information.
|
||||
|
||||
Arguments:
|
||||
vararg(int): vararg
|
||||
Returns:
|
||||
long
|
||||
</%docstring>
|
||||
<%page args="vararg_0=None, vararg_1=None, vararg_2=None, vararg_3=None, vararg_4=None"/>
|
||||
<%
|
||||
abi = pwnlib.abi.ABI.syscall()
|
||||
stack = abi.stack
|
||||
regs = abi.register_arguments[1:]
|
||||
allregs = pwnlib.shellcraft.registers.current()
|
||||
|
||||
can_pushstr = []
|
||||
can_pushstr_array = []
|
||||
|
||||
argument_names = ['vararg_0', 'vararg_1', 'vararg_2', 'vararg_3', 'vararg_4']
|
||||
argument_values = [vararg_0, vararg_1, vararg_2, vararg_3, vararg_4]
|
||||
|
||||
# Load all of the arguments into their destination registers / stack slots.
|
||||
register_arguments = dict()
|
||||
stack_arguments = collections.OrderedDict()
|
||||
string_arguments = dict()
|
||||
dict_arguments = dict()
|
||||
array_arguments = dict()
|
||||
syscall_repr = []
|
||||
|
||||
for name, arg in zip(argument_names, argument_values):
|
||||
if arg is not None:
|
||||
syscall_repr.append('%s=%s' % (name, pwnlib.shellcraft.pretty(arg, False)))
|
||||
|
||||
# If the argument itself (input) is a register...
|
||||
if arg in allregs:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[index] = arg
|
||||
|
||||
# The argument is not a register. It is a string value, and we
|
||||
# are expecting a string value
|
||||
elif name in can_pushstr and isinstance(arg, (six.binary_type, six.text_type)):
|
||||
if isinstance(arg, six.text_type):
|
||||
arg = arg.encode('utf-8')
|
||||
string_arguments[name] = arg
|
||||
|
||||
# The argument is not a register. It is a dictionary, and we are
|
||||
# expecting K:V paris.
|
||||
elif name in can_pushstr_array and isinstance(arg, dict):
|
||||
array_arguments[name] = ['%s=%s' % (k,v) for (k,v) in arg.items()]
|
||||
|
||||
# The arguent is not a register. It is a list, and we are expecting
|
||||
# a list of arguments.
|
||||
elif name in can_pushstr_array and isinstance(arg, (list, tuple)):
|
||||
array_arguments[name] = arg
|
||||
|
||||
# The argument is not a register, string, dict, or list.
|
||||
# It could be a constant string ('O_RDONLY') for an integer argument,
|
||||
# an actual integer value, or a constant.
|
||||
else:
|
||||
index = argument_names.index(name)
|
||||
if index < len(regs):
|
||||
target = regs[index]
|
||||
register_arguments[target] = arg
|
||||
elif arg is not None:
|
||||
stack_arguments[target] = arg
|
||||
|
||||
# Some syscalls have different names on various architectures.
|
||||
# Determine which syscall number to use for the current architecture.
|
||||
for syscall in ['SYS_sysriscv']:
|
||||
if hasattr(pwnlib.constants, syscall):
|
||||
break
|
||||
else:
|
||||
raise Exception("Could not locate any syscalls: %r" % syscalls)
|
||||
%>
|
||||
/* sysriscv(${', '.join(syscall_repr)}) */
|
||||
%for name, arg in string_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr(arg, append_null=(b'\x00' not in arg))}
|
||||
${pwnlib.shellcraft.mov(regs[argument_names.index(name)], abi.stack)}
|
||||
%endfor
|
||||
%for name, arg in array_arguments.items():
|
||||
${pwnlib.shellcraft.pushstr_array(regs[argument_names.index(name)], arg)}
|
||||
%endfor
|
||||
%for name, arg in stack_arguments.items():
|
||||
${pwnlib.shellcraft.push(arg)}
|
||||
%endfor
|
||||
${pwnlib.shellcraft.setregs(register_arguments)}
|
||||
${pwnlib.shellcraft.syscall(syscall)}
|
||||
Loaded 100 of 141 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user