Compare commits

...
80 Commits
Author SHA1 Message Date
Rahulandrahul05ranjan 459dfd7e35 fix(regsort): drop self-assignments through register aliases (#2795)
* fix(regsort): drop self-assignments through register aliases

The self-assignment drop compared register names only (k != v), so an
assignment through an alias (e.g. {'ax': 'eax'} with registers.native32)
was not recognized as a no-op.  It then surfaced as a spurious
1-register dependency cycle, which either raised PwnlibException with
xchg=False or emitted a useless 'mov' of a register into its own alias.

With xchg=False and other registers present, the bogus cycle also
forced the temporary-register code path, reordering unrelated moves and
silently leaving registers with wrong values (see the linked issue).

Compare the mapped names instead, like the rest of the function.

Fixes #2794

Co-authored-by: rahul05ranjan <[email protected]>

* docs(changelog): add regsort register-alias self-assignment fix entry

---------

Co-authored-by: Rahul Ranjan <[email protected]>
2026-10-30 16:20:25 +01:00
peace-maker d8d47977ac gdb.corefile: Run gdb directly to prevent detach race (#2787)
* gdb.corefile: Run gdb directly to prevent detach race

`attach()` waits for the debugger to attach by polling the `TracerPid` regularly. `corefile()` runs `detach` in gdb after dumping the core, so the debugger might attach and detach between two `TracerPid` polls and `wait_for_debugger()` thinks gdb exited before attaching and returns `None` as gdb's pid is no longer valid.

Later `corefile()` ran `psutil.Process(pid).wait()` with `pid = None` which effectively waited on the Python process itself to exit.
This caused a hang in the doctest CI sometimes, which was killed by the watchdog timer eventually.

Run `gdb` directly and just observe the exit code instead of relying on the more advanced `attach` logic for longer running debug sessions.

* Update CHANGELOG
2026-10-26 06:15:28 +00:00
Max Freedom Pollardandpeace-maker 3daf28b6be fix(packing): dd() raises TypeError on a bytearray destination (#2772)
* fix(packing): dd() raises TypeError on a bytearray destination

dd() documents bytearray as a supported destination type, but
dd(bytearray(b'Hello!'), b'?', skip=5) raises
"TypeError: 'bytes' object cannot be interpreted as an integer".

pwnlib/util/packing.py:1108 handled list and bytearray destinations in a
single branch and filled both with list(map(p8, bytearray(src))). p8()
returns a length-1 bytes object, which is what a list destination is
documented to hold (see the existing dd(list('Hello!'), (63,), skip=5)
doctest), but a bytearray slice assignment needs an iterable of int, so
every bytearray destination crashed.

Assign the byte string src directly when the destination is a bytearray.
Every src branch above the destination dispatch (packing.py:1039-1089)
has already reduced src to a byte string, so the slice assignment is
always valid. This also makes a bytearray destination agree with the
bytes and str destinations, which already copy src verbatim.

Add a doctest covering the returned value and the in-place update of the
caller's bytearray.

* Add changelog entry for #2772

---------

Co-authored-by: peace-maker <[email protected]>
2026-10-24 12:15:03 +02:00
h4kk4p4kk4andpeace-maker f4b3e6e1c4 fix(elf): prevent elf.libc returning the executable when its name starts with libc[.-] (#2781)
Co-authored-by: peace-maker <[email protected]>
2026-10-24 12:12:47 +02:00
Max Freedom PollardandPeace-Maker 2b39684912 Disable debuginfod doctests in libcdb.unstrip_libc on stable (#2773)
* Disable debuginfod tests in libcdb.unstrip_libc

The external debuginfod servers are really slow or won't respond at all like debuginfod.ubuntu.com.
The caching in CI doesn't help since we only cache it for 3 month and the query fails afterwards most of the time. We cache the negative response too which doesn't help if the service is flakey itself :D

(cherry picked from commit 86cafce196)

* Add changelog entry for #2773

---------

Co-authored-by: Peace-Maker <[email protected]>
2026-10-21 20:04:53 +02:00
peace-maker 7e5e79d00f Allow running with Unicorn 2.1.[34] but throw when emulating MIPS (#2721)
* Allow running with Unicorn 2.1.[34] but throw when emulating MIPS

Unicorn 2.1.5 wasn't released for a while and 2.1.2 doesn't have binary wheels for Python 3.14.
This made installing pwntools on newer Python versions more annoying since you had to build Unicorn yourself.

The only problem with the blocked versions is MIPS emulation, so only avoid that while allowing to use Unicorn 2.1.3 or 2.1.4 for other architectures.

Refs #2621

* Update CHANGELOG
2026-04-27 18:23:01 +02:00
0xDanielandpeace-maker e551b4ae56 fix: apply force_to_bytes to readline result in non-term_mode path (#2707)
Co-authored-by: peace-maker <[email protected]>
2026-04-07 11:28:48 +02:00
43ef1b494c Fix _build_date() crash on non-standard locale date strings (#2701)
* Fix _build_date() crash on non-standard locale date strings (#2513)

Some Android devices return locale-dependent strings in ro.build.date
(e.g. '2017年 11月 14日 星期二 09:55:07 CST' for Chinese locale) that
dateutil.parser.parse() cannot handle, causing wait_for_device() to
crash with a ParserError.

Fix: prefer ro.build.date.utc (integer epoch timestamp) which is
locale-independent and available on all Android devices. Fall back
to ro.build.date with error handling if the UTC property is missing.

* Add CHANGELOG entry for #2513 fix

* Simplify _build_date(): prefer ro.build.date.utc, keep minimal fallback

Address review: ro.build.date.utc is set by the AOSP build system
and available on all standard Android devices. Simplified comments
to reflect this is the primary path, with ro.build.date kept only
as a fallback for non-standard builds.

* Move CHANGELOG entry

* Fix Python 2.7 compatibility

* Disable intro doctest connecting to `ftp.ubuntu.com`

The FTP server is throttled in CI or just really slow. We already test the basic tcp tubes in the `remote` tests.

---------

Co-authored-by: coder999999999 <[email protected]>
Co-authored-by: peace-maker <[email protected]>
2026-04-07 11:09:01 +02:00
be92aa1b4c fix: pad bytes fields to correct field size in FileStructure (#2694)
* fix: pad bytes fields to correct field size in FileStructure

When setting bytes fields (e.g. _IO_save_base) on FileStructure, the
value was padded to context.bytes instead of the actual field size from
self.length[val]. This caused struct.pack errors for fields whose size
differs from the pointer size.

Fixes #2693

* Cleanup test and add CHANGELOG

---------

Co-authored-by: nightcityblade <[email protected]>
Co-authored-by: Peace-Maker <[email protected]>
2026-04-05 20:37:31 +00:00
Peace-Maker 07f3caadc4 Stay with pylint < 4.0 until recursion errors are fixed
https://github.com/pylint-dev/pylint/issues/9190
2025-10-16 16:17:08 +02:00
Peace-Maker 3ad86ec5ad Release 4.15.0 2025-10-12 16:48:05 +02:00
Arusekk b5076d9262 Merge branch 'stable' into beta 2025-09-26 09:54:54 +02:00
ArusekkandHackrrr 77b4f06b07 docs: warn that .libs/.libc/.maps are dangerous (#2626)
Co-authored-by: Hackrrr <[email protected]>
2025-09-26 07:36:34 +00:00
Arusekk 4968499d11 ffix: ugly ELF docs (whitespace only) 2025-09-26 09:20:53 +02:00
Peace-Maker f38991bc02 Merge branch 'stable' into beta 2025-09-16 21:41:00 +02:00
peace-maker d0e6ee4b37 Fix regression: gdbserver can't handle command-line argument containing whitespace (#2624)
* Fix regression: gdbserver can't handle command-line argument containing whitespace

The `--no-startup-with-shell` argument was passed in an attempt to
fix gdbserver startup with `SHELL=/bin/fish`. (#2377) It caused a regression
which disallowed passing arguments containing whitespace to the debuggee in `gdb.debug`.

gdbserver would exit with a message:
"can't handle command-line argument containing whitespace"

There is a 3 second timeout waiting for gdbserver to startup and
printing a message with a workaround already suggesting to set
`SHELL=/bin/bash` to allow gdbserver to launch. This has to be
our best effort to guide users of such shells until we find time
to investigate a better solution.

Fixes #2550

* Update CHANGELOG
2025-09-16 21:06:29 +02:00
peace-makerandArusekk 48ea09b27f Fix lookup of binutils for mipsel architecture (#2612)
* Fix lookup of binutils for `mipsel` architecture

The endianness is encoded in the architecture name for mips targets which wasn't respected while looking for the correct binutils binary.

Sync the CI and Dockerfile binutils packages while we're at it.

Fixes #2591

* Update CHANGELOG

* still fall back to the other endianness

---------

Co-authored-by: Arusekk <[email protected]>
2025-09-11 13:09:28 +00:00
Arusekk 9f22a2f202 Merge branch 'stable' into beta 2025-09-11 14:55:56 +02:00
Arusekk 7413a3da31 Exclude Unicorn versions segfaulting on MIPS PLT (#2621)
Fixes #2619
2025-09-11 12:55:51 +00:00
Peace-Maker 95aac6e367 Merge branch 'stable' into beta 2025-09-05 13:59:45 +02:00
Peace-Maker 9ed93a5281 Fix race condition in process mapping tests
We could try to lookup the mapped libraries before they are actually loaded in the process.
Wait until the program is up and running before trying to fetch the memory maps.
2025-09-05 13:14:57 +02:00
peace-maker 3579fb1384 Fix log level of child remotes of server tube (#2609)
* Fix log level of child remotes of `server` tube

The log level of the `server` tube wasn't passed
on to the `remote` wrappers created upon receiving
a new child connection. This caused the connection
closed message to be logged even when the server
object was created with `level='error'`.

* Update CHANGELOG
2025-09-05 12:25:49 +02:00
Peace-Maker 485bf0a0b7 Merge branch 'stable' into beta 2025-08-28 14:36:00 +02:00
William Tan b133b76b4e Allow setting debugger path via context.gdb_binary (#2602)
* Allow setting debugger path via context

* Update changelog
2025-08-19 10:30:05 +02:00
ffc46d277a Fix poll error in process.libs() and clean up maps parsing (#2579)
Co-authored-by: Raccoon <raccoon@42>
Co-authored-by: peace-maker <[email protected]>
2025-08-09 14:47:57 +00:00
Peace-Maker dd3a5f6974 libcdb: Fix cache handling of debuginfo
When trying multiple debuginfod servers, the first one to fail would save the failed attempt and block the remaining servers to be tried.

Only save that we couldn't find the debuginfo if we tried all the configured servers.
2025-08-06 14:32:08 +02:00
Peace-Maker 9a275b2db0 Fix libcdb cache in CI
Requests to debuginfod.elfutils.org had the wrong SNI in their request.

Cache requests to debuginfod.ubuntu.com too.
2025-08-06 12:16:10 +02:00
Peace-Maker 1c28222fe6 Merge remote-tracking branch 'stable' into beta-staging 2025-08-05 21:47:13 +02:00
peace-maker b93c5ace10 Ignore colored_traceback error when TERM is unset (#2596)
* Ignore colored_traceback error when TERM is unset

Fixes using pwntools in non-interactive sage scripts with newer colored_traceback versions.

Fixes #2594

* Update CHANGELOG
2025-08-05 21:25:21 +02:00
peace-maker da9797c1c2 Support longer function names in Windows getexport shellcode (#2587)
* Support longer function names in Windows getexport shellcode

Previously, an arbitrary name length limit of 8 characters was in place due to the lack of a proper strcmp loop. Implement a cheap strcmp for longer function names.
This trashes a bunch of registers and we might be able to optimize it further to reduce the damage.

Use a unique label too to avoid redefinition when using the shellcraft template twice in the same shellcode. Use the mov shellcraft template for the destination register to avoid an instruction if the result is already in the desired register.

* Update CHANGELOG
2025-08-05 14:55:35 +00:00
Shordenandpeace-maker 6dfe8b6f72 Use unicorn on macOS w/ SIP enabled (#2593)
* __ensure_memory_to_run_unicorn: don't request wx memory

macOS systems with SIP enabled prohibit mmaping WX memory.
unicorn doesn't run into this issue because it uses the MAP_JIT
protection flag.

See also:
https://github.com/unicorn-engine/unicorn/blob/803fe5a47770360d1942de72600d3b295b521e31/qemu/accel/tcg/translate-all.c#L1021-L1032
https://github.com/pwndbg/pwndbg/blob/2f6b5bbaea484391f55850a09a16efda161498f2/pwndbg/aglib/disasm/__init__.py#L305-L316

* update changelog

---------

Co-authored-by: peace-maker <[email protected]>
2025-08-05 11:39:28 +00:00
peace-maker 425221fb30 Add Ubuntu and Debian debuginfod servers (#2595)
* Add Ubuntu and Debian debuginfod servers

Most CTF challenges are hosted on Ubuntu or Debian [citation needed], so check their debuginfod servers before trying the federating one as a fallback.

This is required since the elfutils.org server seems down for maintenance occasionally.

* Update CHANGELOG
2025-08-05 13:02:00 +02:00
Chaitanya RahalkarandPeace-Maker 004a6dab88 Add automatic detection of statically linked binaries in detect_missing_binaries function. (#2570)
* Add automatic detection of statically linked binaries in `detect_missing_binaries` function.

* Add entry for PR #2570 to CHANGELOG.md: fix `pwn template` for statically linked binaries.

* Remove partial test implementation

The commands should be tested end-to-end instead of using doctests (later).

---------

Co-authored-by: Peace-Maker <[email protected]>
2025-07-11 13:10:40 +02:00
Arusekk 6098f28bfa Merge branch 'stable' into beta 2025-04-02 18:00:52 +02:00
Arusekk 1205b1aaa3 regsort: respect register aliases (#2576)
Closes #2481
2025-04-02 15:57:59 +00:00
tesujiandArusekk ce6d2ca847 Fix invalid parsing of loader error message in elf.libc (#2567)
For example, on my machine:

  > ./main_no_flag
  ./main_no_flag: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.32' not found (required by ./main_no_flag)

Co-authored-by: Arusekk <[email protected]>
2025-04-02 14:17:30 +02:00
Peace-Maker 9e0ca3a415 Move changelog entry to stable log 2025-03-30 12:21:08 +02:00
Daniel Kilimnik b60b2e897f SSH: fix download/upload with -1 exit status (#2545)
* SSH: fix download/upload with -1 exit status

* Add Changelog
2025-03-30 10:19:42 +00:00
Arusekk 2c3e783f96 Release 4.15.0beta1 2025-03-24 13:21:16 +01:00
Arusekk 7c95e838f4 Merge branch 'stable' into beta 2025-03-24 12:15:36 +01:00
Peace-Maker ec6b8cd87c Merge branch 'stable' into beta 2025-01-26 23:47:08 +01:00
Peace-Maker d7a7376eca Merge branch 'stable' into beta 2025-01-15 20:34:56 +01:00
Peace-Maker c02190b5d4 Release 4.15.0beta0 2025-01-15 08:48:06 +01:00
Luca Bancale 7741a187ea Ignore a warning with unused args in asm on NIX (#2508)
* Ignore a warning when compiling with asm

* Add pr to changelog
2025-01-14 22:50:23 +01:00
Findus 4ef3c16d09 ssh: replaced nonexistent key with str(e) in error handling (#2512) 2025-01-06 22:43:21 +01:00
fb2ee19b90 Deprecate direct commandline scripts invocation and exclude nonsense ones (#2364)
* deprecate direct commandline scripts invocation and exclude nonsense ones

* Don't deprecate all commandline tools

---------

Co-authored-by: Arusekk <[email protected]>
Co-authored-by: Peace-Maker <[email protected]>
2024-12-10 22:47:47 +01:00
Jakub Nowakandpeace-maker 74a300db6c Deprecate 'keepends' argument in favor of 'drop' (#2476)
* Replace 'keepends' with 'drop'

Add 'drop' argument in place of 'keepends' for tubes. 'keepends' still
works but raises depreciation warning.

* changelog

* Ignore line numbers in PyLint check

---------

Co-authored-by: peace-maker <[email protected]>
2024-12-10 22:31:29 +01:00
peace-maker 57b9eb9107 Fix loading ELF files without valid .dynamic section (#2502)
* Fix loading ELF files without valid .dynamic section

This allows to load separate debuginfo files and access their symbols.

* Update CHANGELOG
2024-12-10 21:36:33 +01:00
Peace-Maker b2d56fa37c Merge branch 'beta' into dev 2024-12-10 21:17:16 +01:00
Peace-Maker 24d217cfbd Docs: Fix link to source for class properties
The property has setters and getters. Link to the getter if it's available. This adds line numbers to the source link for properties.

Fixes #2401
2024-12-09 13:09:10 +01:00
peace-maker ec262d8d01 Update sphinx for Python 3.13 support (#2503)
* Fix sphinx warnings in docstrings

* Update sphinx for Python 3.13 support

Could not import extension sphinx.builders.epub3 (exception: No module named 'imghdr')

`imghdr` was removed in Python 3.13.
2024-12-08 21:16:39 +01:00
Justin ApplegateandPeace-Maker 55ac6e11fc Update documentation for format strings (#2501)
* Update fmtstr.py documentation

Clarified that the `value` in the `writes` dict (for `fmtstr_payload()`) should be a bytestring if the value to be written is shorter than a long

* Update fmtstr.py documentation for FmtStr class

Updated example and definition for `write()` function in `FmtStr` class to include bytes as the value.

* Fix code formatting

---------

Co-authored-by: Peace-Maker <[email protected]>
2024-12-08 19:33:32 +01:00
peace-maker 6f0793eebc Add tube.upload_manually to upload files in chunks (#2410)
* Add `tube.upload_manually`

Upload data in chunks when having a tube connected to a shell.
This is useful when doing kernel or qemu challenges where you can't use the ssh tube's file upload features.

* Add tests and fix corner cases

* Update CHANGELOG

* Fix character escaping in tests

* Fix gzip compression on Python 2
2024-10-28 21:11:36 +01:00
ckxckxandPeace-Maker 51cbdb465d Fix attaching to a gdbserver with tuple gdb.attach(('0.0.0.0',12345)) (#2291)
* Patch for #issues/2290

* Return listening process on `pidof(("0.0.0.0", 1234))`

Instead of returning the process which is connected to port 1234,
return the process which is listening on that port.

* Update CHANGELOG

---------

Co-authored-by: Peace-Maker <[email protected]>
2024-10-28 21:06:56 +01:00
Peace-Maker 61804b169b Merge branch 'beta' into dev 2024-10-24 23:28:53 +02:00
peace-maker bb7a85c8df Allow to disable caching (#2484)
* Allow to disable caching

By setting `context.cache_dir = None`. Generate default cache dir again by setting `context.cache_dir = True`.

* Disable cache in `asm` caching test

* Update CHANGELOG

* Fix asm cache test
2024-10-24 17:04:50 +02:00
Peace-Maker 3303ea949d Merge branch 'beta' into dev 2024-10-24 16:44:19 +02:00
Th3Sandpeace-maker fa14663243 libcdb-cli: add --offline-only, refactor unstrip and add fetch parser for download libc-database (#2478)
* Add `return_raw` for `search_by_symbol_offsets`

* Add `--offline-only` and unstrip libc as default behavior

* Add short arg name for `--download-libc`

* Fix bugs

* Add fetch parser

* Fix bugs

* file parse not unstrip default

* Update function docs

* Update CHANGELOG

* Edit dest of `--no-strip`

* Update CHANGELOG

* Unstrip before `return cache`

* Revert `--unstrip` help

* Improve `libcdb fetch` default behavior

* Perf fetch command

* Fix fetch command `-u`

---------

Co-authored-by: peace-maker <[email protected]>
2024-10-24 16:11:07 +02:00
peace-maker d2253110bd Add caching proxy for libcdb debuginfod files to CI (#2487) 2024-10-24 15:59:24 +02:00
peace-maker a3b22b748d Throw error when using sni and setting server_hostname manually in remote (#2482)
* Throw error when using `sni` and setting `server_hostname` manually in `remote`

Prevents silently replacing the `server_hostname` that was provided in `ssl_args`.

Fixes #2425

* Update CHANGELOG
2024-10-24 15:56:47 +02:00
peace-maker 584eccaa33 Only print checksec output of ELF.libc when it was printed for the ELF already (#2483)
* Only print `checksec` output of `ELF.libc` when it was printed for the `ELF` already

* Update CHANGELOG
2024-10-24 15:55:37 +02:00
robbert1978 7dceeddca8 Stop using cmd.exe to keep current directory (#2488)
* Stop using cmd.exe to keep current directory

* Update misc.py

* Update misc.py, deal with cmd.exe

* Update misc.py
2024-10-24 15:51:07 +02:00
Peace-Maker 34da249779 Bump Ubuntu versions in README and bug report template 2024-10-12 18:04:01 +02:00
Peace-Maker c68c00c316 Merge branch 'beta' into dev 2024-10-12 18:01:08 +02:00
Lorenzo Cian cfc021d88e Extract libraries from Docker image (#2479)
* feat: extract libraries from Docker image

* docs: update CHANGELOG.md

* fix: python2.7 compatibility

* address comments

* address linter
2024-10-07 11:46:05 +02:00
Peace-Maker 9f92ed04fc Fix docs of ELF.{libs,maps}
Fixes #2400
2024-10-03 12:17:06 +02:00
k4lizen b08f4b7bc8 redirect kitty kill command stderr to /dev/null (#2472) 2024-10-01 19:37:52 +02:00
Peace-Maker d664bb49d4 Merge branch 'beta' into dev 2024-09-30 00:45:22 +02:00
peace-maker fa5a288a69 Fix waiting for gdb under WSL2 (#2470)
* Fix returning wrong pid in WSL for run_in_new_terminal

We run cmd.exe which and other Windows processes before going back into WSL. The returned pid would be the one for the ephemeral cmd.exe process instead of the real command we wanted to launch.

I don't know how to properly trace the execution and get the command pid, so scan for newer pids matching the command for a while instead as a workaround.

We wrap the command in a script so psutil.Process.exe() returns the path to the shell instead of the real command. Look at psutil.Process.cmdline() too which contains the real program running right now.

* Make `proc.wait_for_debugger` return the debugger pid

If we fail to get the pid when launching gdb, grab it after tracing the debugger at least. gdb won't be closed when the exploit exits but at least we have the correct pid.

* Fix working directory of run_in_new_terminal in WSL

The process' cwd would be %WINDIR% due to cmd.exe not supporting WSL paths.

* Update CHANGELOG
2024-09-30 00:27:40 +02:00
peace-maker 69ab2054e8 Fix collecting coverage in CI (#2477)
The upload-artifact action v4.4.0 excluded hidden files from uploads by default. We want to upload only hidden `.coverage*` files though. Enable hidden files again using the `include-hidden-files` input.

https://github.com/actions/upload-artifact/releases/tag/v4.4.0
2024-09-30 00:20:59 +02:00
Peace-Maker 907e921043 Merge branch 'beta' into dev 2024-09-30 00:08:31 +02:00
Th3Sandpeace-maker ee63072930 libcdb: improve the search speed of search_by_symbol_offsets (#2413)
* Add `hash_type` for `search_by_symbol_offsets`

* Add docs

* Update CHANGELOG

* Allow search `id` in search_by_hash

* Fix py2.7 test

* Rename `hash_type` to `search_type`

* Rename `TYPES['id']` to `TYPES['libs_id']`

* Rename part `hex_encoded_id` to `search_target`

* Turbofast extract build id

* Fix docs

* Add a map for types key

* Extract proper buildid

* Fix docs

* Fix E0606

* Simplify get `mapped_type`

* Add `search_by_libs_id` to `__all__`

* Modify docs

* Fix py2.7

* Fix reference

---------

Co-authored-by: peace-maker <[email protected]>
2024-09-29 01:53:06 +02:00
k4lizen 785ed9fdda Properly close spawned kitty window (#2471)
* properly close spawned kitty window

* python2 support

* changelog
2024-09-27 09:23:06 +02:00
peace-maker cdfd64f6de Install pwntools on Windows and import it once (#2450)
This is just a basic smoke test for now.
2024-09-26 13:44:52 +02:00
peace-maker 3727c93859 Add ELF.close() to release resources (#2444)
* Add ELF.close() to release resources

`ELFFile.close()` just closes the mmap'd file, but our own wrapper keeps the file handle open.

This is annoying when using a temporary file on Windows since they can't be deleted if there is
a dangling handle. This can be used together with the inherited context manager from ELFFile.

* Update CHANGELOG
2024-09-26 13:41:18 +02:00
Peace-Maker bc453b46c3 Merge branch 'beta' into dev 2024-09-26 01:57:52 +02:00
tesuji d7817a7eac Nicely handle non ELF files in checksec (#2457) 2024-09-11 11:22:13 +02:00
patryk4815 df620d7449 darwin: generate syscalls sdk 15.1 (#2448) 2024-08-25 12:59:14 +02:00
peace-maker 67678c2e1c Cache output of asm() (#2358)
* Cache output of `asm()`

To speed up repeated runs of an exploit, cache the assembled output.

Use a sha1 hash of the shellcode as well as relevant context values
like `context.arch` and `context.bits` to see if the exact same
shellcode was assembled for the same context before.

Fixes #2312

* Return path to cache file if `not extract`

* Update CHANGELOG

* Create temporary copy of cached file

* Add debug log about using the cache

* Include full assembler and linker commandlines in hash

This should catch any changes across pwntools updates and system environment changes.

* Include pwntools version in hash
2024-08-12 20:59:22 +02:00
Peace-Maker 734cb3bf82 Begin working on 4.15.0 2024-08-12 19:45:10 +02:00
56 changed files with 2178 additions and 530 deletions

No files matched your search

+1 -1
View File
@@ -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
+69 -2
View File
@@ -12,6 +12,22 @@ jobs:
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:
@@ -21,6 +37,28 @@ 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: |
@@ -29,11 +67,10 @@ jobs:
sudo apt-get update && sudo apt-get install -y python3-pip gdb gdbserver
/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
if: matrix.python_version == '2.7'
id: cache-pip
with:
path: ~/.cache/pip
key: ${{ matrix.os }}-${{ matrix.python_version }}-cache-pip-${{ hashFiles('**/pyproject.toml', '**/requirements*.txt') }}
@@ -84,6 +121,7 @@ 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 \
@@ -112,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)'
@@ -224,7 +264,34 @@ jobs:
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
+4 -3
View File
@@ -24,12 +24,13 @@ jobs:
- 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
+77 -7
View File
@@ -10,8 +10,8 @@ The table below shows which release corresponds to each branch, and what date th
| Version | Branch | Release Date |
| ---------------- | -------- | ---------------------- |
| [5.0.0](#500-dev) | `dev` |
| [4.15.0](#4150-beta) | `beta` |
| [4.14.0](#4141-stable) | `stable` | Mar 24, 2025
| [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
@@ -75,6 +75,8 @@ The table below shows which release corresponds to each branch, and what date th
## 5.0.0 (`dev`)
- [#2598][2598] aarch64: Fix ABI definition
- [#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
@@ -82,13 +84,26 @@ The table below shows which release corresponds to each branch, and what date th
- [#2524][2524] Raise EOFError during `process.recv` when stdout closes on Windows
- [#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
- [#2527][2527] Allow setting debugger path via `context.gdb_binary`
- [#2530][2530] Do NOT error when passing directory arguments in `checksec` commandline tool.
- [#2529][2529] Add LoongArch64 support
- [#2506][2506] ROP: fix `ROP(ELF(exe)).leave` is `None` in some ELF
- [#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
- [#2592][2592] pwnlib.config: Fix customization of `context.timeout`
- [#2608][2608] Abort on `libcdb file libc.so --unstrip` if eu-unstrip is not installed
- [#2611][2611] Cleanup `pwnlib.lexer` exports and imports
- [#2610][2610] Fix `log.progress` ignoring `context.log_console`
- [#2615][2615] tube/process: Fix redirecting stderr to stdout on Windows
[2598]: https://github.com/Gallopsled/pwntools/pull/2598
[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
@@ -96,14 +111,43 @@ The table below shows which release corresponds to each branch, and what date th
[2524]: https://github.com/Gallopsled/pwntools/pull/2524
[2526]: https://github.com/Gallopsled/pwntools/pull/2526
[2517]: https://github.com/Gallopsled/pwntools/pull/2517
[2527]: https://github.com/Gallopsled/pwntools/pull/2527
[2530]: https://github.com/Gallopsled/pwntools/pull/2530
[2529]: https://github.com/Gallopsled/pwntools/pull/2529
[2506]: https://github.com/Gallopsled/pwntools/pull/2506
[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
[2592]: https://github.com/Gallopsled/pwntools/pull/2592
[2608]: https://github.com/Gallopsled/pwntools/pull/2608
[2611]: https://github.com/Gallopsled/pwntools/pull/2611
[2610]: https://github.com/Gallopsled/pwntools/pull/2610
[2615]: https://github.com/Gallopsled/pwntools/pull/2615
## 4.15.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
[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
## 4.15.0 (`stable`)
- [#2508][2508] Ignore a warning when compiling with asm on nix
- [#2471][2471] Properly close spawned kitty window
@@ -122,6 +166,19 @@ The table below shows which release corresponds to each branch, and what date th
- [#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
@@ -140,8 +197,21 @@ The table below shows which release corresponds to each branch, and what date th
[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 (`stable`)
## 4.14.1
- [#2451][2451] Show symbols defined to value 0 (start of file)
- [#2533][2533] Fix installation on Python 3.5 and lower
@@ -592,7 +662,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
+1 -1
View File
@@ -32,7 +32,7 @@ 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
+3 -2
View File
@@ -2,7 +2,8 @@ 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
@@ -18,6 +19,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
+3
View File
@@ -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)
+2
View File
@@ -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 ...'
+9
View File
@@ -1 +1,10 @@
.. testsetup:: *
from pwn import *
:mod:`pwnlib.protocols.adb` --- Protocol implementations
========================================================
.. automodule:: pwnlib.protocols.adb
:members:
+3 -3
View File
@@ -4,16 +4,16 @@
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:
+1 -1
View File
@@ -3,7 +3,7 @@
from pwn import *
:mod:`pwnlib.windbg` --- Working with WinDbg
======================================
============================================
.. automodule:: pwnlib.windbg
:members:
+2
View File
@@ -32,8 +32,10 @@ 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 \
+9 -1
View File
@@ -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('_')]
+21 -1
View File
@@ -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):
+64 -4
View File
@@ -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,6 +180,12 @@ 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] + {
@@ -182,11 +193,14 @@ def which_binutils(util, check_version=False):
'i386': ['x86_64', 'amd64'],
'i686': ['x86_64', 'amd64'],
'amd64': ['x86_64', 'i386'],
'mips64': ['mips'],
'mips': ['mipsel'],
'mipsel': ['mips'],
'mips64': ['mips', 'mipsel'],
'mips64el': ['mipsel', 'mips'],
'powerpc64': ['powerpc'],
'sparc64': ['sparc'],
'riscv32': ['riscv32', 'riscv64', 'riscv'],
'riscv64': ['riscv64', 'riscv32', 'riscv'],
'riscv32': ['riscv64', 'riscv'],
'riscv64': ['riscv32', 'riscv'],
}.get(arch, [])
# If one of the candidate architectures matches the native
@@ -468,6 +482,7 @@ def cpp(shellcode):
code = _include_header() + shellcode
cmd = [
cpp,
'-Wno-unused-command-line-argument',
'-C',
'-nostdinc',
'-undef',
@@ -758,8 +773,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()
@@ -770,6 +800,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')
@@ -817,6 +871,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])
@@ -830,6 +886,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
+4 -1
View File
@@ -35,7 +35,10 @@ def main(args):
return
for f in files:
e = ELF(f.name)
try:
e = ELF(f.name)
except Exception as e:
print("{name}: {error}".format(name=f.name, error=e))
if __name__ == '__main__':
common.main(__file__, main)
+7
View File
@@ -33,6 +33,13 @@ def main(file=sys.argv[0], command_main=None):
sys.argv.insert(1, name)
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()
+107 -67
View File
@@ -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,56 @@ 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)
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__, main)
+113 -1
View File
@@ -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,112 @@ 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())
log.error("docker failed with status: %d" % e.returncode)
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 +149,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)
+163 -19
View File
@@ -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)
+163 -19
View File
@@ -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)
+34 -8
View File
@@ -359,6 +359,7 @@ class ContextType(object):
'encoding': 'auto',
'endian': 'little',
'gdbinit': "",
'gdb_binary': "",
'kernel': None,
'local_libcdb': "/var/lib/libc-database",
'log_level': logging.INFO,
@@ -594,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:
@@ -664,7 +665,7 @@ class ContextType(object):
information is printed.
>>> with context.verbose: func()
[DEBUG] Hello
[...] Hello
"""
return self.local(log_level='debug')
@@ -1377,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:
@@ -1394,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:
@@ -1401,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
@@ -1451,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
@@ -1528,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.
+163 -19
View File
@@ -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
+163 -19
View File
@@ -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
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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
View File
@@ -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:
+4 -4
View File
@@ -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.
+132 -82
View File
@@ -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)
@@ -1596,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:
@@ -1779,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
@@ -2339,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>`_.
@@ -2374,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>`_.
@@ -2408,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>`_.
+8 -1
View File
@@ -65,7 +65,7 @@ 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:
@@ -78,6 +78,13 @@ def __ensure_memory_to_run_unicorn():
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
+14 -2
View File
@@ -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
View File
@@ -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
+57 -25
View File
@@ -143,7 +143,6 @@ from __future__ import division
import os
import platform
import psutil
import random
import re
import six
@@ -353,10 +352,6 @@ def _gdbserver_args(pid=None, path=None, port=0, gdbserver_args=None, args=None,
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:%d' % port]
gdbserver_args += args
@@ -750,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:
@@ -950,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`
@@ -1034,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
@@ -1251,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
@@ -1494,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)
+199 -86
View File
@@ -8,6 +8,7 @@ import os
import time
import six
import tempfile
import struct
import sys
from pwnlib.context import context
@@ -15,7 +16,7 @@ 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
@@ -24,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/',
]
@@ -38,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""
@@ -59,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
@@ -67,14 +111,14 @@ 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"
url = "{}/api/find".format(LIBC_RIP_URL)
try:
result = requests.post(url, json=params, timeout=20)
result.raise_for_status()
@@ -87,16 +131,17 @@ def query_libc_rip(params):
return None
# 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:
@@ -105,16 +150,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):
@@ -124,12 +170,12 @@ 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
# Offline search https://github.com/niklasb/libc-database for hash type
def provider_local_database(hex_encoded_id, hash_type):
def provider_local_database(search_target, search_type):
if not context.local_libcdb:
return None
@@ -137,9 +183,16 @@ def provider_local_database(hex_encoded_id, hash_type):
if not localdb.is_dir():
return None
log.debug("Searching local libc database, %s: %s", hash_type, hex_encoded_id)
# 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 hex_encoded_id == HASHES[hash_type](libc_path):
if search_target == TYPES[search_type](libc_path):
return read(libc_path)
return None
@@ -186,12 +239,31 @@ PROVIDERS = {
"online": [provider_libcdb, provider_libc_rip]
}
def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True, offline_only=False):
assert hash_type in HASHES, hash_type
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.
@@ -204,12 +276,12 @@ def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True, offline_o
# 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)
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'')
@@ -224,41 +296,7 @@ def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True, offline_o
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.
@@ -271,14 +309,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
@@ -290,7 +328,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)
@@ -316,15 +354,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'):
@@ -342,16 +380,45 @@ def unstrip_libc(filename):
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()
@@ -467,7 +534,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)
@@ -584,7 +653,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, offline_only=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.
@@ -603,12 +672,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.
return_as_list(bool):
Return a list of build ids of all matching libc versions
instead of a path to a 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`.
@@ -627,6 +700,8 @@ def search_by_symbol_offsets(symbols, select_index=None, unstrip=True, return_as
>>> 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)
@@ -662,21 +737,52 @@ def search_by_symbol_offsets(symbols, select_index=None, unstrip=True, return_as
if return_as_list:
return [libc['buildid'] for libc in matching_list]
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_build_id(matching_list[0]['buildid'], unstrip=unstrip, offline_only=offline_only)
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_list):
return search_by_build_id(matching_list[select_index - 1]['buildid'], unstrip=unstrip, offline_only=offline_only)
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_list))
return None
# Handle multiple matches interactively if no index is specified
selected_libc = _handle_multiple_matching_libcs(matching_list)
return search_by_build_id(selected_libc['buildid'], unstrip=unstrip, offline_only=offline_only)
return search_by_hash(selected_libc[mapped_type], search_type=search_type, unstrip=unstrip, offline_only=offline_only)
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):
"""
@@ -820,9 +926,16 @@ def _pack_libs_info(path, libs_id, libs_url, syms):
info["libs_url"] = libs_url
info["download_url"] = ""
for hash_type, hash_func in HASHES.items():
# replace 'build_id' to 'buildid'
info[hash_type.replace("_", "")] = hash_func(path)
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"
@@ -887,4 +1000,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']
+51 -16
View File
@@ -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]))
+4 -4
View File
@@ -116,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'],
+2 -2
View File
@@ -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')}
+2 -5
View File
@@ -58,12 +58,9 @@ Example:
>>> print(shellcraft.i386.mov('eax', 0xdead00ff).rstrip())
mov eax, -0xdead00ff
neg eax
>>> print(shellcraft.i386.mov('eax', 0xc0).rstrip())
xor eax, eax
mov al, 0xc0
>>> print(shellcraft.i386.mov('edi', 0xc0).rstrip())
mov edi, -0xc0
neg edi
xor edi, edi
mov dil, 0xc0
>>> print(shellcraft.i386.mov('eax', 0xc000).rstrip())
xor eax, eax
mov ah, 0xc000 >> 8
+1 -1
View File
@@ -54,7 +54,7 @@ sorted_regs = regsort(reg_context, registers.i386)
% if not sorted_regs:
/* setregs noop */
% else:
% for how, src, dst in regsort(reg_context, registers.i386):
% for how, src, dst in regsort(reg_context, registers.i386, registers.native32):
% if how == 'xchg':
xchg ${src}, ${dst}
% else:
+1 -1
View File
@@ -380,7 +380,7 @@ def readline(_size=-1, prompt='', float=True, priority=10):
from pwnlib.term import term_mode
if not term_mode:
six.print_(prompt, end='', flush=True)
return getattr(sys.stdin, 'buffer', sys.stdin).readline(_size).rstrip(b'\n')
return force_to_bytes(getattr(sys.stdin, 'buffer', sys.stdin).readline(_size)).rstrip(b'\n')
show_suggestions = False
eof = False
if prompt:
+27 -25
View File
@@ -888,8 +888,10 @@ class process(tube):
"""maps() -> [mapping]
Returns a list of process mappings.
A mapping object has the following fields:
addr, address (addr alias), start (addr alias), end, size, perms, path, rss, pss, shared_clean, shared_dirty, private_clean, private_dirty, referenced, anonymous, swap
perms is a permissions object, with the following fields:
read, write, execute, private, shared, string
@@ -917,24 +919,25 @@ class process(tube):
>>> checker_arr == [True] * len(proc_maps) * 5
True
"""
"""
Useful information about this can be found at: https://man7.org/linux/man-pages/man5/proc.5.html
specifically the /proc/pid/maps section.
memory_maps() returns a list of pmmap_ext objects
memory_maps() returns a list of pmmap_ext objects. The definition (from psutil/_pslinux.py) is:
The definition (from psutil/_pslinux.py) is:
pmmap_grouped = namedtuple(
'pmmap_grouped',
['path', 'rss', 'size', 'pss', 'shared_clean', 'shared_dirty',
'private_clean', 'private_dirty', 'referenced', 'anonymous', 'swap'])
pmmap_ext = namedtuple(
'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
.. code-block:: python
pmmap_grouped = namedtuple(
'pmmap_grouped',
['path', 'rss', 'size', 'pss', 'shared_clean', 'shared_dirty',
'private_clean', 'private_dirty', 'referenced', 'anonymous', 'swap'])
pmmap_ext = namedtuple(
'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
Here is an example of a pmmap_ext entry:
.. code-block:: python
pmmap_ext(addr='15555551c000-155555520000', perms='r--p', path='[vvar]', rss=0, size=16384, pss=0, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=0, referenced=0, anonymous=0, swap=0)
"""
@@ -1256,6 +1259,9 @@ class process(tube):
>>> from pwn import *
>>> p = process(['cat'])
>>> p.send(b'meow')
>>> p.recvuntil(b'meow')
b'meow'
>>> libc_size = p.lib_size(p.libc.path)
>>> hex(libc_size) # doctest: +SKIP
'0x1d5000'
@@ -1322,8 +1328,7 @@ class process(tube):
by the process to the address it is loaded at in the process' address
space.
"""
from pwnlib.util.proc import memory_maps
maps_raw = self.poll() is not None and memory_maps(self.pid)
maps_raw = self.poll() is None and self.maps()
if not maps_raw:
import pwnlib.elf.elf
@@ -1332,23 +1337,15 @@ class process(tube):
return pwnlib.elf.elf.ELF(self.executable).maps
# Enumerate all of the libraries actually loaded right now.
maps = {}
libs = {}
for mapping in maps_raw:
path = mapping.path
if os.sep not in path: continue
path = os.path.realpath(path)
if path not in maps:
maps[path]=0
if path not in libs:
libs[path] = mapping.addr
for lib in maps:
path = os.path.realpath(lib)
for mapping in maps_raw:
if mapping.path == path:
address = mapping.addr.split('-')[0]
maps[lib] = int(address, 16)
break
return maps
return libs
@property
def libc(self):
@@ -1361,7 +1358,12 @@ class process(tube):
Example:
>>> p = process("/bin/cat")
>>> p.send(b"meow")
>>> p.recvuntil(b"meow")
b'meow'
>>> libc = p.libc
>>> libc is not None
True
>>> libc # doctest: +SKIP
ELF('/lib64/libc-...so')
>>> p.close()
+2
View File
@@ -96,6 +96,8 @@ class remote(sock):
import ssl as _ssl
ssl_args = ssl_args or {}
if "server_hostname" in ssl_args and sni:
log.error("sni and server_hostname cannot be set at the same time")
ssl_context = ssl_context or _ssl.SSLContext(_ssl.PROTOCOL_TLSv1_2)
if isinstance(sni, str):
ssl_args["server_hostname"] = sni
+1 -1
View File
@@ -127,7 +127,7 @@ class server(sock):
return
self.rhost, self.rport = rhost[:2]
r = remote(self.rhost, self.rport, sock = sock)
r = remote(self.rhost, self.rport, sock = sock, level = self.level)
h.success('Got connection from %s on port %d' % (self.rhost, self.rport))
if callback:
if not blocking:
+11 -3
View File
@@ -450,7 +450,7 @@ class ssh_connecter(sock):
try:
self.sock = parent.transport.open_channel('direct-tcpip', (host, port), ('127.0.0.1', 0))
except Exception as e:
self.exception(e.message)
self.exception(str(e))
raise
try:
@@ -1359,7 +1359,11 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
update(len(data), total)
result = c.wait()
if result != 0:
if result == -1:
self.warn_once("Could not verify success of file download %r, no error code" % (remote))
if result != 0 and result != -1:
h.failure('Could not download file %r (%r)' % (remote, result))
return
@@ -1539,7 +1543,11 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
s.shutdown('send')
data = s.recvall()
result = s.wait()
if result != 0:
if result == -1:
self.warn_once("Could not verify success of file upload %r, no error code" % (remote))
if result != 0 and result != -1:
self.error("Could not upload file %r (%r)\n%s" % (remote, result, data))
def upload_file(self, filename, remote = None):
+227 -46
View File
@@ -21,6 +21,8 @@ from pwnlib.context import context
from pwnlib.log import Logger
from pwnlib.timeout import Timeout
from pwnlib.tubes.buffer import Buffer
from pwnlib.util import fiddling
from pwnlib.util import iters
from pwnlib.util import misc
from pwnlib.util import packing
@@ -44,6 +46,44 @@ class tube(Timeout, Logger):
self._newline = None
atexit.register(self.close)
def _normalize_keepends_drop(self, keepends, drop, drop_default):
'''
>>> t = tube()
>>> t._normalize_keepends_drop(None, None, True)
True
>>> t._normalize_keepends_drop(None, None, False)
False
>>> t._normalize_keepends_drop(None, True, True)
True
>>> t._normalize_keepends_drop(None, True, False)
True
>>> t._normalize_keepends_drop(True, None, True)
False
>>> t._normalize_keepends_drop(True, None, False)
False
>>> t._normalize_keepends_drop(None, False, True)
False
>>> t._normalize_keepends_drop(None, False, False)
False
>>> t._normalize_keepends_drop(False, None, True)
True
>>> t._normalize_keepends_drop(False, None, False)
True
>>> t._normalize_keepends_drop(False, True, False)
Traceback (most recent call last):
...
pwnlib.exception.PwnlibException: 'drop' and 'keepends' arguments cannot be used together.
'''
if keepends is not None:
self.warn_once("'keepends' argument is deprecated. Use 'drop' instead.")
if drop is None and keepends is None:
return drop_default
elif drop is not None:
if keepends is not None:
self.error("'drop' and 'keepends' arguments cannot be used together.")
return drop
return not keepends
@property
def newline(self):
r'''Character sent with methods like sendline() or used for recvline().
@@ -98,7 +138,7 @@ class tube(Timeout, Logger):
>>> t.recv() == b'Woohoo'
True
>>> with context.local(log_level='debug'):
... _ = t.recv() # doctest: +ELLIPSIS
... _ = t.recv()
[...] Received 0xc bytes:
b'Hello, world'
"""
@@ -263,7 +303,7 @@ class tube(Timeout, Logger):
>>> t.recv_raw = lambda *a: time.sleep(0.01) or b'a'
>>> t.recvn(10, timeout=0.05)
b''
>>> t.recvn(10, timeout=0.06) # doctest: +ELLIPSIS
>>> t.recvn(10, timeout=0.06)
b'aaaaaa...'
"""
# Keep track of how much data has been received
@@ -368,8 +408,8 @@ class tube(Timeout, Logger):
return b''
def recvlines(self, numlines=2**20, keepends=False, timeout=default):
r"""recvlines(numlines, keepends=False, timeout=default) -> list of bytes objects
def recvlines(self, numlines=2**20, keepends=None, drop=None, timeout=default):
r"""recvlines(numlines, drop=True, timeout=default) -> list of bytes objects
Receive up to ``numlines`` lines.
@@ -381,7 +421,7 @@ class tube(Timeout, Logger):
Arguments:
numlines(int): Maximum number of lines to receive
keepends(bool): Keep newlines at the end of each line (:const:`False`).
drop(bool): Drop newlines at the end of each line (:const:`True`).
timeout(int): Maximum timeout
Raises:
@@ -402,15 +442,20 @@ class tube(Timeout, Logger):
[b'Foo', b'Bar', b'Baz']
>>> t.recvlines(3, True)
[b'Foo\n', b'Bar\n', b'Baz\n']
>>> t.recvlines(3, drop=False)
[b'Foo\n', b'Bar\n', b'Baz\n']
"""
drop = self._normalize_keepends_drop(keepends, drop, True)
del keepends
lines = []
with self.countdown(timeout):
for _ in range(numlines):
try:
# We must set 'keepends' to True here so that we can
# We must set 'drop' to False here so that we can
# restore the original, unmodified data to the buffer
# in the event of a timeout.
res = self.recvline(keepends=True, timeout=timeout)
res = self.recvline(drop=False, timeout=timeout)
except Exception:
self.unrecv(b''.join(lines))
raise
@@ -420,13 +465,13 @@ class tube(Timeout, Logger):
else:
break
if not keepends:
if drop:
lines = [line.rstrip(self.newline) for line in lines]
return lines
def recvlinesS(self, numlines=2**20, keepends=False, timeout=default):
r"""recvlinesS(numlines, keepends=False, timeout=default) -> str list
def recvlinesS(self, numlines=2**20, keepends=None, drop=None, timeout=default):
r"""recvlinesS(numlines, drop=True, timeout=default) -> str list
This function is identical to :meth:`recvlines`, but decodes
the received bytes into string using :func:`context.encoding`.
@@ -442,10 +487,10 @@ class tube(Timeout, Logger):
>>> t.recvlinesS(3)
['Foo', 'Bar', 'Baz']
"""
return [packing._decode(x) for x in self.recvlines(numlines, keepends, timeout)]
return [packing._decode(x) for x in self.recvlines(numlines, keepends=keepends, drop=drop, timeout=timeout)]
def recvlinesb(self, numlines=2**20, keepends=False, timeout=default):
r"""recvlinesb(numlines, keepends=False, timeout=default) -> bytearray list
def recvlinesb(self, numlines=2**20, keepends=None, drop=None, timeout=default):
r"""recvlinesb(numlines, drop=True, timeout=default) -> bytearray list
This function is identical to :meth:`recvlines`, but returns a bytearray.
@@ -459,10 +504,10 @@ class tube(Timeout, Logger):
>>> t.recvlinesb(3)
[bytearray(b'Foo'), bytearray(b'Bar'), bytearray(b'Baz')]
"""
return [bytearray(x) for x in self.recvlines(numlines, keepends, timeout)]
return [bytearray(x) for x in self.recvlines(numlines, keepends=keepends, drop=drop, timeout=timeout)]
def recvline(self, keepends=True, timeout=default):
r"""recvline(keepends=True, timeout=default) -> bytes
def recvline(self, keepends=None, drop=None, timeout=default):
r"""recvline(drop=False, timeout=default) -> bytes
Receive a single line from the tube.
@@ -478,7 +523,7 @@ class tube(Timeout, Logger):
all data is buffered and an empty byte string (``b''``) is returned.
Arguments:
keepends(bool): Keep the line ending (:const:`True`).
drop(bool): Drop the line ending (:const:`False`).
timeout(int): Timeout
Raises:
@@ -501,10 +546,10 @@ class tube(Timeout, Logger):
b'Foo\n'
>>> t.recvline()
b'Bar\r\n'
>>> t.recvline(keepends = False)
>>> t.recvline(False)
b'Baz'
>>> t.newline = b'\r\n'
>>> t.recvline(keepends = False)
>>> t.recvline(drop=True)
b'Foo\nBar'
>>> t = tube()
>>> def _recv_eof(n):
@@ -518,13 +563,16 @@ class tube(Timeout, Logger):
b'real line\n'
>>> t.recvline()
b'trailing data'
>>> t.recvline() # doctest: +ELLIPSIS
>>> t.recvline()
Traceback (most recent call last):
...
...
EOFError
"""
drop = self._normalize_keepends_drop(keepends, drop, False)
del keepends
try:
return self.recvuntil(self.newline, drop = not keepends, timeout = timeout)
return self.recvuntil(self.newline, drop=drop, timeout=timeout)
except EOFError:
if not context.throw_eof_on_incomplete_line and self.buffer.size > 0:
if context.throw_eof_on_incomplete_line is None:
@@ -532,8 +580,8 @@ class tube(Timeout, Logger):
return self.buffer.get()
raise
def recvline_pred(self, pred, keepends=False, timeout=default):
r"""recvline_pred(pred, keepends=False) -> bytes
def recvline_pred(self, pred, keepends=None, drop=None, timeout=default):
r"""recvline_pred(pred, drop=True, timeout=default) -> bytes
Receive data until ``pred(line)`` returns a truthy value.
Drop all other data.
@@ -544,6 +592,7 @@ class tube(Timeout, Logger):
Arguments:
pred(callable): Function to call. Returns the line for which
this function returns :const:`True`.
drop(bool): Drop the line ending (:const:`True`).
Examples:
@@ -551,18 +600,22 @@ class tube(Timeout, Logger):
>>> t.recv_raw = lambda n: b"Foo\nBar\nBaz\n"
>>> t.recvline_pred(lambda line: line == b"Bar\n")
b'Bar'
>>> t.recvline_pred(lambda line: line == b"Bar\n", keepends=True)
>>> t.recvline_pred(lambda line: line == b"Bar\n", True)
b'Bar\n'
>>> t.recvline_pred(lambda line: line == b"Bar\n", drop=False)
b'Bar\n'
>>> t.recvline_pred(lambda line: line == b'Nope!', timeout=0.1)
b''
"""
drop = self._normalize_keepends_drop(keepends, drop, True)
del keepends
tmpbuf = Buffer()
line = b''
with self.countdown(timeout):
while self.countdown_active():
try:
line = self.recvline(keepends=True)
line = self.recvline(drop=False)
except Exception:
self.buffer.unget(tmpbuf)
raise
@@ -572,22 +625,23 @@ class tube(Timeout, Logger):
return b''
if pred(line):
if not keepends:
line = line[:-len(self.newline)]
if drop:
line = line.rstrip(self.newline)
return line
else:
tmpbuf.add(line)
return b''
def recvline_contains(self, items, keepends = False, timeout = default):
r"""
def recvline_contains(self, items, keepends=None, drop=None, timeout=default):
r"""recvline_contains(items, drop=True, timeout=default) -> bytes
Receive lines until one line is found which contains at least
one of `items`.
Arguments:
items(str,tuple): List of strings to search for, or a single string.
keepends(bool): Return lines with newlines if :const:`True`
drop(bool): Drop the line ending (:const:`True`).
timeout(int): Timeout, in seconds
Examples:
@@ -613,10 +667,10 @@ class tube(Timeout, Logger):
def pred(line):
return any(d in line for d in items)
return self.recvline_pred(pred, keepends, timeout)
return self.recvline_pred(pred, keepends=keepends, drop=drop, timeout=timeout)
def recvline_startswith(self, delims, keepends=False, timeout=default):
r"""recvline_startswith(delims, keepends=False, timeout=default) -> bytes
def recvline_startswith(self, delims, keepends=None, drop=None, timeout=default):
r"""recvline_startswith(delims, drop=True, timeout=default) -> bytes
Keep receiving lines until one is found that starts with one of
`delims`. Returns the last line received.
@@ -626,7 +680,7 @@ class tube(Timeout, Logger):
Arguments:
delims(str,tuple): List of strings to search for, or string of single characters
keepends(bool): Return lines with newlines if :const:`True`
drop(bool): Drop the line ending (:const:`True`).
timeout(int): Timeout, in seconds
Returns:
@@ -638,7 +692,7 @@ class tube(Timeout, Logger):
>>> t.recv_raw = lambda n: b"Hello\nWorld\nXylophone\n"
>>> t.recvline_startswith((b'W',b'X',b'Y',b'Z'))
b'World'
>>> t.recvline_startswith((b'W',b'X',b'Y',b'Z'), True)
>>> t.recvline_startswith((b'W',b'X',b'Y',b'Z'), drop=False)
b'Xylophone\n'
>>> t.recvline_startswith(b'Wo')
b'World'
@@ -650,10 +704,11 @@ class tube(Timeout, Logger):
return self.recvline_pred(lambda line: any(map(line.startswith, delims)),
keepends=keepends,
drop=drop,
timeout=timeout)
def recvline_endswith(self, delims, keepends=False, timeout=default):
r"""recvline_endswith(delims, keepends=False, timeout=default) -> bytes
def recvline_endswith(self, delims, keepends=None, drop=None, timeout=default):
r"""recvline_endswith(delims, drop=True, timeout=default) -> bytes
Keep receiving lines until one is found that ends with one of
`delims`. Returns the last line received.
@@ -669,7 +724,7 @@ class tube(Timeout, Logger):
>>> t.recv_raw = lambda n: b'Foo\nBar\nBaz\nKaboodle\n'
>>> t.recvline_endswith(b'r')
b'Bar'
>>> t.recvline_endswith((b'a',b'b',b'c',b'd',b'e'), True)
>>> t.recvline_endswith((b'a',b'b',b'c',b'd',b'e'), drop=False)
b'Kaboodle\n'
>>> t.recvline_endswith(b'oodle')
b'Kaboodle'
@@ -682,6 +737,7 @@ class tube(Timeout, Logger):
return self.recvline_pred(lambda line: any(map(line.endswith, delims)),
keepends=keepends,
drop=drop,
timeout=timeout)
def recvregex(self, regex, exact=False, timeout=default, capture=False):
@@ -724,8 +780,8 @@ class tube(Timeout, Logger):
else:
return self.recvpred(pred, timeout = timeout)
def recvline_regex(self, regex, exact=False, keepends=False, timeout=default):
"""recvline_regex(regex, exact=False, keepends=False, timeout=default) -> bytes
def recvline_regex(self, regex, exact=False, keepends=None, drop=None, timeout=default):
"""recvline_regex(regex, exact=False, drop=True, timeout=default) -> bytes
Wrapper around :func:`recvline_pred`, which will return when a regex
matches a line.
@@ -746,7 +802,7 @@ class tube(Timeout, Logger):
else:
pred = regex.search
return self.recvline_pred(pred, keepends = keepends, timeout = timeout)
return self.recvline_pred(pred, keepends=keepends, drop=drop, timeout=timeout)
def recvrepeat(self, timeout=default):
"""recvrepeat(timeout=default) -> bytes
@@ -1062,8 +1118,8 @@ class tube(Timeout, Logger):
>>> t.connected_raw = lambda d: True
>>> t.fileno = lambda: 1234
>>> with context.local(log_level='info'):
... data = t.clean_and_log() #doctest: +ELLIPSIS
[DEBUG] Received 0xb bytes:
... data = t.clean_and_log()
[...] Received 0xb bytes:
b'hooray_data'
>>> data
b'hooray_data'
@@ -1077,6 +1133,131 @@ class tube(Timeout, Logger):
with context.local(log_level='debug'):
return cached_data + self.clean(timeout)
def upload_manually(self, data, target_path = './payload', prompt = b'$', chunk_size = 0x200, chmod_flags = 'u+x', compression='auto', end_marker = 'PWNTOOLS_DONE'):
"""upload_manually(data, target_path = './payload', prompt = b'$', chunk_size = 0x200, chmod_flags = 'u+x', compression='auto', end_marker = 'PWNTOOLS_DONE')
Upload a file manually using base64 encoding and compression.
This can be used when the tube is connected to a shell.
The file is uploaded in base64-encoded chunks by appending to a file
and then decompressing it:
.. code-block::
loop:
echo <chunk> | base64 -d >> <target_path>.<compression>
<compression> -d -f <target_path>.<compression>
chmod <chmod_flags> <target_path>
It is assumed that a `base64` command is available on the target system.
When ``compression`` is ``auto`` the best compression utility available
between ``gzip`` and ``xz`` is chosen with a fallback to uncompressed
upload.
Arguments:
data(bytes): The data to upload.
target_path(str): The path to upload the data to.
prompt(bytes): The shell prompt to wait for.
chunk_size(int): The size of each chunk to upload.
chmod_flags(str): The flags to use with chmod. ``""`` to ignore.
compression(str): The compression to use. ``auto`` to automatically choose the best compression or ``gzip`` or ``xz``.
end_marker(str): The marker to use to detect the end of the output. Only used when prompt is not set.
Examples:
>>> l = listen()
>>> l.spawn_process('/bin/sh')
>>> r = remote('127.0.0.1', l.lport)
>>> r.upload_manually(b'some\\xca\\xfedata\\n', prompt=b'', chmod_flags='')
>>> r.sendline(b'cat ./payload')
>>> r.recvline()
b'some\\xca\\xfedata\\n'
>>> r.upload_manually(cyclic(0x1000), target_path='./cyclic_pattern', prompt=b'', chunk_size=0x10, compression='gzip')
>>> r.sendline(b'sha256sum ./cyclic_pattern')
>>> r.recvlineS(keepends=False).startswith(sha256sumhex(cyclic(0x1000)))
True
>>> blob = ELF.from_assembly(shellcraft.echo('Hello world!\\n') + shellcraft.exit(0))
>>> r.upload_manually(blob.data, prompt=b'')
>>> r.sendline(b'./payload')
>>> r.recvline()
b'Hello world!\\n'
>>> r.close()
>>> l.close()
"""
echo_end = ""
if not prompt:
echo_end = "; echo {}".format(end_marker)
end_markerb = end_marker.encode()
else:
end_markerb = prompt
# Detect available compression utility, fallback to uncompressed upload.
compression_mode = None
possible_compression = ['gzip']
if six.PY3:
possible_compression.insert(0, 'xz')
if not prompt:
self.sendline("echo {}".format(end_marker).encode())
if compression == 'auto':
for utility in possible_compression:
self.sendlineafter(end_markerb, "command -v {} && echo YEP || echo NOPE{}".format(utility, echo_end).encode())
result = self.recvuntil([b'YEP', b'NOPE'])
if b'YEP' in result:
compression_mode = utility
break
elif compression in possible_compression:
compression_mode = compression
else:
self.error('Invalid compression mode: %s, has to be one of %s', compression, possible_compression)
self.debug('Manually uploading using compression mode: %s', compression_mode)
compressed_data = b''
if compression_mode == 'xz':
import lzma
compressed_data = lzma.compress(data, format=lzma.FORMAT_XZ, preset=9)
compressed_path = target_path + '.xz'
elif compression_mode == 'gzip':
import gzip
from six import BytesIO
f = BytesIO()
with gzip.GzipFile(fileobj=f, mode='wb', compresslevel=9) as g:
g.write(data)
compressed_data = f.getvalue()
compressed_path = target_path + '.gz'
else:
compressed_path = target_path
# Don't compress if it doesn't reduce the size.
if len(compressed_data) >= len(data):
compression_mode = None
compressed_path = target_path
else:
data = compressed_data
# Upload data in `chunk_size` chunks. Assume base64 is available.
with self.progress('Uploading payload') as p:
for idx, chunk in enumerate(iters.group(chunk_size, data)):
if None in chunk:
chunk = chunk[:chunk.index(None)]
if idx == 0:
self.sendlineafter(end_markerb, "echo {} | base64 -d > {}{}".format(fiddling.b64e(bytearray(chunk)), compressed_path, echo_end).encode())
else:
self.sendlineafter(end_markerb, "echo {} | base64 -d >> {}{}".format(fiddling.b64e(bytearray(chunk)), compressed_path, echo_end).encode())
p.status('{}/{} {}'.format(idx+1, len(data)//chunk_size+1, misc.size(idx*chunk_size + len(chunk))))
p.success(misc.size(len(data)))
# Decompress the file and set the permissions.
if compression_mode is not None:
self.sendlineafter(end_markerb, '{} -d -f {}{}'.format(compression_mode, compressed_path, echo_end).encode())
if chmod_flags:
self.sendlineafter(end_markerb, 'chmod {} {}{}'.format(chmod_flags, target_path, echo_end).encode())
if not prompt:
self.recvuntil(end_markerb + b'\n')
def connect_input(self, other):
"""connect_input(other)
@@ -1313,7 +1494,7 @@ class tube(Timeout, Logger):
send
send
send
>>> t.shutdown('bad_value') #doctest: +ELLIPSIS
>>> t.shutdown('bad_value')
Traceback (most recent call last):
...
KeyError: "direction must be in ['in', 'out', 'read', 'recv', 'send', 'write']"
@@ -1347,7 +1528,7 @@ class tube(Timeout, Logger):
send
send
send
>>> t.connected('bad_value') #doctest: +ELLIPSIS
>>> t.connected('bad_value')
Traceback (most recent call last):
...
KeyError: "direction must be in ['any', 'in', 'out', 'read', 'recv', 'send', 'write']"
+42 -5
View File
@@ -13,11 +13,13 @@ import subprocess
import sys
import tempfile
import inspect
import time
import types
from pwnlib import atexit
from pwnlib.context import context
from pwnlib.log import getLogger
from pwnlib.timeout import Timeout
from pwnlib.util import fiddling
from pwnlib.util import lists
from pwnlib.util import packing
@@ -368,13 +370,13 @@ def run_in_new_terminal(command, terminal=None, args=None, kill_at_exit=True, pr
terminal = 'cmd.exe'
args = ['/c', 'start']
distro_name = os.getenv('WSL_DISTRO_NAME')
current_dir = os.getcwd()
# Split pane in Windows Terminal
if 'WT_SESSION' in os.environ and which('wt.exe'):
args.extend(['wt.exe', '-w', '0', 'split-pane', '-d', '.'])
args.extend(['wt.exe', '-w', '0', 'split-pane'])
if distro_name:
args.extend(['wsl.exe', '-d', distro_name, 'bash', '-c'])
args.extend(['wsl.exe', '-d', distro_name, '--cd', current_dir, 'bash', '-c'])
else:
args.extend(['bash.exe', '-c'])
@@ -439,15 +441,22 @@ end tell
tmp.flush()
os.chmod(tmp.name, 0o700)
argv = [which(terminal), tmp.name]
# cmd.exe does not support WSL UNC paths as working directory
# so it gets reset to %WINDIR% before starting wsl again.
# Set the working directory correctly in WSL.
elif terminal == 'cmd.exe':
argv[-1] = "cd '{}' && {}".format(os.getcwd(), argv[-1])
log.debug("Launching a new terminal: %r" % argv)
stdin = stdout = stderr = open(os.devnull, 'r+b')
if terminal == 'tmux':
if terminal == 'tmux' or terminal == 'kitty':
stdout = subprocess.PIPE
p = subprocess.Popen(argv, stdin=stdin, stdout=stdout, stderr=stderr, preexec_fn=preexec_fn)
kittyid = None
if terminal == 'tmux':
out, _ = p.communicate()
try:
@@ -460,14 +469,42 @@ end tell
with subprocess.Popen((qdbus, konsole_dbus_service, '/Sessions/{}'.format(last_konsole_session),
'org.kde.konsole.Session.processId'), stdout=subprocess.PIPE) as proc:
pid = int(proc.communicate()[0].decode())
elif terminal == 'kitty':
pid = p.pid
out, _ = p.communicate()
try:
kittyid = int(out)
except ValueError:
kittyid = None
if kittyid is None:
log.error("Could not parse kitty window ID from output (%r)", out)
elif terminal == 'cmd.exe':
# p.pid is cmd.exe's pid instead of the WSL process we want to start eventually.
# I don't know how to trace the execution through Windows and back into the WSL2 VM.
# Do a best guess by waiting for a new process matching the command to be run.
# Otherwise it's better to return nothing instead of a know wrong pid.
from pwnlib.util.proc import pid_by_name
pid = None
ran_program = command.split(' ')[0] if isinstance(command, six.string_types) else command[0]
t = Timeout()
with t.countdown(timeout=5):
while t.timeout:
new_pid = pid_by_name(ran_program)
if new_pid and new_pid[0] > p.pid:
pid = new_pid[0]
break
time.sleep(0.01)
else:
pid = p.pid
if kill_at_exit:
if kill_at_exit and pid:
def kill():
try:
if terminal == 'qdbus':
os.kill(pid, signal.SIGHUP)
elif terminal == 'kitty':
subprocess.Popen(["kitten", "@", "close-window", "--match", "id:{}".format(kittyid)], stderr=stderr)
else:
os.kill(pid, signal.SIGTERM)
except OSError:
+6 -6
View File
@@ -259,17 +259,17 @@ def sock_match(local, remote, fam=socket.AF_UNSPEC, typ=0):
infos |= set(socket.getaddrinfo(sockaddr[0], sockaddr[1], socket.AF_INET6, t, proto, socket.AI_V4MAPPED))
return infos
if local is not None:
local = sockinfos(local, fam, typ)
remote = sockinfos(remote, fam, typ)
local = sockinfos(local, fam, typ)
if remote is not None:
remote = sockinfos(remote, fam, typ)
def match(c):
laddrs = sockinfos(c.laddr, c.family, c.type)
raddrs = sockinfos(c.raddr, c.family, c.type)
if not (raddrs & remote):
if not (laddrs & local):
return False
if local is None:
if remote is None:
return True
return bool(laddrs & local)
return bool(raddrs & remote)
return match
+11 -1
View File
@@ -988,6 +988,11 @@ def dd(dst, src, count = 0, skip = 0, seek = 0, truncate = False):
('H', 'e', 'l', 'l', 'o', b'?')
>>> dd(list('Hello!'), (63,), skip = 5)
['H', 'e', 'l', 'l', 'o', b'?']
>>> buf = bytearray(b'Hello!')
>>> dd(buf, b'?', skip = 5)
bytearray(b'Hello?')
>>> buf
bytearray(b'Hello?')
>>> _ = open('/tmp/foo', 'w').write('A' * 10)
>>> dd(open('/tmp/foo'), open('/dev/zero'), skip = 3, count = 4).read()
'AAA\\x00\\x00\\x00\\x00AAA'
@@ -1105,7 +1110,12 @@ def dd(dst, src, count = 0, skip = 0, seek = 0, truncate = False):
dst = real_dst
elif isinstance(dst, (list, bytearray)):
dst[skip : skip + len(src)] = list(map(p8, bytearray(src)))
# A bytearray slice takes a byte string, while a list slice takes the
# single-byte bytes objects that p8() returns.
if isinstance(dst, bytearray):
dst[skip : skip + len(src)] = src
else:
dst[skip : skip + len(src)] = list(map(p8, bytearray(src)))
if truncate:
while len(dst) > truncate:
dst.pop()
+13 -4
View File
@@ -27,6 +27,11 @@ def pidof(target):
- :class:`pwnlib.tubes.sock.sock`: singleton list of the PID at the
remote end of `target` if it is running on the host. Otherwise an
empty list.
- :class:`pwnlib.tubes.ssh.ssh_channel`: singleton list of the PID of
`target` on the remote system.
- :class:`tuple`: singleton list of the PID at the local end of the
connection to `target` if it is running on the host. Otherwise an
empty list.
Arguments:
target(object): The target whose PID(s) to find.
@@ -38,7 +43,7 @@ def pidof(target):
>>> l = tubes.listen.listen()
>>> p = process(['curl', '-s', 'http://127.0.0.1:%d'%l.lport])
>>> pidof(p) == pidof(l) == pidof(('127.0.0.1', l.lport))
>>> pidof(p) == pidof(l) == pidof(('127.0.0.1', l.rport))
True
"""
if isinstance(target, tubes.ssh.ssh_channel):
@@ -51,7 +56,7 @@ def pidof(target):
return [c.pid for c in psutil.net_connections() if match(c)]
elif isinstance(target, tuple):
match = sock_match(None, target)
match = sock_match(target, None)
return [c.pid for c in psutil.net_connections() if match(c)]
elif isinstance(target, tubes.process.process):
@@ -82,6 +87,8 @@ def pid_by_name(name):
try:
if p.exe() == name:
return True
if p.cmdline()[0] == name:
return True
except Exception:
pass
return False
@@ -398,7 +405,7 @@ def wait_for_debugger(pid, debugger_pid=None):
pid (int): PID of the process.
Returns:
None
The PID of the debugger that attached to the process.
"""
t = Timeout()
with t.countdown(timeout=15):
@@ -416,9 +423,11 @@ def wait_for_debugger(pid, debugger_pid=None):
else:
time.sleep(0.01)
if tracer(pid):
tracer_pid = tracer(pid)
if tracer_pid:
l.success()
elif debugger_pid == 0:
l.failure("debugger exited! (maybe check /proc/sys/kernel/yama/ptrace_scope)")
else:
l.failure('Debugger did not attach to pid %d within 15 seconds', pid)
return tracer_pid
+1 -1
View File
@@ -1 +1 @@
__version__ = '4.14.1'
__version__ = '4.15.0'
+1 -1
View File
@@ -50,7 +50,7 @@ dependencies = [
"psutil>=3.3.0",
"intervaltree>=3.0",
"sortedcontainers",
"unicorn>=2.0.1, !=2.1.3",
"unicorn>=2.0.1",
"six>=1.12.0",
"rpyc",
"colored_traceback<0.4; python_version < '3'",
+27 -4
View File
@@ -31,14 +31,38 @@ if flag in sys.argv:
else:
flag = False
DEPRECATED_SCRIPTS= [
'asm',
# 'checksec',
# 'constgrep',
'cyclic',
'debug',
'disablenx',
'disasm',
'elfdiff',
'elfpatch',
'errno',
'hex',
# 'libcdb',
# 'phd',
# 'pwnstrip',
'scramble',
# 'shellcraft',
'template',
'unhex',
]
for filename in glob.glob('pwnlib/commandline/*'):
filename = os.path.basename(filename)
filename, ext = os.path.splitext(filename)
if ext != '.py' or '__init__' in filename:
if ext != '.py' or filename in ('__init__', 'common', 'main', 'update', 'version'):
continue
script = '%s=pwnlib.commandline.common:main' % filename
if filename in DEPRECATED_SCRIPTS:
script = '%s=pwnlib.commandline.common:deprecated_main' % filename
else:
script = '%s=pwnlib.commandline.common:main' % filename
if not flag:
console_scripts.append(script)
@@ -63,7 +87,7 @@ if not os.path.exists(PythonH):
sys.exit(-1)
setup(
version = '4.14.1',
version = '4.15.0',
data_files = [('pwntools-doc',
glob.glob('*.md') + glob.glob('*.txt')),
],
@@ -78,6 +102,5 @@ setup(
] + templates,
},
entry_points = {'console_scripts': console_scripts},
scripts = glob.glob("bin/*"),
**compat
)
+86
View File
@@ -0,0 +1,86 @@
events {
worker_connections 1024;
}
http {
proxy_cache_path /var/cache/nginx keys_zone=my_cache:1m max_size=1g inactive=12w use_temp_path=off;
log_format cache_st '$remote_addr - $remote_user - $upstream_cache_status [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log /dev/stdout cache_st;
server {
listen 3000;
proxy_cache my_cache;
location / {
proxy_set_header Host debuginfod.elfutils.org;
proxy_ssl_server_name on;
proxy_cache_revalidate on;
proxy_cache_key $scheme://$host$uri$is_args$query_string;
proxy_cache_valid 200 404 12w;
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504 http_429;
proxy_pass https://debuginfod.elfutils.org/;
}
}
server {
listen 3001;
proxy_cache my_cache;
location / {
proxy_set_header Host libc.rip;
proxy_ssl_server_name on;
proxy_cache_methods GET HEAD POST;
proxy_cache_revalidate on;
proxy_cache_key $scheme://$host$uri$is_args$query_string$request_body;
proxy_cache_valid 200 404 12w;
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504 http_429;
proxy_pass https://libc.rip/;
}
}
server {
listen 3002;
proxy_cache my_cache;
location / {
proxy_set_header Host archive.ubuntu.com;
proxy_cache_revalidate on;
proxy_cache_key $scheme://$host$uri$is_args$query_string;
proxy_cache_valid 200 404 12w;
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504 http_429;
proxy_pass http://archive.ubuntu.com/;
}
}
server {
listen 3003;
proxy_cache my_cache;
location / {
proxy_set_header Host gitlab.com;
proxy_ssl_server_name on;
proxy_cache_revalidate on;
proxy_cache_key $scheme://$host$uri$is_args$query_string;
proxy_cache_valid 200 404 12w;
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504 http_429;
proxy_pass https://gitlab.com/;
}
}
server {
listen 3004;
proxy_cache my_cache;
location / {
proxy_set_header Host debuginfod.ubuntu.com;
proxy_ssl_server_name on;
proxy_cache_revalidate on;
proxy_cache_key $scheme://$host$uri$is_args$query_string;
proxy_cache_valid 200 404 12w;
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504 http_429;
proxy_pass https://debuginfod.ubuntu.com/;
}
}
}