Skip to content

Commit

Permalink
Change newline when setting context.os to "windows" (#2330)
Browse files Browse the repository at this point in the history
* Change newline when setting `context.os`

Windows uses `b'\r\n'` for newlines while unix uses `b'\n'`. Change the expected newline to `b'\r\n'` when setting `context.os = "windows"` automatically for convenience.

* Update CHANGELOG

* Fix other tests setting os
  • Loading branch information
peace-maker committed Mar 29, 2024
1 parent cb54085 commit 5981c72
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,14 @@ The table below shows which release corresponds to each branch, and what date th
- [#2374][2374] libcdb.unstrip_libc: debug symbols are fetched only if not present
- [#2327][2327] Add basic support to debug processes on Windows
- [#2322][2322] Add basic RISCV64 shellcraft support
- [#2330][2330] Change `context.newline` when setting `context.os` to `"windows"`

[2360]: https://github.com/Gallopsled/pwntools/pull/2360
[2356]: https://github.com/Gallopsled/pwntools/pull/2356
[2374]: https://github.com/Gallopsled/pwntools/pull/2374
[2327]: https://github.com/Gallopsled/pwntools/pull/2327
[2322]: https://github.com/Gallopsled/pwntools/pull/2322
[2330]: https://github.com/Gallopsled/pwntools/pull/2330

## 4.13.0 (`beta`)

Expand Down
77 changes: 68 additions & 9 deletions pwnlib/context/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ class ContextType(object):
>>> context.os == 'linux'
True
>>> context.arch = 'arm'
>>> vars(context) == {'arch': 'arm', 'bits': 32, 'endian': 'little', 'os': 'linux'}
>>> vars(context) == {'arch': 'arm', 'bits': 32, 'endian': 'little', 'os': 'linux', 'newline': b'\n'}
True
>>> context.endian
'little'
Expand Down Expand Up @@ -376,8 +376,19 @@ class ContextType(object):
'timeout': Timeout.maximum,
}

#: Valid values for :meth:`pwnlib.context.ContextType.os`
oses = sorted(('linux','freebsd','windows','cgc','android','baremetal','darwin'))
unix_like = {'newline': b'\n'}
windows_like = {'newline': b'\r\n'}

#: Keys are valid values for :meth:`pwnlib.context.ContextType.os`
oses = _longest({
'linux': unix_like,
'freebsd': unix_like,
'windows': windows_like,
'cgc': unix_like,
'android': unix_like,
'baremetal': unix_like,
'darwin': unix_like,
})

big_32 = {'endian': 'big', 'bits': 32}
big_64 = {'endian': 'big', 'bits': 64}
Expand Down Expand Up @@ -446,14 +457,14 @@ def __init__(self, **kwargs):


def copy(self):
"""copy() -> dict
r"""copy() -> dict
Returns a copy of the current context as a dictionary.
Examples:
>>> context.clear()
>>> context.os = 'linux'
>>> vars(context) == {'os': 'linux'}
>>> vars(context) == {'os': 'linux', 'newline': b'\n'}
True
"""
return self._tls.copy()
Expand Down Expand Up @@ -1104,25 +1115,73 @@ def mask(self):

@_validator
def os(self, os):
"""
r"""
Operating system of the target machine.
The default value is ``linux``.
Allowed values are listed in :attr:`pwnlib.context.ContextType.oses`.
Side Effects:
If an os is specified some attributes will be set on the context
if a user has not already set a value.
The following property may be modified:
- :attr:`newline`
Raises:
AttributeError: An invalid os was specified
Examples:
>>> context.os = 'linux'
>>> context.clear()
>>> context.os == 'linux' # Default os
True
>>> context.os = 'freebsd'
>>> context.os == 'freebsd'
True
>>> context.os = 'foobar' #doctest: +ELLIPSIS
Traceback (most recent call last):
...
AttributeError: os must be one of ['android', 'baremetal', 'cgc', 'freebsd', 'linux', 'windows']
>>> context.clear()
>>> context.newline == b'\n' # Default value
True
>>> context.os = 'windows'
>>> context.newline == b'\r\n' # New value
True
Note that expressly setting :attr:`newline` means that we use
that value instead of the default
>>> context.clear()
>>> context.newline = b'\n'
>>> context.os = 'windows'
>>> context.newline == b'\n'
True
Setting the os can override the default for :attr:`newline`
>>> context.clear()
>>> context.os = 'windows'
>>> vars(context) == {'os': 'windows', 'newline': b'\r\n'}
True
"""
os = os.lower()

if os not in self.oses:
raise AttributeError("os must be one of %r" % self.oses)
try:
defaults = self.oses[os]
except KeyError:
raise AttributeError("os must be one of %r" % sorted(self.oses))

for k,v in defaults.items():
if k not in self._tls:
self._tls[k] = v

return os

Expand Down

0 comments on commit 5981c72

Please sign in to comment.