mirror of
https://github.com/hugsy/gef.git
synced 2026-10-11 21:49:56 +00:00
[Maintenance] Remove unmaintained commands, tests, and documentation, and moved to Ruff (#1222)
## Description This PR - removes unmaintained `shellcode` commands, tests, and documentation - (finally) switches to Ruff instead of Pylint (still handled by `pre-commit`) - fixes a few ruff/ty-found issues
This commit is contained in:
+17
-15
@@ -2,24 +2,26 @@ default_stages: [pre-commit, pre-push]
|
||||
fail_fast: false
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
rev: v6.0.0
|
||||
hooks:
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
|
||||
- repo: https://github.com/pycqa/pylint
|
||||
rev: v3.0.0a6
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.15.2
|
||||
hooks:
|
||||
- id: pylint
|
||||
- id: ruff-check
|
||||
args: [ --fix ]
|
||||
- id: ruff-format
|
||||
|
||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||
rev: v0.35.0
|
||||
rev: v0.48.0
|
||||
hooks:
|
||||
- id: markdownlint-docker
|
||||
args:
|
||||
- --config=docs/.markdownlint.yaml
|
||||
- --ignore=docs/api/gef.md
|
||||
- --ignore=docs/obsolete/docs/index.md
|
||||
- --ignore=docs/index.md
|
||||
- --ignore=README.md
|
||||
- "docs/**/*.md"
|
||||
- id: markdownlint-docker
|
||||
args:
|
||||
- --config=docs/.markdownlint.yaml
|
||||
- --ignore=docs/api/gef.md
|
||||
- --ignore=docs/obsolete/docs/index.md
|
||||
- --ignore=docs/index.md
|
||||
- --ignore=README.md
|
||||
- "docs/**/*.md"
|
||||
|
||||
@@ -1,904 +0,0 @@
|
||||
[MASTER]
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code.
|
||||
extension-pkg-allow-list=
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code. (This is an alternative name to extension-pkg-allow-list
|
||||
# for backward compatibility.)
|
||||
extension-pkg-whitelist=
|
||||
|
||||
# Return non-zero exit code if any of these messages/categories are detected,
|
||||
# even if score is above --fail-under value. Syntax same as enable. Messages
|
||||
# specified are enabled, while categories only check already-enabled messages.
|
||||
fail-on=
|
||||
|
||||
# Specify a score threshold to be exceeded before program exits with error.
|
||||
fail-under=10.0
|
||||
|
||||
# Files or directories to be skipped. They should be base names, not paths.
|
||||
ignore=CVS
|
||||
|
||||
# Add files or directories matching the regex patterns to the ignore-list. The
|
||||
# regex matches against paths and can be in Posix or Windows format.
|
||||
ignore-paths=
|
||||
|
||||
# Files or directories matching the regex patterns are skipped. The regex
|
||||
# matches against base names, not paths.
|
||||
ignore-patterns=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
#init-hook=
|
||||
|
||||
# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
|
||||
# number of processors available to use.
|
||||
jobs=0
|
||||
|
||||
# Control the amount of potential inferred values when inferring a single
|
||||
# object. This can help the performance when dealing with large functions or
|
||||
# complex, nested conditions.
|
||||
limit-inference-results=100
|
||||
|
||||
# List of plugins (as comma separated values of python module names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# Minimum Python version to use for version dependent checks. Will default to
|
||||
# the version used to run pylint.
|
||||
py-version=3.10
|
||||
|
||||
# When enabled, pylint would attempt to guess common misconfiguration and emit
|
||||
# user-friendly hints instead of false-positive error messages.
|
||||
suggestion-mode=yes
|
||||
|
||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||
# active Python interpreter and may run arbitrary code.
|
||||
unsafe-load-any-extension=no
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
|
||||
confidence=
|
||||
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
# option multiple times (only on the command line, not in the configuration
|
||||
# file where it should appear only once). You can also use "--disable=all" to
|
||||
# disable everything first and then reenable specific checks. For example, if
|
||||
# you want to run only the similarities checker, you can use "--disable=all
|
||||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use "--disable=all --enable=classes
|
||||
# --disable=W".
|
||||
; disable=invalid-name,
|
||||
; disallowed-name,
|
||||
; empty-docstring,
|
||||
; missing-module-docstring,
|
||||
; missing-class-docstring,
|
||||
; missing-function-docstring,
|
||||
; unidiomatic-typecheck,
|
||||
; non-ascii-name,
|
||||
; consider-using-enumerate,
|
||||
; consider-iterating-dictionary,
|
||||
; bad-classmethod-argument,
|
||||
; bad-mcs-method-argument,
|
||||
; bad-mcs-classmethod-argument,
|
||||
; single-string-used-for-slots,
|
||||
; consider-using-dict-items,
|
||||
; use-maxsplit-arg,
|
||||
; use-sequence-for-iteration,
|
||||
; too-many-lines,
|
||||
; missing-final-newline,
|
||||
; trailing-newlines,
|
||||
; superfluous-parens,
|
||||
; mixed-line-endings,
|
||||
; unexpected-line-ending-format,
|
||||
; wrong-spelling-in-comment,
|
||||
; wrong-spelling-in-docstring,
|
||||
; invalid-characters-in-docstring,
|
||||
; multiple-imports,
|
||||
; wrong-import-order,
|
||||
; ungrouped-imports,
|
||||
; wrong-import-position,
|
||||
; useless-import-alias,
|
||||
; import-outside-toplevel,
|
||||
; use-implicit-booleaness-not-len,
|
||||
; use-implicit-booleaness-not-comparison,
|
||||
; raw-checker-failed,
|
||||
; bad-inline-option,
|
||||
; locally-disabled,
|
||||
; file-ignored,
|
||||
; suppressed-message,
|
||||
; useless-suppression,
|
||||
; deprecated-pragma,
|
||||
; use-symbolic-message-instead,
|
||||
; c-extension-no-member,
|
||||
; literal-comparison,
|
||||
; comparison-with-itself,
|
||||
; no-self-use,
|
||||
; no-classmethod-decorator,
|
||||
; no-staticmethod-decorator,
|
||||
; useless-object-inheritance,
|
||||
; property-with-parameters,
|
||||
; cyclic-import,
|
||||
; consider-using-from-import,
|
||||
; duplicate-code,
|
||||
; too-many-ancestors,
|
||||
; too-many-instance-attributes,
|
||||
; too-few-public-methods,
|
||||
; too-many-public-methods,
|
||||
; too-many-return-statements,
|
||||
; too-many-branches,
|
||||
; too-many-arguments,
|
||||
; too-many-locals,
|
||||
; too-many-statements,
|
||||
; too-many-boolean-expressions,
|
||||
; consider-merging-isinstance,
|
||||
; too-many-nested-blocks,
|
||||
; simplifiable-if-statement,
|
||||
; redefined-argument-from-local,
|
||||
; no-else-return,
|
||||
; consider-using-ternary,
|
||||
; trailing-comma-tuple,
|
||||
; stop-iteration-return,
|
||||
; simplify-boolean-expression,
|
||||
; inconsistent-return-statements,
|
||||
; useless-return,
|
||||
; consider-swap-variables,
|
||||
; consider-using-join,
|
||||
; consider-using-in,
|
||||
; consider-using-get,
|
||||
; chained-comparison,
|
||||
; consider-using-dict-comprehension,
|
||||
; consider-using-set-comprehension,
|
||||
; simplifiable-if-expression,
|
||||
; no-else-raise,
|
||||
; unnecessary-comprehension,
|
||||
; consider-using-sys-exit,
|
||||
; no-else-break,
|
||||
; no-else-continue,
|
||||
; super-with-arguments,
|
||||
; simplifiable-condition,
|
||||
; condition-evals-to-constant,
|
||||
; consider-using-generator,
|
||||
; use-a-generator,
|
||||
; consider-using-min-builtin,
|
||||
; consider-using-max-builtin,
|
||||
; consider-using-with,
|
||||
; unnecessary-dict-index-lookup,
|
||||
; use-list-literal,
|
||||
; use-dict-literal,
|
||||
; pointless-statement,
|
||||
; pointless-string-statement,
|
||||
; expression-not-assigned,
|
||||
; unnecessary-pass,
|
||||
; unnecessary-lambda,
|
||||
; assign-to-new-keyword,
|
||||
; useless-else-on-loop,
|
||||
; exec-used,
|
||||
; eval-used,
|
||||
; confusing-with-statement,
|
||||
; using-constant-test,
|
||||
; missing-parentheses-for-call-in-test,
|
||||
; self-assigning-variable,
|
||||
; redeclared-assigned-name,
|
||||
; assert-on-string-literal,
|
||||
; comparison-with-callable,
|
||||
; lost-exception,
|
||||
; nan-comparison,
|
||||
; assert-on-tuple,
|
||||
; attribute-defined-outside-init,
|
||||
; bad-staticmethod-argument,
|
||||
; protected-access,
|
||||
; arguments-differ,
|
||||
; signature-differs,
|
||||
; abstract-method,
|
||||
; super-init-not-called,
|
||||
; no-init,
|
||||
; non-parent-init-called,
|
||||
; useless-super-delegation,
|
||||
; invalid-overridden-method,
|
||||
; arguments-renamed,
|
||||
; unused-private-member,
|
||||
; overridden-final-method,
|
||||
; subclassed-final-class,
|
||||
; bad-indentation,
|
||||
; wildcard-import,
|
||||
; deprecated-module,
|
||||
; reimported,
|
||||
; import-self,
|
||||
; preferred-module,
|
||||
; misplaced-future,
|
||||
; fixme,
|
||||
; global-variable-undefined,
|
||||
; global-statement,
|
||||
; global-at-module-level,
|
||||
; unused-argument,
|
||||
; unused-wildcard-import,
|
||||
; redefined-outer-name,
|
||||
; redefined-builtin,
|
||||
; undefined-loop-variable,
|
||||
; unbalanced-tuple-unpacking,
|
||||
; cell-var-from-loop,
|
||||
; possibly-unused-variable,
|
||||
; self-cls-assignment,
|
||||
; bare-except,
|
||||
; broad-except,
|
||||
; duplicate-except,
|
||||
; try-except-raise,
|
||||
; raise-missing-from,
|
||||
; raising-format-tuple,
|
||||
; wrong-exception-operation,
|
||||
; keyword-arg-before-vararg,
|
||||
; arguments-out-of-order,
|
||||
; non-str-assignment-to-dunder-name,
|
||||
; isinstance-second-argument-not-valid-type,
|
||||
; logging-not-lazy,
|
||||
; logging-format-interpolation,
|
||||
; logging-fstring-interpolation,
|
||||
; bad-format-string-key,
|
||||
; unused-format-string-key,
|
||||
; missing-format-argument-key,
|
||||
; unused-format-string-argument,
|
||||
; format-combined-specification,
|
||||
; missing-format-attribute,
|
||||
; invalid-format-index,
|
||||
; duplicate-string-formatting-argument,
|
||||
; f-string-without-interpolation,
|
||||
; useless-with-lock
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once). See also the "--disable" option for examples.
|
||||
; enable=unneeded-not,
|
||||
; format-string-without-interpolation,
|
||||
; anomalous-unicode-escape-in-string,
|
||||
; implicit-str-concat,
|
||||
; inconsistent-quotes,
|
||||
; redundant-u-string-prefix,
|
||||
; boolean-datetime,
|
||||
; redundant-unittest-assert,
|
||||
; deprecated-method,
|
||||
; bad-thread-instantiation,
|
||||
; shallow-copy-environ,
|
||||
; invalid-envvar-default,
|
||||
; subprocess-popen-preexec-fn,
|
||||
; subprocess-run-check,
|
||||
; deprecated-argument,
|
||||
; deprecated-class,
|
||||
; deprecated-decorator,
|
||||
; unspecified-encoding,
|
||||
; forgotten-debug-statement,
|
||||
; using-f-string-in-unsupported-version,
|
||||
; using-final-decorator-in-unsupported-version,
|
||||
; singleton-comparison,
|
||||
; consider-using-f-string,
|
||||
; line-too-long,
|
||||
; trailing-whitespace,
|
||||
; multiple-statements,
|
||||
; syntax-error,
|
||||
; unrecognized-inline-option,
|
||||
; bad-option-value,
|
||||
; bad-plugin-value,
|
||||
; bad-configuration-section,
|
||||
; init-is-generator,
|
||||
; return-in-init,
|
||||
; function-redefined,
|
||||
; not-in-loop,
|
||||
; return-outside-function,
|
||||
; yield-outside-function,
|
||||
; return-arg-in-generator,
|
||||
; nonexistent-operator,
|
||||
; duplicate-argument-name,
|
||||
; abstract-class-instantiated,
|
||||
; bad-reversed-sequence,
|
||||
; too-many-star-expressions,
|
||||
; invalid-star-assignment-target,
|
||||
; star-needs-assignment-target,
|
||||
; nonlocal-and-global,
|
||||
; continue-in-finally,
|
||||
; nonlocal-without-binding,
|
||||
; used-prior-global-declaration,
|
||||
; misplaced-format-function,
|
||||
; method-hidden,
|
||||
; access-member-before-definition,
|
||||
; no-method-argument,
|
||||
; no-self-argument,
|
||||
; invalid-slots-object,
|
||||
; assigning-non-slot,
|
||||
; invalid-slots,
|
||||
; inherit-non-class,
|
||||
; inconsistent-mro,
|
||||
; duplicate-bases,
|
||||
; class-variable-slots-conflict,
|
||||
; invalid-class-object,
|
||||
; non-iterator-returned,
|
||||
; unexpected-special-method-signature,
|
||||
; invalid-length-returned,
|
||||
; invalid-bool-returned,
|
||||
; invalid-index-returned,
|
||||
; invalid-repr-returned,
|
||||
; invalid-str-returned,
|
||||
; invalid-bytes-returned,
|
||||
; invalid-hash-returned,
|
||||
; invalid-length-hint-returned,
|
||||
; invalid-format-returned,
|
||||
; invalid-getnewargs-returned,
|
||||
; invalid-getnewargs-ex-returned,
|
||||
; import-error,
|
||||
; relative-beyond-top-level,
|
||||
; used-before-assignment,
|
||||
; undefined-variable,
|
||||
; undefined-all-variable,
|
||||
; invalid-all-object,
|
||||
; invalid-all-format,
|
||||
; no-name-in-module,
|
||||
; unpacking-non-sequence,
|
||||
; bad-except-order,
|
||||
; raising-bad-type,
|
||||
; bad-exception-context,
|
||||
; misplaced-bare-raise,
|
||||
; raising-non-exception,
|
||||
; notimplemented-raised,
|
||||
; catching-non-exception,
|
||||
; bad-super-call,
|
||||
; no-member,
|
||||
; not-callable,
|
||||
; assignment-from-no-return,
|
||||
; no-value-for-parameter,
|
||||
; too-many-function-args,
|
||||
; unexpected-keyword-arg,
|
||||
; redundant-keyword-arg,
|
||||
; missing-kwoa,
|
||||
; invalid-sequence-index,
|
||||
; invalid-slice-index,
|
||||
; assignment-from-none,
|
||||
; not-context-manager,
|
||||
; invalid-unary-operand-type,
|
||||
; unsupported-binary-operation,
|
||||
; repeated-keyword,
|
||||
; not-an-iterable,
|
||||
; not-a-mapping,
|
||||
; unsupported-membership-test,
|
||||
; unsubscriptable-object,
|
||||
; unsupported-assignment-operation,
|
||||
; unsupported-delete-operation,
|
||||
; invalid-metaclass,
|
||||
; unhashable-dict-key,
|
||||
; dict-iter-missing-items,
|
||||
; await-outside-async,
|
||||
; logging-unsupported-format,
|
||||
; logging-format-truncated,
|
||||
; logging-too-many-args,
|
||||
; logging-too-few-args,
|
||||
; bad-format-character,
|
||||
; truncated-format-string,
|
||||
; mixed-format-string,
|
||||
; format-needs-mapping,
|
||||
; missing-format-string-key,
|
||||
; too-many-format-args,
|
||||
; too-few-format-args,
|
||||
; bad-string-format-type,
|
||||
; bad-str-strip-call,
|
||||
; invalid-envvar-value,
|
||||
; yield-inside-async-function,
|
||||
; not-async-context-manager,
|
||||
; fatal,
|
||||
; astroid-error,
|
||||
; parse-error,
|
||||
; config-parse-error,
|
||||
; method-check-failed,
|
||||
; unreachable,
|
||||
; dangerous-default-value,
|
||||
; duplicate-key,
|
||||
; unnecessary-semicolon,
|
||||
; global-variable-not-assigned,
|
||||
; unused-import,
|
||||
; unused-variable,
|
||||
; binary-op-exception,
|
||||
; bad-format-string,
|
||||
; anomalous-backslash-in-string,
|
||||
; bad-open-mode
|
||||
|
||||
enable =
|
||||
F,
|
||||
E,
|
||||
anomalous-backslash-in-string,
|
||||
bad-format-string,
|
||||
bad-open-mode,
|
||||
consider-using-f-string,
|
||||
dangerous-default-value,
|
||||
duplicate-key,
|
||||
global-variable-not-assigned
|
||||
line-too-long,
|
||||
singleton-comparison,
|
||||
trailing-whitespace,
|
||||
unnecessary-semicolon,
|
||||
unneeded-not,
|
||||
unreachable,
|
||||
unused-import,
|
||||
unused-variable,
|
||||
binary-op-exception
|
||||
disable = all
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Python expression which should return a score less than or equal to 10. You
|
||||
# have access to the variables 'error', 'warning', 'refactor', and 'convention'
|
||||
# which contain the number of messages in each category, as well as 'statement'
|
||||
# which is the total number of statements analyzed. This score is used by the
|
||||
# global evaluation report (RP0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Template used to display messages. This is a python new-style format string
|
||||
# used to format the message information. See doc for all details.
|
||||
#msg-template=
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, json
|
||||
# and msvs (visual studio). You can also give a reporter class, e.g.
|
||||
# mypackage.mymodule.MyReporterClass.
|
||||
output-format=text
|
||||
|
||||
# Tells whether to display a full report or only the messages.
|
||||
reports=no
|
||||
|
||||
# Activate the evaluation score.
|
||||
score=yes
|
||||
|
||||
|
||||
[REFACTORING]
|
||||
|
||||
# Maximum number of nested blocks for function / method body
|
||||
max-nested-blocks=5
|
||||
|
||||
# Complete name of functions that never returns. When checking for
|
||||
# inconsistent-return-statements if a never returning function is called then
|
||||
# it will be considered as an explicit return statement and no message will be
|
||||
# printed.
|
||||
never-returning-functions=sys.exit,argparse.parse_error
|
||||
|
||||
|
||||
[FORMAT]
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
expected-line-ending-format=LF
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||
|
||||
# Number of spaces of indent required inside a hanging or continued line.
|
||||
indent-after-paren=4
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string=' '
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=200
|
||||
|
||||
# Maximum number of lines in a module.
|
||||
max-module-lines=15000
|
||||
|
||||
# Allow the body of a class to be on the same line as the declaration if body
|
||||
# contains single statement.
|
||||
single-line-class-stmt=no
|
||||
|
||||
# Allow the body of an if to be on the same line as the test if there is no
|
||||
# else.
|
||||
single-line-if-stmt=no
|
||||
|
||||
|
||||
[SPELLING]
|
||||
|
||||
# Limits count of emitted suggestions for spelling mistakes.
|
||||
max-spelling-suggestions=4
|
||||
|
||||
# Spelling dictionary name. Available dictionaries: none. To make it work,
|
||||
# install the 'python-enchant' package.
|
||||
spelling-dict=
|
||||
|
||||
# List of comma separated words that should be considered directives if they
|
||||
# appear and the beginning of a comment and should not be checked.
|
||||
spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:
|
||||
|
||||
# List of comma separated words that should not be checked.
|
||||
spelling-ignore-words=
|
||||
|
||||
# A path to a file that contains the private dictionary; one word per line.
|
||||
spelling-private-dict-file=
|
||||
|
||||
# Tells whether to store unknown words to the private dictionary (see the
|
||||
# --spelling-private-dict-file option) instead of raising a message.
|
||||
spelling-store-unknown-words=no
|
||||
|
||||
|
||||
[LOGGING]
|
||||
|
||||
# The type of string formatting that logging methods do. `old` means using %
|
||||
# formatting, `new` is for `{}` formatting.
|
||||
logging-format-style=old
|
||||
|
||||
# Logging modules to check that the string format arguments are in logging
|
||||
# function parameter format.
|
||||
logging-modules=logging
|
||||
|
||||
|
||||
[VARIABLES]
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid defining new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
# Tells whether unused global variables should be treated as a violation.
|
||||
allow-global-unused-variables=yes
|
||||
|
||||
# List of names allowed to shadow builtins
|
||||
allowed-redefined-builtins=
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
callbacks=cb_,
|
||||
_cb
|
||||
|
||||
# A regular expression matching the name of dummy variables (i.e. expected to
|
||||
# not be used).
|
||||
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
||||
|
||||
# Argument names that match this expression will be ignored. Default to name
|
||||
# with leading underscore.
|
||||
ignored-argument-names=_.*|^ignored_|^unused_
|
||||
|
||||
# Tells whether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# List of qualified module names which can have objects that can redefine
|
||||
# builtins.
|
||||
redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Comments are removed from the similarity computation
|
||||
ignore-comments=yes
|
||||
|
||||
# Docstrings are removed from the similarity computation
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Imports are removed from the similarity computation
|
||||
ignore-imports=no
|
||||
|
||||
# Signatures are removed from the similarity computation
|
||||
ignore-signatures=no
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=4
|
||||
|
||||
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=FIXME,
|
||||
XXX,
|
||||
TODO
|
||||
|
||||
# Regular expression of note tags to take in consideration.
|
||||
#notes-rgx=
|
||||
|
||||
|
||||
[BASIC]
|
||||
|
||||
# Naming style matching correct argument names.
|
||||
argument-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct argument names. Overrides argument-
|
||||
# naming-style.
|
||||
#argument-rgx=
|
||||
|
||||
# Naming style matching correct attribute names.
|
||||
attr-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct attribute names. Overrides attr-naming-
|
||||
# style.
|
||||
#attr-rgx=
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma.
|
||||
bad-names=foo,
|
||||
bar,
|
||||
baz,
|
||||
toto,
|
||||
tutu,
|
||||
tata
|
||||
|
||||
# Bad variable names regexes, separated by a comma. If names match any regex,
|
||||
# they will always be refused
|
||||
bad-names-rgxs=
|
||||
|
||||
# Naming style matching correct class attribute names.
|
||||
class-attribute-naming-style=any
|
||||
|
||||
# Regular expression matching correct class attribute names. Overrides class-
|
||||
# attribute-naming-style.
|
||||
#class-attribute-rgx=
|
||||
|
||||
# Naming style matching correct class constant names.
|
||||
class-const-naming-style=UPPER_CASE
|
||||
|
||||
# Regular expression matching correct class constant names. Overrides class-
|
||||
# const-naming-style.
|
||||
#class-const-rgx=
|
||||
|
||||
# Naming style matching correct class names.
|
||||
class-naming-style=PascalCase
|
||||
|
||||
# Regular expression matching correct class names. Overrides class-naming-
|
||||
# style.
|
||||
#class-rgx=
|
||||
|
||||
# Naming style matching correct constant names.
|
||||
const-naming-style=UPPER_CASE
|
||||
|
||||
# Regular expression matching correct constant names. Overrides const-naming-
|
||||
# style.
|
||||
#const-rgx=
|
||||
|
||||
# Minimum line length for functions/classes that require docstrings, shorter
|
||||
# ones are exempt.
|
||||
docstring-min-length=-1
|
||||
|
||||
# Naming style matching correct function names.
|
||||
function-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct function names. Overrides function-
|
||||
# naming-style.
|
||||
#function-rgx=
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma.
|
||||
good-names=i,
|
||||
j,
|
||||
k,
|
||||
ex,
|
||||
Run,
|
||||
_
|
||||
|
||||
# Good variable names regexes, separated by a comma. If names match any regex,
|
||||
# they will always be accepted
|
||||
good-names-rgxs=
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name.
|
||||
include-naming-hint=no
|
||||
|
||||
# Naming style matching correct inline iteration names.
|
||||
inlinevar-naming-style=any
|
||||
|
||||
# Regular expression matching correct inline iteration names. Overrides
|
||||
# inlinevar-naming-style.
|
||||
#inlinevar-rgx=
|
||||
|
||||
# Naming style matching correct method names.
|
||||
method-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct method names. Overrides method-naming-
|
||||
# style.
|
||||
#method-rgx=
|
||||
|
||||
# Naming style matching correct module names.
|
||||
module-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct module names. Overrides module-naming-
|
||||
# style.
|
||||
#module-rgx=
|
||||
|
||||
# Colon-delimited sets of names that determine each other's naming style when
|
||||
# the name regexes allow several styles.
|
||||
name-group=
|
||||
|
||||
# Regular expression which should only match function or class names that do
|
||||
# not require a docstring.
|
||||
no-docstring-rgx=^_
|
||||
|
||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
||||
# to this list to register other decorators that produce valid properties.
|
||||
# These decorators are taken in consideration only for invalid-name.
|
||||
property-classes=abc.abstractproperty
|
||||
|
||||
# Naming style matching correct variable names.
|
||||
variable-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct variable names. Overrides variable-
|
||||
# naming-style.
|
||||
#variable-rgx=
|
||||
|
||||
|
||||
[STRING]
|
||||
|
||||
# This flag controls whether inconsistent-quotes generates a warning when the
|
||||
# character used as a quote delimiter is used inconsistently within a module.
|
||||
check-quote-consistency=no
|
||||
|
||||
# This flag controls whether the implicit-str-concat should generate a warning
|
||||
# on implicit string concatenation in sequences defined over several lines.
|
||||
check-str-concat-over-line-jumps=no
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# List of decorators that produce context managers, such as
|
||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
||||
# produce valid context managers.
|
||||
contextmanager-decorators=contextlib.contextmanager
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||
# expressions are accepted.
|
||||
generated-members=
|
||||
|
||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||
# class is considered mixin if its name matches the mixin-class-rgx option.
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# Tells whether to warn about missing members when the owner of the attribute
|
||||
# is inferred to be None.
|
||||
ignore-none=yes
|
||||
|
||||
# This flag controls whether pylint should warn about no-member and similar
|
||||
# checks whenever an opaque object is returned when inferring. The inference
|
||||
# can return multiple potential results while evaluating a Python object, but
|
||||
# some branches might not be evaluated, which results in partial inference. In
|
||||
# that case, it might be useful to still emit no-member and other checks for
|
||||
# the rest of the inferred objects.
|
||||
ignore-on-opaque-inference=yes
|
||||
|
||||
# List of class names for which member attributes should not be checked (useful
|
||||
# for classes with dynamically set attributes). This supports the use of
|
||||
# qualified names.
|
||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
||||
|
||||
# List of module names for which member attributes should not be checked
|
||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||
# and thus existing member attributes cannot be deduced by static analysis). It
|
||||
# supports qualified module names, as well as Unix pattern matching.
|
||||
ignored-modules=
|
||||
|
||||
# Show a hint with possible names when a member name was not found. The aspect
|
||||
# of finding the hint is based on edit distance.
|
||||
missing-member-hint=yes
|
||||
|
||||
# The minimum edit distance a name should have in order to be considered a
|
||||
# similar match for a missing member name.
|
||||
missing-member-hint-distance=1
|
||||
|
||||
# The total number of similar names that should be taken in consideration when
|
||||
# showing a hint for a missing member.
|
||||
missing-member-max-choices=1
|
||||
|
||||
# Regex pattern to define which classes are considered mixins ignore-mixin-
|
||||
# members is set to 'yes'
|
||||
mixin-class-rgx=.*[Mm]ixin
|
||||
|
||||
# List of decorators that change the signature of a decorated function.
|
||||
signature-mutators=
|
||||
|
||||
|
||||
[IMPORTS]
|
||||
|
||||
# List of modules that can be imported at any level, not just the top level
|
||||
# one.
|
||||
allow-any-import-level=
|
||||
|
||||
# Allow wildcard imports from modules that define __all__.
|
||||
allow-wildcard-with-all=no
|
||||
|
||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
||||
# 3 compatible code, which means that the block might have code that exists
|
||||
# only in one or another interpreter, leading to false positives when analysed.
|
||||
analyse-fallback-blocks=no
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma.
|
||||
deprecated-modules=
|
||||
|
||||
# Output a graph (.gv or any supported image format) of external dependencies
|
||||
# to the given file (report RP0402 must not be disabled).
|
||||
ext-import-graph=
|
||||
|
||||
# Output a graph (.gv or any supported image format) of all (i.e. internal and
|
||||
# external) dependencies to the given file (report RP0402 must not be
|
||||
# disabled).
|
||||
import-graph=
|
||||
|
||||
# Output a graph (.gv or any supported image format) of internal dependencies
|
||||
# to the given file (report RP0402 must not be disabled).
|
||||
int-import-graph=
|
||||
|
||||
# Force import order to recognize a module as part of the standard
|
||||
# compatibility libraries.
|
||||
known-standard-library=
|
||||
|
||||
# Force import order to recognize a module as part of a third party library.
|
||||
known-third-party=enchant
|
||||
|
||||
# Couples of modules and preferred modules, separated by a comma.
|
||||
preferred-modules=
|
||||
|
||||
|
||||
[DESIGN]
|
||||
|
||||
# List of regular expressions of class ancestor names to ignore when counting
|
||||
# public methods (see R0903)
|
||||
exclude-too-few-public-methods=
|
||||
|
||||
# List of qualified class names to ignore when counting class parents (see
|
||||
# R0901)
|
||||
ignored-parents=
|
||||
|
||||
# Maximum number of arguments for function / method.
|
||||
max-args=5
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
max-attributes=7
|
||||
|
||||
# Maximum number of boolean expressions in an if statement (see R0916).
|
||||
max-bool-expr=5
|
||||
|
||||
# Maximum number of branch for function / method body.
|
||||
max-branches=12
|
||||
|
||||
# Maximum number of locals for function / method body.
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
# Maximum number of return / yield for function / method body.
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of statements in function / method body.
|
||||
max-statements=50
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=2
|
||||
|
||||
|
||||
[CLASSES]
|
||||
|
||||
# Warn about protected attribute access inside special methods
|
||||
check-protected-access-in-special-methods=no
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,
|
||||
__new__,
|
||||
setUp,
|
||||
__post_init__
|
||||
|
||||
# List of member names, which should be excluded from the protected access
|
||||
# warning.
|
||||
exclude-protected=_asdict,
|
||||
_fields,
|
||||
_replace,
|
||||
_source,
|
||||
_make
|
||||
|
||||
# List of valid names for the first argument in a class method.
|
||||
valid-classmethod-first-arg=cls
|
||||
|
||||
# List of valid names for the first argument in a metaclass class method.
|
||||
valid-metaclass-classmethod-first-arg=cls
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
||||
# Exceptions that will emit a warning when being caught. Defaults to
|
||||
# "BaseException, Exception".
|
||||
overgeneral-exceptions=BaseException,
|
||||
Exception
|
||||
@@ -3,7 +3,9 @@
|
||||
As long as the 'memory' section is enabled in your context layout (which it is by default), you can
|
||||
register addresses, lengths, and grouping size.
|
||||
|
||||

|
||||
<!-- markdownlint-disable MD013,MD034 -->
|
||||

|
||||
<!-- markdownlint-enable MD013,MD034 -->
|
||||
|
||||
_Note_: this command **should NOT** be mistaken with the [GDB `watch`
|
||||
command](https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Watchpoints.html) meant to set
|
||||
@@ -23,9 +25,10 @@ If the format specified is `pointers`, then the output will be similar to execut
|
||||
`dereference $address`. For all other format, the output will be an hexdump of the designated
|
||||
location.
|
||||
|
||||
Note that the address format is a GDB therefore a symbol can be passed to it. It also supports [GEF
|
||||
functions
|
||||
format](https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html)
|
||||
Note that the address format is a GDB therefore a symbol can be passed to it. It also supports
|
||||
<!-- markdownlint-disable MD013 -->
|
||||
[GEF functions format](https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html)
|
||||
<!-- markdownlint-enable MD013 -->
|
||||
allowing to easily track commonly used addresses:
|
||||
|
||||
For example, to watch the first 5 entries of the [GOT](https://hugsy.github.io/gef/functions/got/)
|
||||
@@ -37,8 +40,9 @@ gef ➤ memory watch $_got()+0x18 5
|
||||
```
|
||||
|
||||
Which, when the `context` is displayed, will show something like:
|
||||
|
||||
<!-- markdownlint-disable MD013 -->
|
||||

|
||||
<!-- markdownlint-enable MD013 -->
|
||||
|
||||
### Removing a watch
|
||||
|
||||
|
||||
@@ -120,8 +120,10 @@ For a full demo, watch the following tutorial:
|
||||
|
||||
Additionally, if you have successfully configured your IDA settings, you can also directly import
|
||||
the structure(s) that was(were) reverse-engineered in IDA directly in your GDB session:
|
||||
 - (see `gef-extras/ida-rpyc`,
|
||||
which is the new improved version of `ida-interact`)
|
||||
<!-- markdownlint-disable MD013 -->
|
||||

|
||||
<!-- markdownlint-enable MD013 -->
|
||||
(see `gef-extras/ida-rpyc`, which is the new improved version of `ida-interact`)
|
||||
|
||||
#### Dynamic `ctypes.Structure`-like classes
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
## Command `shellcode`
|
||||
|
||||
`shellcode` is a command line client for @JonathanSalwan shellcodes database. It can be used to
|
||||
search and download directly via `GEF` the shellcode you're looking for. Two primitive subcommands
|
||||
are available, `search` and `get`
|
||||
|
||||
```text
|
||||
gef➤ shellcode search arm
|
||||
[+] Showing matching shellcodes
|
||||
901 Linux/ARM Add map in /etc/hosts file - 79 bytes
|
||||
853 Linux/ARM chmod("/etc/passwd", 0777) - 39 bytes
|
||||
854 Linux/ARM creat("/root/pwned", 0777) - 39 bytes
|
||||
855 Linux/ARM execve("/bin/sh", [], [0 vars]) - 35 bytes
|
||||
729 Linux/ARM Bind Connect UDP Port 68
|
||||
730 Linux/ARM Bindshell port 0x1337
|
||||
[...]
|
||||
gef➤ shellcode get 698
|
||||
[+] Downloading shellcode id=698
|
||||
[+] Shellcode written as '/tmp/sc-EfcWtM.txt'
|
||||
gef➤ system cat /tmp/sc-EfcWtM.txt
|
||||
/*
|
||||
Title: Linux/ARM - execve("/bin/sh", [0], [0 vars]) - 27 bytes
|
||||
Date: 2010-09-05
|
||||
Tested on: ARM926EJ-S rev 5 (v5l)
|
||||
Author: Jonathan Salwan - twitter: @jonathansalwan
|
||||
|
||||
shell-storm.org
|
||||
|
||||
Shellcode ARM without 0x20, 0x0a and 0x00
|
||||
[...]
|
||||
```
|
||||
@@ -23,8 +23,12 @@ Patching `fork()` calls:
|
||||
|
||||
* Without stub:
|
||||
|
||||

|
||||
<!-- markdownlint-disable MD013,MD034 -->
|
||||

|
||||
<!-- markdownlint-enable MD013,MD034 -->
|
||||
|
||||
* With stub:
|
||||
|
||||

|
||||
<!-- markdownlint-disable MD013,MD034 -->
|
||||

|
||||
<!-- markdownlint-enable MD013,MD034 -->
|
||||
|
||||
@@ -16,6 +16,7 @@ page aims to track those changes.
|
||||
| `windbg` | Moved | [a933a5a](https://github.com/hugsy/gef-extras/commit/a933a5ac43933742d91f4e299eadf05e3e0670be) | [New location](https://github.com/hugsy/gef-extras/blob/main/scripts/windbg.py) | |
|
||||
| `is-syscall` | Moved | [3f79fb38](https://github.com/hugsy/gef-extras/commit/3f79fb382aa9052d073698d40237f98982c5d2de) | [New location](https://github.com/hugsy/gef-extras/blob/main/scripts/syscall_args) | |
|
||||
| `syscall-args` | Moved | [3f79fb38](https://github.com/hugsy/gef-extras/commit/3f79fb382aa9052d073698d40237f98982c5d2de) | [New location](https://github.com/hugsy/gef-extras/blob/main/scripts/syscall_args) | |
|
||||
| `shellcode` | Removed | 2026.06 | N/A | Reason: `http://shell-storm.org` not active |
|
||||
|
||||
## Removed support for pyenv
|
||||
|
||||
|
||||
+1
-1
@@ -138,7 +138,7 @@ cases, the following command is enough:
|
||||
|
||||
```bash
|
||||
cd /root/of/gef
|
||||
python3 -m pylint --rcfile .pylintrc
|
||||
ruff check ./gef.py [other/python/file/added/modified]
|
||||
```
|
||||
|
||||
Note that to ensure compatibility, tests must be executed with the same Python version GDB was
|
||||
|
||||
-27506
File diff suppressed because it is too large
Load Diff
@@ -61,7 +61,6 @@ nav:
|
||||
- reset-cache: commands/reset-cache.md
|
||||
- scan: commands/scan.md
|
||||
- search-pattern: commands/search-pattern.md
|
||||
- shellcode: commands/shellcode.md
|
||||
- stub: commands/stub.md
|
||||
- stepover: commands/stepover.md
|
||||
- skipi: commands/skipi.md
|
||||
|
||||
+99
-49
@@ -12,24 +12,25 @@ from https://github.com/settings/tokens/new).
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import requests
|
||||
import subprocess
|
||||
import os
|
||||
import pathlib
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
__author__ = "@_hugsy_"
|
||||
__version__ = 0.1
|
||||
__licence__ = "MIT"
|
||||
__file__ = "new-release.py"
|
||||
__desc__ = "Generate a new release for a Github project."
|
||||
__usage__ = f"""{__file__} v{__version__}\nby {__author__} under {__licence__}\nsyntax: {__file__} [options] args"""
|
||||
import requests
|
||||
|
||||
__author__ = "@_hugsy_"
|
||||
__version__ = 0.1
|
||||
__licence__ = "MIT"
|
||||
__file__ = "new-release.py"
|
||||
__desc__ = "Generate a new release for a Github project."
|
||||
__usage__ = f"""{__file__} v{__version__}\nby {__author__} under {__licence__}\nsyntax: {__file__} [options] args"""
|
||||
|
||||
|
||||
REPOSITORY = "hugsy/gef"
|
||||
GITHUB_TOKEN = os.getenv("GITHUB_REPO_TOKEN")
|
||||
DEBUG = False
|
||||
OUTPUT_FILE = pathlib.Path( tempfile.gettempdir() ) / "CHANGELOG.md"
|
||||
REPOSITORY = "hugsy/gef"
|
||||
GITHUB_TOKEN = os.getenv("GITHUB_REPO_TOKEN")
|
||||
DEBUG = False
|
||||
OUTPUT_FILE = pathlib.Path(tempfile.gettempdir()) / "CHANGELOG.md"
|
||||
GITHUB_NEW_TOKEN_URL = "https://github.com/settings/personal-access-tokens/new"
|
||||
|
||||
|
||||
@@ -49,36 +50,42 @@ def generate_changelog(args: argparse.Namespace) -> bool:
|
||||
latest_tag = shell("git describe --tags --abbrev=0")
|
||||
|
||||
print(f"Creating changelog for {args.version} in {args.output_file.name}")
|
||||
args.output_file.write(f"# Changelog: {args.version} - {args.codename}{os.linesep}{os.linesep}")
|
||||
content = f"# Changelog: {args.version} - {args.codename}{os.linesep}{os.linesep}"
|
||||
|
||||
dbg("Adding commit summary...")
|
||||
args.output_file.write(f"## Highlights of `{args.codename}`{os.linesep}{os.linesep}")
|
||||
args.output_file.write(f"{os.linesep}{os.linesep}")
|
||||
content += f"## Highlights of `{args.codename}`{os.linesep}{os.linesep}"
|
||||
content += f"{os.linesep}{os.linesep}"
|
||||
|
||||
dbg("Adding contributor summary...")
|
||||
args.output_file.write(f"## Contributors{os.linesep}{os.linesep}")
|
||||
contributor_names = shell(f"git log {latest_tag}..HEAD --pretty=format:'%aN' | sort -u").splitlines()
|
||||
content += f"## Contributors{os.linesep}{os.linesep}"
|
||||
contributor_names = shell(
|
||||
f"git log {latest_tag}..HEAD --pretty=format:'%aN' | sort -u"
|
||||
).splitlines()
|
||||
commits = {}
|
||||
for author in contributor_names:
|
||||
author_commits = shell(f'git log {latest_tag}..HEAD --pretty=format:"%h" --author="{author}"').splitlines()
|
||||
commits[ author ] = len(author_commits)
|
||||
author_commits = shell(
|
||||
f'git log {latest_tag}..HEAD --pretty=format:"%h" --author="{author}"'
|
||||
).splitlines()
|
||||
commits[author] = len(author_commits)
|
||||
total_commits = sum(commits.values())
|
||||
|
||||
args.output_file.write(f"| Author | Number of commits | {os.linesep}")
|
||||
args.output_file.write(f"|:--|--:| {os.linesep}")
|
||||
content += f"| Author | Number of commits | {os.linesep}"
|
||||
content += f"|:--|--:| {os.linesep}"
|
||||
commits_sorted = dict(sorted(commits.items(), key=lambda item: -item[1]))
|
||||
for author in commits_sorted:
|
||||
args.output_file.write(f"| {author} | {commits[author]}|{os.linesep}")
|
||||
args.output_file.write(f"{os.linesep}{os.linesep}")
|
||||
content += f"| {author} | {commits[author]}|{os.linesep}"
|
||||
content += f"{os.linesep}{os.linesep}"
|
||||
|
||||
dbg("Adding Github info...")
|
||||
url = f"https://api.github.com/repos/{args.repository}/issues?state=closed&milestone.title=Release%3a%20{args.version}"
|
||||
js = requests.get(url, headers={"Authorization": f"token {args.token}"}).json()
|
||||
prs = { x['number']: x['html_url'] for x in js if "pull" in x['html_url'] }
|
||||
issues = { x['number']: x['html_url'] for x in js if "issues" in x['html_url'] }
|
||||
prs = {x["number"]: x["html_url"] for x in js if "pull" in x["html_url"]}
|
||||
issues = {x["number"]: x["html_url"] for x in js if "issues" in x["html_url"]}
|
||||
closed_prs_item = " • ".join([f" [{nb}]({url}) " for nb, url in prs.items()])
|
||||
closed_issues_item = " • ".join([f" [{nb}]({url}) " for nb, url in issues.items()])
|
||||
args.output_file.write(f"""
|
||||
closed_issues_item = " • ".join(
|
||||
[f" [{nb}]({url}) " for nb, url in issues.items()]
|
||||
)
|
||||
content += f"""
|
||||
## Closed Issues
|
||||
|
||||
* {len(issues)} issues closed ({closed_issues_item})
|
||||
@@ -88,12 +95,14 @@ def generate_changelog(args: argparse.Namespace) -> bool:
|
||||
|
||||
* {len(prs)} PRs closed ({closed_prs_item})
|
||||
|
||||
""")
|
||||
"""
|
||||
|
||||
dbg("Adding commit summary...")
|
||||
log = shell(f"""git log {latest_tag}..HEAD --pretty=format:' * %cs [%h](https://github.com/{args.repository}/commit/%H) • *%aN* • %s ' --reverse""")
|
||||
log = shell(
|
||||
f"""git log {latest_tag}..HEAD --pretty=format:' * %cs [%h](https://github.com/{args.repository}/commit/%H) • *%aN* • %s ' --reverse"""
|
||||
)
|
||||
diff = shell(f"""git diff --no-color --stat {latest_tag}..HEAD""")
|
||||
args.output_file.write(f"""
|
||||
content += f"""
|
||||
## Commit details
|
||||
|
||||
<details>
|
||||
@@ -113,11 +122,14 @@ def generate_changelog(args: argparse.Namespace) -> bool:
|
||||
|
||||
</details>
|
||||
|
||||
""")
|
||||
"""
|
||||
args.output_file.write_text(content)
|
||||
print(f"Done, the changelog file was written to `{args.output_file.name}`")
|
||||
|
||||
if args.push_release:
|
||||
shell(f"""git tag --annotate "{args.version}" --message "Release {args.version} - {args.codename}" --sign""")
|
||||
shell(
|
||||
f"""git tag --annotate "{args.version}" --message "Release {args.version} - {args.codename}" --sign"""
|
||||
)
|
||||
shell(f"""git push origin "{args.version}" """)
|
||||
|
||||
return True
|
||||
@@ -128,32 +140,70 @@ def test_token(args) -> bool:
|
||||
req = requests.get(url, headers={"Authorization": f"token {args.token}"})
|
||||
if req.status_code != 200:
|
||||
print(f"test_token(): return HTTP code {req.status_code}")
|
||||
print(f"Get a token from {GITHUB_NEW_TOKEN_URL} with 'Read-Only' privilege on Issues for the {args.repository} repository")
|
||||
print(
|
||||
f"Get a token from {GITHUB_NEW_TOKEN_URL} with 'Read-Only' privilege on Issues for the {args.repository} repository"
|
||||
)
|
||||
return req.status_code == 200
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(usage = __usage__, description = __desc__, prog = __file__)
|
||||
parser.add_argument("--debug", action="store_true", default=DEBUG,
|
||||
help="Enable debug output")
|
||||
parser.add_argument("-r", "--repository", type=str, default=REPOSITORY,
|
||||
help="Specify the repository (default: '%(default)s')")
|
||||
parser.add_argument("-t", "--token", dest="token", type=str, metavar="TOKEN",
|
||||
default=GITHUB_TOKEN, help="Specify the Github token to use (requires `repo` scope)")
|
||||
parser.add_argument("-o", "--output-file", type=argparse.FileType('w', encoding='UTF-8'), default=open(str(OUTPUT_FILE.absolute()), 'w'),
|
||||
metavar="/path/to/output_file.md", help=f"Specify the output file (default: '{OUTPUT_FILE}')")
|
||||
parser.add_argument("--version", type=str, default=datetime.date.today().strftime("%Y.%m"),
|
||||
help="Specify the version number (default: '%(default)s')")
|
||||
parser.add_argument("--codename", type=str, default=shell("random-word").title(),
|
||||
help="Specify the version codename (default: '%(default)s')")
|
||||
parser.add_argument("--push-release", action="store_true", default=False,
|
||||
help="Create the new tag and publish the release on Github")
|
||||
parser = argparse.ArgumentParser(
|
||||
usage=__usage__, description=__desc__, prog=__file__
|
||||
)
|
||||
parser.add_argument(
|
||||
"--debug", action="store_true", default=DEBUG, help="Enable debug output"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-r",
|
||||
"--repository",
|
||||
type=str,
|
||||
default=REPOSITORY,
|
||||
help="Specify the repository (default: '%(default)s')",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--token",
|
||||
dest="token",
|
||||
type=str,
|
||||
metavar="TOKEN",
|
||||
default=GITHUB_TOKEN,
|
||||
help="Specify the Github token to use (requires `repo` scope)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output-file",
|
||||
type=pathlib.Path,
|
||||
default=OUTPUT_FILE.absolute(),
|
||||
metavar="/path/to/output_file.md",
|
||||
help=f"Specify the output file (default: '{OUTPUT_FILE}')",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--version",
|
||||
type=str,
|
||||
default=datetime.date.today().strftime("%Y.%m"),
|
||||
help="Specify the version number (default: '%(default)s')",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--codename",
|
||||
type=str,
|
||||
default="GENERATE_ME",
|
||||
help="Specify the version codename (default: '%(default)s')",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--push-release",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Create the new tag and publish the release on Github",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
DEBUG = args.debug
|
||||
|
||||
if args.codename == "GENERATE_ME":
|
||||
args.codename = shell("random-word").title()
|
||||
|
||||
if not test_token(args):
|
||||
dbg(f"The GITHUB_TOKEN is not valid")
|
||||
dbg("The GITHUB_TOKEN is not valid")
|
||||
exit(1)
|
||||
|
||||
generate_changelog(args)
|
||||
|
||||
@@ -19,15 +19,16 @@ class RemoteDebugService(rpyc.Service):
|
||||
def exposed_eval(self, cmd):
|
||||
return eval(cmd)
|
||||
|
||||
exposed_gdb = gdb
|
||||
exposed_gdb = gdb # noqa: F821
|
||||
|
||||
exposed_gef = gef
|
||||
exposed_gef = gef # noqa: F821
|
||||
|
||||
|
||||
def start_rpyc_service(port: int = RPYC_PORT):
|
||||
logging.info(f"RPYC service listening on tcp/{port}")
|
||||
def start_rpyc_service(port: int = RPYC_PORT, bind_host: str = "127.0.0.1"):
|
||||
logging.info(f"RPYC service listening on {bind_host}:tcp/{port}")
|
||||
svc = rpyc.utils.server.OneShotServer(
|
||||
RemoteDebugService,
|
||||
hostname=bind_host,
|
||||
port=port,
|
||||
protocol_config={
|
||||
"allow_public_attrs": True,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
test module for deprecated functions
|
||||
"""
|
||||
|
||||
|
||||
import pytest
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import WARNING_DEPRECATION_MESSAGE
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`gef.arch` test module.
|
||||
"""
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
+19
-20
@@ -2,14 +2,16 @@
|
||||
`gef.heap` test module.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import random
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ARCH, debug_target, is_64b
|
||||
|
||||
TCACHE_BINS = 64
|
||||
|
||||
|
||||
class GefHeapApi(RemoteGefUnitTestGeneric):
|
||||
"""`gef.heap` test module."""
|
||||
|
||||
@@ -17,24 +19,25 @@ class GefHeapApi(RemoteGefUnitTestGeneric):
|
||||
self._target = debug_target("heap")
|
||||
return super().setUp()
|
||||
|
||||
# from https://elixir.bootlin.com/glibc/latest/source/malloc/malloc.c#L326
|
||||
# With rounding and alignment, the bins are...
|
||||
# idx 0 bytes 0..24 (64-bit) or 0..12 (32-bit)
|
||||
# idx 1 bytes 25..40 or 13..20
|
||||
# idx 2 bytes 41..56 or 21..28
|
||||
# etc.
|
||||
# from https://elixir.bootlin.com/glibc/latest/source/malloc/malloc.c#L326
|
||||
# With rounding and alignment, the bins are...
|
||||
# idx 0 bytes 0..24 (64-bit) or 0..12 (32-bit)
|
||||
# idx 1 bytes 25..40 or 13..20
|
||||
# idx 2 bytes 41..56 or 21..28
|
||||
# etc.
|
||||
# fmt: off
|
||||
valid_sizes_32b = [16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
|
||||
128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216,
|
||||
224, 232, 240, 248, 256, 264, 272, 280, 288, 296, 304, 312, 320,
|
||||
328, 336, 344, 352, 360, 368, 376, 384, 392, 400, 408, 416, 424,
|
||||
432, 440, 448, 456, 464, 472, 480, 488, 496, 504, 512, 520, ]
|
||||
128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216,
|
||||
224, 232, 240, 248, 256, 264, 272, 280, 288, 296, 304, 312, 320,
|
||||
328, 336, 344, 352, 360, 368, 376, 384, 392, 400, 408, 416, 424,
|
||||
432, 440, 448, 456, 464, 472, 480, 488, 496, 504, 512, 520, ]
|
||||
|
||||
valid_sizes_64b = [32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240,
|
||||
256, 272, 288, 304, 320, 336, 352, 368, 384, 400, 416, 432, 448,
|
||||
464, 480, 496, 512, 528, 544, 560, 576, 592, 608, 624, 640, 656,
|
||||
672, 688, 704, 720, 736, 752, 768, 784, 800, 816, 832, 848, 864,
|
||||
880, 896, 912, 928, 944, 960, 976, 992, 1008, 1024, 1040]
|
||||
|
||||
256, 272, 288, 304, 320, 336, 352, 368, 384, 400, 416, 432, 448,
|
||||
464, 480, 496, 512, 528, 544, 560, 576, 592, 608, 624, 640, 656,
|
||||
672, 688, 704, 720, 736, 752, 768, 784, 800, 816, 832, 848, 864,
|
||||
880, 896, 912, 928, 944, 960, 976, 992, 1008, 1024, 1040]
|
||||
# fmt: on
|
||||
|
||||
@property
|
||||
def valid_sizes(self):
|
||||
@@ -42,7 +45,6 @@ class GefHeapApi(RemoteGefUnitTestGeneric):
|
||||
return self.valid_sizes_64b
|
||||
return self.valid_sizes_32b
|
||||
|
||||
|
||||
def test_func_gef_heap_tidx2size(self):
|
||||
gdb, gef = self._gdb, self._gef
|
||||
gdb.execute("run")
|
||||
@@ -51,7 +53,6 @@ class GefHeapApi(RemoteGefUnitTestGeneric):
|
||||
size = gef.heap.tidx2size(idx)
|
||||
assert size in self.valid_sizes, f"idx={idx}"
|
||||
|
||||
|
||||
def test_func_gef_heap_csize2tidx(self):
|
||||
gdb, gef = self._gdb, self._gef
|
||||
gdb.execute("run")
|
||||
@@ -60,7 +61,6 @@ class GefHeapApi(RemoteGefUnitTestGeneric):
|
||||
idx = gef.heap.csize2tidx(size)
|
||||
assert idx in range(TCACHE_BINS), f"size={size}"
|
||||
|
||||
|
||||
@pytest.mark.skipif(ARCH not in ("x86_64",), reason=f"Skipped for {ARCH}")
|
||||
def test_func_gef_heap_malloc_align_address(self):
|
||||
gdb, gef = self._gdb, self._gef
|
||||
@@ -76,7 +76,6 @@ class GefHeapApi(RemoteGefUnitTestGeneric):
|
||||
res = gef.heap.malloc_align_address(x)
|
||||
assert res == y
|
||||
|
||||
|
||||
def test_class_glibcarena_main_arena(self):
|
||||
gdb, gef = self._gdb, self._gef
|
||||
gdb.execute("run")
|
||||
|
||||
+18
-9
@@ -74,7 +74,7 @@ class GefMemoryApi(RemoteGefUnitTestGeneric):
|
||||
if self.gdb_version < (11, 0):
|
||||
# expect an exception
|
||||
with pytest.raises(AttributeError):
|
||||
next(root.eval("gef.memory.parse_gdb_info_proc_maps()") )
|
||||
next(root.eval("gef.memory.parse_gdb_info_proc_maps()"))
|
||||
|
||||
else:
|
||||
sections = list(root.eval("gef.memory.parse_gdb_info_proc_maps()"))
|
||||
@@ -137,7 +137,9 @@ class GefMemoryApi(RemoteGefUnitTestGeneric):
|
||||
sections = gef.memory.maps
|
||||
assert len(sections) > 0
|
||||
|
||||
@pytest.mark.skipif(ARCH == "aarch64" and IN_GITHUB_ACTIONS, reason=f"Skipped for {ARCH} on CI")
|
||||
@pytest.mark.skipif(
|
||||
ARCH == "aarch64" and IN_GITHUB_ACTIONS, reason=f"Skipped for {ARCH} on CI"
|
||||
)
|
||||
def test_func_parse_maps_remote_qemu(self):
|
||||
gdb, gef = self._gdb, self._gef
|
||||
# When in a gef-remote qemu-user session `parse_gdb_info_proc_maps`
|
||||
@@ -153,7 +155,9 @@ class GefMemoryApi(RemoteGefUnitTestGeneric):
|
||||
sections = gef.memory.maps
|
||||
assert len(sections) > 0
|
||||
|
||||
@pytest.mark.skipif(ARCH == "aarch64" and IN_GITHUB_ACTIONS, reason=f"Skipped for {ARCH}")
|
||||
@pytest.mark.skipif(
|
||||
ARCH == "aarch64" and IN_GITHUB_ACTIONS, reason=f"Skipped for {ARCH}"
|
||||
)
|
||||
def test_func_parse_maps_realpath(self):
|
||||
gef, gdb = self._gef, self._gdb
|
||||
# When in a gef-remote session `parse_gdb_info_proc_maps` should work to
|
||||
@@ -176,8 +180,11 @@ class GefMemoryApi(RemoteGefUnitTestGeneric):
|
||||
# probably corrected the path to account for gdb bug #23764
|
||||
#
|
||||
for section in sections:
|
||||
if(section.is_executable() and section.path.startswith("/usr") and
|
||||
"/usr" not in section.realpath):
|
||||
if (
|
||||
section.is_executable()
|
||||
and section.path.startswith("/usr")
|
||||
and "/usr" not in section.realpath
|
||||
):
|
||||
assert pathlib.Path(section.realpath).is_file()
|
||||
break
|
||||
|
||||
@@ -188,9 +195,11 @@ class GefMemoryApi(RemoteGefUnitTestGeneric):
|
||||
gdb.execute("start")
|
||||
|
||||
section = gef.memory.maps[0]
|
||||
oob_val = gef.memory.read_cstring(section.page_start, section.page_end -
|
||||
section.page_start + 0x100)
|
||||
val = gef.memory.read_cstring(section.page_start, section.page_end -
|
||||
section.page_start)
|
||||
oob_val = gef.memory.read_cstring(
|
||||
section.page_start, section.page_end - section.page_start + 0x100
|
||||
)
|
||||
val = gef.memory.read_cstring(
|
||||
section.page_start, section.page_end - section.page_start
|
||||
)
|
||||
|
||||
assert val == oob_val
|
||||
|
||||
+3
-3
@@ -52,8 +52,8 @@ class RemoteGefUnitTestGeneric(unittest.TestCase):
|
||||
if not hasattr(self, "_target"):
|
||||
setattr(self, "_target", debug_target("default"))
|
||||
else:
|
||||
assert isinstance(self._target, pathlib.Path) # type: ignore pylint: disable=E1101
|
||||
assert self._target.exists() # type: ignore pylint: disable=E1101
|
||||
assert isinstance(self._target, pathlib.Path)
|
||||
assert self._target.exists()
|
||||
|
||||
#
|
||||
# Select a random tcp port for rpyc
|
||||
@@ -90,7 +90,7 @@ pi start_rpyc_service({self._port})
|
||||
"-ex",
|
||||
f"source {self._initfile.name}",
|
||||
"--",
|
||||
str(self._target.absolute()), # type: ignore pylint: disable=E1101
|
||||
str(self._target.absolute()),
|
||||
]
|
||||
self._process = subprocess.Popen(self._command)
|
||||
assert self._process.pid > 0
|
||||
|
||||
@@ -28,7 +28,6 @@ class ArchCommand(RemoteGefUnitTestGeneric):
|
||||
assert " Architecture(X86, 32, LITTLE_ENDIAN)" in res
|
||||
assert " The architecture has been set manually" in res
|
||||
|
||||
|
||||
gdb.execute("arch set ppc")
|
||||
|
||||
res = gdb.execute("arch get", to_string=True)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`aslr` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
|
||||
@@ -2,10 +2,17 @@
|
||||
`canary` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE, debug_target, p64, p32, is_64b, u32
|
||||
from tests.utils import (
|
||||
ERROR_INACTIVE_SESSION_MESSAGE,
|
||||
debug_target,
|
||||
p64,
|
||||
p32,
|
||||
is_64b,
|
||||
u32,
|
||||
)
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
class CanaryCommand(RemoteGefUnitTestGeneric):
|
||||
"""`canary` command test module"""
|
||||
|
||||
@@ -14,7 +21,9 @@ class CanaryCommand(RemoteGefUnitTestGeneric):
|
||||
return super().setUp()
|
||||
|
||||
def test_cmd_canary(self):
|
||||
assert ERROR_INACTIVE_SESSION_MESSAGE == self._gdb.execute("canary", to_string=True)
|
||||
assert ERROR_INACTIVE_SESSION_MESSAGE == self._gdb.execute(
|
||||
"canary", to_string=True
|
||||
)
|
||||
self._gdb.execute("start")
|
||||
res = self._gdb.execute("canary", to_string=True)
|
||||
assert "The canary of process" in res
|
||||
@@ -30,4 +39,4 @@ class CanaryCommand(RemoteGefUnitTestGeneric):
|
||||
else:
|
||||
gef.memory.write(canary_address, p32(0xDEADBEEF))
|
||||
res = u32(gef.memory.read(canary_address, gef.arch.ptrsize))
|
||||
assert 0xdeadbeef == res
|
||||
assert 0xDEADBEEF == res
|
||||
|
||||
@@ -18,7 +18,7 @@ class ChecksecCommandNoCanary(RemoteGefUnitTestGeneric):
|
||||
gef = self._gef
|
||||
res = gdb.execute("checksec", to_string=True)
|
||||
assert "Canary : ✘" in res
|
||||
assert gef.binary.checksec["Canary"] == False
|
||||
assert not gef.binary.checksec["Canary"]
|
||||
|
||||
|
||||
class ChecksecCommandNoNx(RemoteGefUnitTestGeneric):
|
||||
@@ -31,7 +31,7 @@ class ChecksecCommandNoNx(RemoteGefUnitTestGeneric):
|
||||
gef = self._gef
|
||||
res = gdb.execute("checksec", to_string=True)
|
||||
assert "NX : ✘" in res
|
||||
assert gef.binary.checksec["NX"] == False
|
||||
assert not gef.binary.checksec["NX"]
|
||||
|
||||
|
||||
class ChecksecCommandNoPie(RemoteGefUnitTestGeneric):
|
||||
@@ -44,4 +44,4 @@ class ChecksecCommandNoPie(RemoteGefUnitTestGeneric):
|
||||
gef = self._gef
|
||||
res = gdb.execute("checksec", to_string=True)
|
||||
assert "PIE : ✘" in res
|
||||
assert gef.binary.checksec["PIE"] == False
|
||||
assert not gef.binary.checksec["PIE"]
|
||||
|
||||
@@ -2,17 +2,14 @@
|
||||
`context` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
class ContextCommand(RemoteGefUnitTestGeneric):
|
||||
"""`context` command test module"""
|
||||
|
||||
|
||||
cmd = "context"
|
||||
|
||||
|
||||
# TODO See https://github.com/hugsy/gef/projects/10
|
||||
|
||||
def test_duplicate_pane_name(self):
|
||||
@@ -25,12 +22,18 @@ class ContextCommand(RemoteGefUnitTestGeneric):
|
||||
current_layout = gef.config["context.layout"]
|
||||
assert not current_layout.endswith(new_pane_id)
|
||||
|
||||
res = gdb.execute(f"pi register_external_context_pane('{new_pane_id}', print, print, None)", to_string=True)
|
||||
res = gdb.execute(
|
||||
f"pi register_external_context_pane('{new_pane_id}', print, print, None)",
|
||||
to_string=True,
|
||||
)
|
||||
assert "Python Exception" not in res
|
||||
new_layout = gef.config["context.layout"]
|
||||
assert new_layout.endswith(new_pane_id)
|
||||
|
||||
res = gdb.execute(f"pi register_external_context_pane('{new_pane_id}', print, print, None)", to_string=True)
|
||||
res = gdb.execute(
|
||||
f"pi register_external_context_pane('{new_pane_id}', print, print, None)",
|
||||
to_string=True,
|
||||
)
|
||||
assert "Python Exception" not in res
|
||||
new_layout2 = gef.config["context.layout"]
|
||||
assert new_layout == new_layout2
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
`edit-flags` command test module
|
||||
"""
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ARCH, ERROR_INACTIVE_SESSION_MESSAGE
|
||||
from tests.utils import ARCH
|
||||
|
||||
|
||||
@pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}")
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
elf-info command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
class ElfInfoCommand(RemoteGefUnitTestGeneric):
|
||||
"""`elf-info` command test module"""
|
||||
|
||||
|
||||
def test_cmd_elf_info(self):
|
||||
gdb = self._gdb
|
||||
res = gdb.execute("elf-info", to_string=True)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`entry-break` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`format-string_helper` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import debug_target
|
||||
|
||||
@@ -19,9 +18,7 @@ class FormatStringHelperCommand(RemoteGefUnitTestGeneric):
|
||||
|
||||
gdb.execute("set args testtest")
|
||||
res = gdb.execute("format-string-helper", to_string=True)
|
||||
assert res.endswith(
|
||||
"[+] Enabled 5 FormatString breakpoints\n"
|
||||
)
|
||||
assert res.endswith("[+] Enabled 5 FormatString breakpoints\n")
|
||||
|
||||
res = gdb.execute("run", to_string=True)
|
||||
assert "Possible insecure format string:" in res
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`functions` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,9 @@ class GefRemoteCommand(RemoteGefUnitTestGeneric):
|
||||
with gdbserver_session(port=port):
|
||||
gdb.execute(f"gef-remote {GDBSERVER_DEFAULT_HOST} {port}")
|
||||
res: str = root.eval("str(gef.session.remote)")
|
||||
assert res.startswith(f"RemoteSession(target='{GDBSERVER_DEFAULT_HOST}:{port}', local='/tmp/")
|
||||
assert res.startswith(
|
||||
f"RemoteSession(target='{GDBSERVER_DEFAULT_HOST}:{port}', local='/tmp/"
|
||||
)
|
||||
assert res.endswith(f"pid={gef.session.pid}, mode={gdbserver_mode})")
|
||||
|
||||
@pytest.mark.slow
|
||||
@@ -55,7 +57,9 @@ class GefRemoteCommand(RemoteGefUnitTestGeneric):
|
||||
cmd = f"gef-remote --qemu-user --qemu-binary {self._target} {GDBSERVER_DEFAULT_HOST} {port}"
|
||||
gdb.execute(cmd)
|
||||
res = root.eval("str(gef.session.remote)")
|
||||
assert res.startswith(f"RemoteSession(target='{GDBSERVER_DEFAULT_HOST}:{port}', local='/tmp/")
|
||||
assert res.startswith(
|
||||
f"RemoteSession(target='{GDBSERVER_DEFAULT_HOST}:{port}', local='/tmp/"
|
||||
)
|
||||
assert res.endswith(f"pid={gef.session.pid}, mode={qemu_mode})")
|
||||
|
||||
def test_cmd_target_remote(self):
|
||||
|
||||
@@ -21,11 +21,12 @@ class GotCommand(RemoteGefUnitTestGeneric):
|
||||
self._target = debug_target("format-string-helper")
|
||||
return super().setUp()
|
||||
|
||||
|
||||
def test_cmd_got(self):
|
||||
gdb = self._gdb
|
||||
|
||||
self.assertEqual(ERROR_INACTIVE_SESSION_MESSAGE,gdb.execute("got", to_string=True))
|
||||
self.assertEqual(
|
||||
ERROR_INACTIVE_SESSION_MESSAGE, gdb.execute("got", to_string=True)
|
||||
)
|
||||
|
||||
gdb.execute("start")
|
||||
res = gdb.execute("got", to_string=True)
|
||||
@@ -41,12 +42,12 @@ class GotCommand(RemoteGefUnitTestGeneric):
|
||||
if not lines:
|
||||
return None
|
||||
if "format-string-helper.out" in lines[0]:
|
||||
res = ''.join(lines)
|
||||
res = "".join(lines)
|
||||
self.assertIn(" printf", res)
|
||||
self.assertNotIn(" strcpy", res)
|
||||
return "format-string-helper.out"
|
||||
if "/libc" in lines[0]:
|
||||
res = ''.join(lines)
|
||||
res = "".join(lines)
|
||||
self.assertNotIn(" printf", res)
|
||||
self.assertNotIn(" strcpy", res)
|
||||
return "libc"
|
||||
|
||||
@@ -187,7 +187,14 @@ class HeapCommandNonMain(RemoteGefUnitTestGeneric):
|
||||
res = gdb.execute(cmd, to_string=True)
|
||||
self.assertIn("size=0x20", res)
|
||||
|
||||
@pytest.mark.skipif(ARCH not in ("i686", "x86_64",), reason=f"Skipped for {ARCH}")
|
||||
@pytest.mark.skipif(
|
||||
ARCH
|
||||
not in (
|
||||
"i686",
|
||||
"x86_64",
|
||||
),
|
||||
reason=f"Skipped for {ARCH}",
|
||||
)
|
||||
@pytest.mark.skipif(is_glibc_ge(2, 42), reason="Skipped for glibc >= 2.42")
|
||||
def test_cmd_heap_bins_tcache(self):
|
||||
gdb = self._gdb
|
||||
@@ -238,7 +245,7 @@ class HeapCommandClass(RemoteGefUnitTestGeneric):
|
||||
assert len(lines) > 0
|
||||
self.assertEqual("== Chunk distribution by size ==", lines[0])
|
||||
self.assertIn("== Chunk distribution by flag ==", lines)
|
||||
assert any( map(lambda x: "B<TraitA, TraitB>" in x, lines))
|
||||
assert any(map(lambda x: "B<TraitA, TraitB>" in x, lines))
|
||||
|
||||
|
||||
class HeapCommandFastBins(RemoteGefUnitTestGeneric):
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`heap-analysis` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE, debug_target
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`hexdump` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE
|
||||
|
||||
@@ -10,13 +9,14 @@ from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE
|
||||
class HexdumpCommand(RemoteGefUnitTestGeneric):
|
||||
"""`hexdump` command test module"""
|
||||
|
||||
|
||||
def test_cmd_hexdump(self):
|
||||
gdb = self._gdb
|
||||
self.assertEqual(ERROR_INACTIVE_SESSION_MESSAGE,gdb.execute("hexdump $pc", to_string=True))
|
||||
self.assertEqual(
|
||||
ERROR_INACTIVE_SESSION_MESSAGE, gdb.execute("hexdump $pc", to_string=True)
|
||||
)
|
||||
|
||||
gdb.execute("start")
|
||||
res = gdb.execute("hexdump qword $pc", to_string=True)
|
||||
res = gdb.execute("hexdump dword $pc -s 1", to_string=True)
|
||||
res = gdb.execute("hexdump word $pc -s 5 -r", to_string=True)
|
||||
res = gdb.execute("hexdump byte $sp -s 32", to_string=True)
|
||||
gdb.execute("hexdump qword $pc", to_string=True)
|
||||
gdb.execute("hexdump dword $pc -s 1", to_string=True)
|
||||
gdb.execute("hexdump word $pc -s 5 -r", to_string=True)
|
||||
gdb.execute("hexdump byte $sp -s 32", to_string=True)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`highlight` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import Color
|
||||
|
||||
|
||||
@@ -2,17 +2,14 @@
|
||||
`hijack_fd` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
class HijackFdCommand(RemoteGefUnitTestGeneric):
|
||||
"""`hijack-fd` command test module"""
|
||||
|
||||
|
||||
cmd = "hijack-fd"
|
||||
|
||||
|
||||
def test_cmd_hijack_fd(self):
|
||||
gdb = self._gdb
|
||||
res = gdb.execute(f"{self.cmd}", to_string=True)
|
||||
gdb.execute(f"{self.cmd}", to_string=True)
|
||||
|
||||
@@ -88,4 +88,4 @@ class MemoryCommand(RemoteGefUnitTestGeneric):
|
||||
ERROR_INACTIVE_SESSION_MESSAGE, gdb.execute("memory reset", to_string=True)
|
||||
)
|
||||
gdb.execute("start")
|
||||
res = gdb.execute("memory reset", to_string=True)
|
||||
gdb.execute("memory reset", to_string=True)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`name-break` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
|
||||
+10
-7
@@ -171,10 +171,13 @@ class NopCommand(RemoteGefUnitTestGeneric):
|
||||
gef = self._gef
|
||||
gdb.execute("start")
|
||||
gef.memory.write(gef.arch.pc, p16(0x9191))
|
||||
res = gdb.execute(
|
||||
f"{self.cmd} --b",
|
||||
to_string=True,
|
||||
) or ""
|
||||
res = (
|
||||
gdb.execute(
|
||||
f"{self.cmd} --b",
|
||||
to_string=True,
|
||||
)
|
||||
or ""
|
||||
)
|
||||
assert res
|
||||
mem = u16(gef.memory.read(gef.arch.pc, 2))
|
||||
self.assertEqual(0x9190, mem)
|
||||
@@ -199,7 +202,7 @@ class NopCommand(RemoteGefUnitTestGeneric):
|
||||
res = gdb.execute(f"{self.cmd} --b --f", to_string=True)
|
||||
mem = u16(gef.memory.read(gef.arch.pc, 2))
|
||||
self.assertIn(r"will result in LAST-INSTRUCTION", res)
|
||||
self.assertEqual(0xfe90, mem)
|
||||
self.assertEqual(0xFE90, mem)
|
||||
|
||||
@pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}")
|
||||
def test_cmd_nop_bytes_arg(self):
|
||||
@@ -247,7 +250,7 @@ class NopCommandMmapKnownAddress(RemoteGefUnitTestGeneric):
|
||||
def test_cmd_nop_invalid_end_address(self):
|
||||
gdb = self._gdb
|
||||
gdb.execute("run")
|
||||
res = gdb.execute(f"nop --i 5 0x1337000+0x1000-4", to_string=True)
|
||||
res = gdb.execute("nop --i 5 0x1337000+0x1000-4", to_string=True)
|
||||
self.assertIn("reaching unmapped area", res)
|
||||
|
||||
@pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}")
|
||||
@@ -256,7 +259,7 @@ class NopCommandMmapKnownAddress(RemoteGefUnitTestGeneric):
|
||||
gef = self._gef
|
||||
# Make sure we error out if writing nops into an unmapped or RO area
|
||||
gdb.execute("run")
|
||||
res = gdb.execute(f"nop --b --i 5 0x1337000+0x1000-4", to_string=True)
|
||||
res = gdb.execute("nop --b --i 5 0x1337000+0x1000-4", to_string=True)
|
||||
self.assertIn(
|
||||
"Cannot patch instruction at 0x1337ffc: reaching unmapped area", res
|
||||
)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
patch command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE, debug_target, u16, u32, u64, u8
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Pattern commands test module
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
@@ -91,4 +92,4 @@ class PatternCommand(RemoteGefUnitTestGeneric):
|
||||
gdb.execute("set args aaaabaaacaaadaaaeaaafaaagaaahaaa")
|
||||
gdb.execute("run")
|
||||
res = gdb.execute(cmd, to_string=True)
|
||||
self.assertIn(f"not found", res)
|
||||
self.assertIn("not found", res)
|
||||
|
||||
@@ -45,7 +45,7 @@ class PcustomCommand(RemoteGefUnitTestGeneric):
|
||||
#
|
||||
gdb.execute(f"gef config pcustom.struct_path {dirpath}")
|
||||
res = gdb.execute("gef config pcustom.struct_path", to_string=True)
|
||||
self.assertIn(f'pcustom.struct_path (Path) = {dirpath}', res)
|
||||
self.assertIn(f"pcustom.struct_path (Path) = {dirpath}", res)
|
||||
|
||||
#
|
||||
# List the structures in the files inside dirpath
|
||||
@@ -59,8 +59,12 @@ class PcustomCommand(RemoteGefUnitTestGeneric):
|
||||
#
|
||||
gdb.execute("run")
|
||||
bad_struct_name = "meh_t"
|
||||
res = gdb.execute(f"pcustom {bad_struct_name} 0x1337100", to_string=True).strip()
|
||||
self.assertEqual(f"[!] No structure named '{bad_struct_name}' found", res)
|
||||
res = gdb.execute(
|
||||
f"pcustom {bad_struct_name} 0x1337100", to_string=True
|
||||
).strip()
|
||||
self.assertEqual(
|
||||
f"[!] No structure named '{bad_struct_name}' found", res
|
||||
)
|
||||
print(res)
|
||||
|
||||
def test_cmd_pcustom_show(self):
|
||||
@@ -102,13 +106,13 @@ class PcustomCommand(RemoteGefUnitTestGeneric):
|
||||
res = gdb.execute("pcustom goo_t 0x1337100", to_string=True)
|
||||
if is_64b():
|
||||
self.assertIn(
|
||||
f"""0x1337100+0x00 a : 3 (c_int)
|
||||
"""0x1337100+0x00 a : 3 (c_int)
|
||||
0x1337100+0x04 b : 4 (c_int)
|
||||
0x1337100+0x08 c : """,
|
||||
res,
|
||||
)
|
||||
self.assertIn(
|
||||
f""" 0x1337000+0x00 a : 1 (c_int)
|
||||
""" 0x1337000+0x00 a : 1 (c_int)
|
||||
0x1337000+0x04 b : 2 (c_int)
|
||||
0x1337100+0x10 d : 12 (c_int)
|
||||
0x1337100+0x14 e : 13 (c_int)""",
|
||||
@@ -116,13 +120,13 @@ class PcustomCommand(RemoteGefUnitTestGeneric):
|
||||
)
|
||||
else:
|
||||
self.assertIn(
|
||||
f"""0x1337100+0x00 a : 3 (c_long)
|
||||
"""0x1337100+0x00 a : 3 (c_long)
|
||||
0x1337100+0x04 b : 4 (c_long)
|
||||
0x1337100+0x08 c : """,
|
||||
res,
|
||||
)
|
||||
self.assertIn(
|
||||
f""" 0x1337000+0x00 a : 1 (c_long)
|
||||
""" 0x1337000+0x00 a : 1 (c_long)
|
||||
0x1337000+0x04 b : 2 (c_long)
|
||||
0x1337100+0x0c d : 12 (c_long)
|
||||
0x1337100+0x10 e : 13 (c_long)""",
|
||||
|
||||
@@ -44,10 +44,7 @@ class PieCommand(RemoteGefUnitTestGeneric):
|
||||
gdb = self._gdb
|
||||
# breakpoint at a random instruction and run
|
||||
gdb.execute(f"pie breakpoint {self.pie_offset}")
|
||||
res = gdb.execute(
|
||||
"pie run",
|
||||
to_string=True
|
||||
)
|
||||
res = gdb.execute("pie run", to_string=True)
|
||||
# check we stopped for a breakpoint
|
||||
res = removeuntil('Name: "default.out", stopped ', res).splitlines()[0]
|
||||
self.assertIn("in main (), reason: BREAKPOINT", res)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
print-format command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE, p32
|
||||
|
||||
@@ -41,7 +40,9 @@ class PrintFormatCommand(RemoteGefUnitTestGeneric):
|
||||
|
||||
gef.memory.write(gef.arch.sp, p32(0x41414141))
|
||||
|
||||
res = gdb.execute("print-format --lang bytearray -l 4 $sp", to_string=True).strip()
|
||||
res = gdb.execute(
|
||||
"print-format --lang bytearray -l 4 $sp", to_string=True
|
||||
).strip()
|
||||
gef_var = res.split("$_gef")[1].split("'")[0]
|
||||
self.assertEqual(f"Saved data b'AAAA'... in '$_gef{gef_var}'", res)
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`process-search` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import debug_target
|
||||
|
||||
@@ -28,9 +27,7 @@ class ProcessSearchCommand(RemoteGefUnitTestGeneric):
|
||||
lines = gdb.execute("process-search gdb.*fakefake", to_string=True).splitlines()
|
||||
self.assertEqual(len(lines), 0)
|
||||
|
||||
lines = gdb.execute(
|
||||
f"process-search gdb.*", to_string=True
|
||||
).splitlines()
|
||||
lines = gdb.execute("process-search gdb.*", to_string=True).splitlines()
|
||||
self.assertGreaterEqual(len(lines), 1)
|
||||
|
||||
def test_cmd_process_search_smartscan(self):
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`process-status` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`registers` command test module
|
||||
"""
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
`reset-cache` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
class ResetCacheCommand(RemoteGefUnitTestGeneric):
|
||||
"""`reset-cache` command test module"""
|
||||
|
||||
|
||||
def test_cmd_reset_cache(self):
|
||||
gdb = self._gdb
|
||||
gdb.execute("start")
|
||||
|
||||
+11
-2
@@ -5,7 +5,13 @@ scan command test module
|
||||
import pytest
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ARCH, ERROR_INACTIVE_SESSION_MESSAGE, IN_GITHUB_ACTIONS, debug_target, is_glibc_ge
|
||||
from tests.utils import (
|
||||
ARCH,
|
||||
ERROR_INACTIVE_SESSION_MESSAGE,
|
||||
IN_GITHUB_ACTIONS,
|
||||
debug_target,
|
||||
is_glibc_ge,
|
||||
)
|
||||
|
||||
|
||||
class ScanCommand(RemoteGefUnitTestGeneric):
|
||||
@@ -15,7 +21,10 @@ class ScanCommand(RemoteGefUnitTestGeneric):
|
||||
self._target = debug_target("default")
|
||||
return super().setUp()
|
||||
|
||||
@pytest.mark.skipif(ARCH == "aarch64" and IN_GITHUB_ACTIONS and is_glibc_ge(2, 41), reason=f"Skipped for {ARCH} on CI with glibc >= 2.41")
|
||||
@pytest.mark.skipif(
|
||||
ARCH == "aarch64" and IN_GITHUB_ACTIONS and is_glibc_ge(2, 41),
|
||||
reason=f"Skipped for {ARCH} on CI with glibc >= 2.41",
|
||||
)
|
||||
def test_cmd_scan(self):
|
||||
gdb = self._gdb
|
||||
cmd = "scan libc stack"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
search_pattern command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import BIN_SH, ERROR_INACTIVE_SESSION_MESSAGE
|
||||
|
||||
@@ -26,7 +25,7 @@ class SearchPatternCommand(RemoteGefUnitTestGeneric):
|
||||
gdb.execute("set {char[6]} $sp = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x00 }")
|
||||
res = gdb.execute(
|
||||
r"search-pattern --regex $sp $sp+7 ([\\x20-\\x7E]{2,})(?=\\x00)",
|
||||
to_string=True
|
||||
to_string=True,
|
||||
)
|
||||
self.assertTrue(r"b'ABCDE'" in res)
|
||||
|
||||
@@ -34,6 +33,6 @@ class SearchPatternCommand(RemoteGefUnitTestGeneric):
|
||||
gdb.execute("set {char[6]} $sp = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x03 }")
|
||||
res = gdb.execute(
|
||||
r"search-pattern --regex $sp $sp+7 ([\\x20-\\x7E]{2,})(?=\\x00)",
|
||||
to_string=True
|
||||
to_string=True,
|
||||
)
|
||||
self.assertNotIn(r"b'ABCDE'", res)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
"""
|
||||
Shellcode commands test module
|
||||
"""
|
||||
import pytest
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
from tests.utils import BIN_SH
|
||||
|
||||
|
||||
class ShellcodeCommand(RemoteGefUnitTestGeneric):
|
||||
"""`shellcode` command test module"""
|
||||
|
||||
def test_cmd_shellcode(self):
|
||||
gdb = self._gdb
|
||||
gdb.execute("start")
|
||||
res = gdb.execute("shellcode", to_string=True)
|
||||
self.assertIn("Missing sub-command (search|get)", res)
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.slow
|
||||
def test_cmd_shellcode_search(self):
|
||||
gdb = self._gdb
|
||||
cmd = f"shellcode search execve {BIN_SH}"
|
||||
gdb.execute("start")
|
||||
res = gdb.execute(cmd, to_string=True)
|
||||
self.assertIn(f"setuid(0) + execve({BIN_SH}) 49 bytes", res)
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.slow
|
||||
def test_cmd_shellcode_get_ok(self):
|
||||
gdb = self._gdb
|
||||
gdb.execute("start")
|
||||
res = gdb.execute("shellcode get 77", to_string=True)
|
||||
self.assertIn("Shellcode written to ", res)
|
||||
|
||||
@pytest.mark.online
|
||||
@pytest.mark.slow
|
||||
def test_cmd_shellcode_get_nok(self):
|
||||
gdb = self._gdb
|
||||
n = 1111111111111
|
||||
gdb.execute("start")
|
||||
res = gdb.execute(f"shellcode get {n}", to_string=True)
|
||||
self.assertIn(f"Failed to fetch shellcode #{n}", res)
|
||||
@@ -50,7 +50,8 @@ class SkipiCommand(RemoteGefUnitTestGeneric):
|
||||
gdb.execute("start")
|
||||
gef.memory.write(gef.arch.pc, p64(0x9090FEEBFEEBFEEB))
|
||||
res = gdb.execute(
|
||||
f"{self.cmd} $pc+2 --n 2", to_string=True # from the second short jump
|
||||
f"{self.cmd} $pc+2 --n 2", # from the second short jump
|
||||
to_string=True,
|
||||
)
|
||||
assert res
|
||||
mem = u16(gef.memory.read(gef.arch.pc, 2)) # read 2 bytes
|
||||
|
||||
@@ -2,21 +2,19 @@
|
||||
`smart_eval` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
class SmartEvalCommand(RemoteGefUnitTestGeneric):
|
||||
"""`smart_eval` command test module"""
|
||||
|
||||
|
||||
def test_cmd_smart_eval(self):
|
||||
gdb = self._gdb
|
||||
gef = self._gef
|
||||
|
||||
gdb.execute("start")
|
||||
examples = (
|
||||
("$ $pc+1", str(gef.arch.pc+1)),
|
||||
("$ $pc+1", str(gef.arch.pc + 1)),
|
||||
("$ -0x1000", "-4096"),
|
||||
("$ 0x00007ffff7812000 0x00007ffff79a7000", "1658880"),
|
||||
("$ 1658880", "0b110010101000000000000"),
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import pytest
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ARCH, ERROR_INACTIVE_SESSION_MESSAGE, p32, p64, u16, u32
|
||||
from tests.utils import ARCH, ERROR_INACTIVE_SESSION_MESSAGE, u16
|
||||
|
||||
|
||||
class Stepover(RemoteGefUnitTestGeneric):
|
||||
@@ -24,7 +24,7 @@ class Stepover(RemoteGefUnitTestGeneric):
|
||||
gef = self._gef
|
||||
|
||||
payload = b"\xe8\x05\x00\x00\x00\x90\x90\x6a\x00\xc3\xb8\x69\x69\x69\x69\xc3"
|
||||
'''
|
||||
"""
|
||||
call movtag <- 'stepover' execution from this point
|
||||
nop <- 'stepover' should stops here and eax value should be 0x69696969
|
||||
nop
|
||||
@@ -33,7 +33,7 @@ class Stepover(RemoteGefUnitTestGeneric):
|
||||
movtag:
|
||||
mov eax, 0x69696969
|
||||
ret
|
||||
'''
|
||||
"""
|
||||
|
||||
gdb.execute("start")
|
||||
gef.memory.write(gef.arch.pc, payload)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
stub command test module
|
||||
"""
|
||||
|
||||
|
||||
import pytest
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
theme command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
@@ -40,6 +39,5 @@ class ThemeCommand(RemoteGefUnitTestGeneric):
|
||||
v = "blue blah 10 -1 0xfff bold"
|
||||
gdb.execute(f"theme {t} {v}")
|
||||
|
||||
|
||||
res = gdb.execute("theme ___I_DONT_EXIST___", to_string=True)
|
||||
self.assertIn("Invalid key", res)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
trace-run command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import TMPDIR, ERROR_INACTIVE_SESSION_MESSAGE
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`version` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
vmmap command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE
|
||||
|
||||
@@ -24,7 +23,9 @@ class VmmapCommand(RemoteGefUnitTestGeneric):
|
||||
self.assertEqual(len(res.splitlines()), 9)
|
||||
|
||||
res = gdb.execute("vmmap $pc", to_string=True)
|
||||
assert "`$pc` has no type specified. We guessed it was an address filter." in res
|
||||
assert (
|
||||
"`$pc` has no type specified. We guessed it was an address filter." in res
|
||||
)
|
||||
self.assertEqual(len(res.splitlines()), 8)
|
||||
|
||||
def test_cmd_vmmap_addr(self):
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
`xfiles` command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE
|
||||
|
||||
@@ -17,4 +16,4 @@ class XfilesCommand(RemoteGefUnitTestGeneric):
|
||||
)
|
||||
gdb.execute("start")
|
||||
res = gdb.execute("xfiles", to_string=True)
|
||||
self.assertGreaterEqual(len(res.splitlines()) , 3)
|
||||
self.assertGreaterEqual(len(res.splitlines()), 3)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
xinfo command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE, debug_target
|
||||
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
xor-memory command test module
|
||||
"""
|
||||
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE
|
||||
|
||||
|
||||
class XorMemoryCommand(RemoteGefUnitTestGeneric):
|
||||
"""`xor-memory` command test module"""
|
||||
|
||||
|
||||
def test_cmd_xor_memory_display(self):
|
||||
gdb = self._gdb
|
||||
cmd = "xor-memory display $sp 0x10 0x41"
|
||||
self.assertEqual(ERROR_INACTIVE_SESSION_MESSAGE, gdb.execute(cmd, to_string=True))
|
||||
self.assertEqual(
|
||||
ERROR_INACTIVE_SESSION_MESSAGE, gdb.execute(cmd, to_string=True)
|
||||
)
|
||||
|
||||
gdb.execute("start")
|
||||
res = gdb.execute(cmd, to_string=True)
|
||||
assert "Original block" in res
|
||||
assert "XOR-ed block" in res
|
||||
|
||||
|
||||
def test_cmd_xor_memory_patch(self):
|
||||
gdb = self._gdb
|
||||
gdb.execute("start")
|
||||
|
||||
@@ -37,9 +37,9 @@ class TestGefConfigUnit(RemoteGefUnitTestGeneric):
|
||||
for line in lines:
|
||||
parts = line.replace(GEF_RIGHT_ARROW, "").split()
|
||||
opcode: str = parts[1].replace("...", "").lower()
|
||||
assert (
|
||||
len(opcode) <= max_opcode_len * 2
|
||||
), f"Invalid length for {opcode=}: {len(opcode)}"
|
||||
assert len(opcode) <= max_opcode_len * 2, (
|
||||
f"Invalid length for {opcode=}: {len(opcode)}"
|
||||
)
|
||||
assert all(map(lambda c: c in "0123456789abcdef", opcode))
|
||||
|
||||
def test_config_hook_validator(self):
|
||||
@@ -75,7 +75,9 @@ class TestGefConfigUnit(RemoteGefUnitTestGeneric):
|
||||
gdb.execute("gef config gef.debug 0")
|
||||
|
||||
# debug disable -> set setting should not raise but print error
|
||||
output = (gdb.execute("gef config gef.debug 'fooo'", to_string=True) or "").strip()
|
||||
output = (
|
||||
gdb.execute("gef config gef.debug 'fooo'", to_string=True) or ""
|
||||
).strip()
|
||||
assert output == "[!] Cannot parse 'fooo' as bool"
|
||||
|
||||
def test_config_libc_version(self):
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
GDB function test module for ELF section convenience functions
|
||||
"""
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.utils import ERROR_INACTIVE_SESSION_MESSAGE, debug_target, is_64b
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import pytest
|
||||
|
||||
from tests.base import RemoteGefUnitTestGeneric
|
||||
from tests.utils import debug_target
|
||||
|
||||
|
||||
@@ -8,7 +8,9 @@ from tests.utils import (
|
||||
|
||||
|
||||
class RegressionGdbserverConnection(RemoteGefUnitTestGeneric):
|
||||
@pytest.mark.skipif(ARCH == "aarch64" and IN_GITHUB_ACTIONS, reason=f"Skipped for {ARCH} on CI")
|
||||
@pytest.mark.skipif(
|
||||
ARCH == "aarch64" and IN_GITHUB_ACTIONS, reason=f"Skipped for {ARCH} on CI"
|
||||
)
|
||||
def test_can_establish_connection_to_gdbserver_again_after_disconnect(self):
|
||||
"""Ensure that gdb can connect to a gdbserver again after disconnecting (PR #896)."""
|
||||
gdb = self._gdb
|
||||
|
||||
@@ -74,7 +74,7 @@ class RegressionRegisterOrderNested(RemoteGefUnitTestGeneric):
|
||||
lines1 = gdb.execute("registers", to_string=True).splitlines()
|
||||
gdb.execute("frame 5")
|
||||
lines2 = gdb.execute("registers", to_string=True).splitlines()
|
||||
rips = [x for x in lines1+lines2 if x.startswith("$rip")]
|
||||
rips = [x for x in lines1 + lines2 if x.startswith("$rip")]
|
||||
self.assertEqual(len(rips), 2) # we must have only 2 entries
|
||||
self.assertNotEqual(rips[0], rips[1]) # they must be different
|
||||
self.assertIn("<f10", rips[0]) # the first one must be in the f10 frame
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
pylint
|
||||
pytest
|
||||
pytest-cov
|
||||
pytest-xdist
|
||||
@@ -8,3 +7,4 @@ coverage
|
||||
pre-commit
|
||||
rpyc>=5
|
||||
requests
|
||||
ruff
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import pathlib
|
||||
import unittest
|
||||
import tempfile
|
||||
import subprocess
|
||||
import requests
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
from tests.utils import GEF_PATH
|
||||
|
||||
@@ -15,6 +15,8 @@ class GefInstallScript(unittest.TestCase):
|
||||
def setUp(self):
|
||||
url = "https://api.github.com/repos/hugsy/gef/tags"
|
||||
res = requests.get(url)
|
||||
if res.status_code == 403:
|
||||
pytest.skip("API rate limit exceeded")
|
||||
assert res.status_code == 200
|
||||
self.latest_release = res.json()[0]["name"]
|
||||
|
||||
|
||||
+19
-19
@@ -12,7 +12,6 @@ import struct
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
from typing import Iterable, List, Optional, Union
|
||||
from urllib.request import urlopen
|
||||
|
||||
@@ -57,31 +56,32 @@ WARNING_DEPRECATION_MESSAGE = "is deprecated and will be removed in a feature re
|
||||
|
||||
IN_GITHUB_ACTIONS = os.getenv("GITHUB_ACTIONS") == "true"
|
||||
|
||||
|
||||
class Color(enum.Enum):
|
||||
"""Used to colorify terminal output."""
|
||||
|
||||
NORMAL = "\001\033[0m\002"
|
||||
GRAY = "\001\033[1;38;5;240m\002"
|
||||
LIGHT_GRAY = "\001\033[0;37m\002"
|
||||
RED = "\001\033[31m\002"
|
||||
GREEN = "\001\033[32m\002"
|
||||
YELLOW = "\001\033[33m\002"
|
||||
BLUE = "\001\033[34m\002"
|
||||
PINK = "\001\033[35m\002"
|
||||
CYAN = "\001\033[36m\002"
|
||||
BOLD = "\001\033[1m\002"
|
||||
UNDERLINE = "\001\033[4m\002"
|
||||
UNDERLINE_OFF = "\001\033[24m\002"
|
||||
HIGHLIGHT = "\001\033[3m\002"
|
||||
HIGHLIGHT_OFF = "\001\033[23m\002"
|
||||
BLINK = "\001\033[5m\002"
|
||||
BLINK_OFF = "\001\033[25m\002"
|
||||
NORMAL = "\001\033[0m\002"
|
||||
GRAY = "\001\033[1;38;5;240m\002"
|
||||
LIGHT_GRAY = "\001\033[0;37m\002"
|
||||
RED = "\001\033[31m\002"
|
||||
GREEN = "\001\033[32m\002"
|
||||
YELLOW = "\001\033[33m\002"
|
||||
BLUE = "\001\033[34m\002"
|
||||
PINK = "\001\033[35m\002"
|
||||
CYAN = "\001\033[36m\002"
|
||||
BOLD = "\001\033[1m\002"
|
||||
UNDERLINE = "\001\033[4m\002"
|
||||
UNDERLINE_OFF = "\001\033[24m\002"
|
||||
HIGHLIGHT = "\001\033[3m\002"
|
||||
HIGHLIGHT_OFF = "\001\033[23m\002"
|
||||
BLINK = "\001\033[5m\002"
|
||||
BLINK_OFF = "\001\033[25m\002"
|
||||
|
||||
|
||||
def is_glibc_ge(major, minor):
|
||||
ver = platform.libc_ver()
|
||||
if ver[0] == 'glibc':
|
||||
(glibc_major, glibc_minor, *glibc_patch) = list(map(int, ver[1].split('.')))
|
||||
if ver[0] == "glibc":
|
||||
(glibc_major, glibc_minor, *_) = list(map(int, ver[1].split(".")))
|
||||
return (glibc_major, glibc_minor) >= (major, minor)
|
||||
return False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user