<feed xmlns='http://www.w3.org/2005/Atom'>
<title>nsploit/sploit, branch v0.2</title>
<subtitle>Process interaction tool for software exploitation</subtitle>
<link rel='alternate' type='text/html' href='http://normalmode.org/malf/nsploit/'/>
<entry>
<title>r2: Simplify Symtbl construction in get_locals()</title>
<updated>2023-02-24T08:39:09+00:00</updated>
<author>
<name>Malfurious</name>
<email>m@lfurio.us</email>
</author>
<published>2023-02-22T20:01:24+00:00</published>
<link rel='alternate' type='text/html' href='http://normalmode.org/malf/nsploit/commit/?id=e3fcc7bf6450bf985291a4d8dd62eb2c08a83245'/>
<id>e3fcc7bf6450bf985291a4d8dd62eb2c08a83245</id>
<content type='text'>
Signed-off-by: Malfurious &lt;m@lfurio.us&gt;
Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Malfurious &lt;m@lfurio.us&gt;
Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>symtbl: Refactor module as an improved container type (and more)</title>
<updated>2023-02-24T08:39:09+00:00</updated>
<author>
<name>Malfurious</name>
<email>m@lfurio.us</email>
</author>
<published>2023-02-22T20:01:23+00:00</published>
<link rel='alternate' type='text/html' href='http://normalmode.org/malf/nsploit/commit/?id=d49577bdb3cd352fcbdab26391711ccbfcca82ec'/>
<id>d49577bdb3cd352fcbdab26391711ccbfcca82ec</id>
<content type='text'>
This effort was triggered by three immediate wants of the module:

    An improved data container interface to support things like key
    iteration and better key management.  This is primarily wanted by
    the ROP module (which is still in development).

    The introduction of package documentation across the project.  This
    module is now fully documented.

    To fix a bug in the Symtbl constructor, which would not allow a
    caller to supply "self" as an initial symbol name, even though it is
    legal in every other context.  This problem was caused by the
    constructor's bound instance parameter sharing this name.

This patch addresses all of these concerns, and also introduces some
fringe / QoL improvements that were discovered during the API refactor.

Element access may now be done via subscripting, as well as the previous
(and still generally perferred) .attribute notation.  The syntax for
storing subtables within a parent Symtbl is now greatly streamlined due
to some implementation-level changes to the class.  You may now directly
assign just a Symtbl object or a normal int, and you don't have to fuss
with tuples anymore.  The subtable's base is taken as its offset in the
parent, and the new operator replacement for the .map() method may be
used to define a desired value for the parent.

This detail is actually a breaking change compared to the previous
version.  While not technically a bug, it is unintuitive that the
previous version would not remove subtables when their offset was
changed by a simple assignment - the table would just move.  This patch
make it such that any symbol assignment to a regular int will replace an
old mounted subtable if one exists.

There are now no normal instance methods on the Symtbl type (only dunder
method overrides).  This is to free up the available symbol namespace as
much as possible.  The previous methods map(), adjust(), and rebase()
are now implemented as operators which, in every case, yield a new
derivative object, rather than mutating the original.  All operators are
listed here:

    @   remap to absolute address
    +   remap to relative address
    -   remap to negated relative address
    &gt;&gt;  adjust all symbol offsets upward
    &lt;&lt;  adjust all symbol offsets downward
    %   rebase all symbol offsets around an absolute zero point

Additionally, Symtbl objects will convert to an integer via int(),
hex(), oct(), or bin(), yielding the base value.

The addition of these operators presents another breaking change to the
previous version.  Previously, symbol adjustments or rebases affected
the tracked offsets and caused symbols to shift around in linked tables
as well.  Since these operators now preserve the state of their source
object, this is no longer the case.  The amount of shift due to
adjustment or rebasing is localized in a specific Symtbl instance (and
is affected the the use of the related operators), however this value is
inherited by derivatives of that object.

There is a third breaking change caused by the use of operators as well.
Previously, the map() function allowed the caller to specify that the
given absolute address is not that of the table base, but of some offset
in the table, from which the new base is calculated.  However, the
remapping operators take only a single numeric value as their right hand
side operand, which is the absolute or relative address.  The new
intended way of accomplishing this (which is _nearly_ equivalent) is
through the combined use of the rebase and remap operations:

    # The address of the puts() function in a libc tbl is leaked
    sym = sym % sym.puts @ leak

aka: adjust offsets such that the known point is at the base, then move
that base to the known location.  The way in which this is different to
what you would end up with before is that previously, following a
map(abs, off) the base of the table would be accurately valued
according to the known information.  Now, the 'base' is considered to be
the leaked value, but internal offsets are shifted such that they still
resolve correctly.

Finally, a few new pieces of functionality are added to build out the
container API:

    - symbol key deletion
    - iteration over symbol:offset pairs
    - can now check for symbol existence with the "in" keyword
    - len(symtbl) returns the number of symbols defined

Signed-off-by: Malfurious &lt;m@lfurio.us&gt;
Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This effort was triggered by three immediate wants of the module:

    An improved data container interface to support things like key
    iteration and better key management.  This is primarily wanted by
    the ROP module (which is still in development).

    The introduction of package documentation across the project.  This
    module is now fully documented.

    To fix a bug in the Symtbl constructor, which would not allow a
    caller to supply "self" as an initial symbol name, even though it is
    legal in every other context.  This problem was caused by the
    constructor's bound instance parameter sharing this name.

This patch addresses all of these concerns, and also introduces some
fringe / QoL improvements that were discovered during the API refactor.

Element access may now be done via subscripting, as well as the previous
(and still generally perferred) .attribute notation.  The syntax for
storing subtables within a parent Symtbl is now greatly streamlined due
to some implementation-level changes to the class.  You may now directly
assign just a Symtbl object or a normal int, and you don't have to fuss
with tuples anymore.  The subtable's base is taken as its offset in the
parent, and the new operator replacement for the .map() method may be
used to define a desired value for the parent.

This detail is actually a breaking change compared to the previous
version.  While not technically a bug, it is unintuitive that the
previous version would not remove subtables when their offset was
changed by a simple assignment - the table would just move.  This patch
make it such that any symbol assignment to a regular int will replace an
old mounted subtable if one exists.

There are now no normal instance methods on the Symtbl type (only dunder
method overrides).  This is to free up the available symbol namespace as
much as possible.  The previous methods map(), adjust(), and rebase()
are now implemented as operators which, in every case, yield a new
derivative object, rather than mutating the original.  All operators are
listed here:

    @   remap to absolute address
    +   remap to relative address
    -   remap to negated relative address
    &gt;&gt;  adjust all symbol offsets upward
    &lt;&lt;  adjust all symbol offsets downward
    %   rebase all symbol offsets around an absolute zero point

Additionally, Symtbl objects will convert to an integer via int(),
hex(), oct(), or bin(), yielding the base value.

The addition of these operators presents another breaking change to the
previous version.  Previously, symbol adjustments or rebases affected
the tracked offsets and caused symbols to shift around in linked tables
as well.  Since these operators now preserve the state of their source
object, this is no longer the case.  The amount of shift due to
adjustment or rebasing is localized in a specific Symtbl instance (and
is affected the the use of the related operators), however this value is
inherited by derivatives of that object.

There is a third breaking change caused by the use of operators as well.
Previously, the map() function allowed the caller to specify that the
given absolute address is not that of the table base, but of some offset
in the table, from which the new base is calculated.  However, the
remapping operators take only a single numeric value as their right hand
side operand, which is the absolute or relative address.  The new
intended way of accomplishing this (which is _nearly_ equivalent) is
through the combined use of the rebase and remap operations:

    # The address of the puts() function in a libc tbl is leaked
    sym = sym % sym.puts @ leak

aka: adjust offsets such that the known point is at the base, then move
that base to the known location.  The way in which this is different to
what you would end up with before is that previously, following a
map(abs, off) the base of the table would be accurately valued
according to the known information.  Now, the 'base' is considered to be
the leaked value, but internal offsets are shifted such that they still
resolve correctly.

Finally, a few new pieces of functionality are added to build out the
container API:

    - symbol key deletion
    - iteration over symbol:offset pairs
    - can now check for symbol existence with the "in" keyword
    - len(symtbl) returns the number of symbols defined

Signed-off-by: Malfurious &lt;m@lfurio.us&gt;
Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>symtbl: Rename file to match class name</title>
<updated>2023-02-24T08:39:04+00:00</updated>
<author>
<name>Malfurious</name>
<email>m@lfurio.us</email>
</author>
<published>2023-02-22T20:01:22+00:00</published>
<link rel='alternate' type='text/html' href='http://normalmode.org/malf/nsploit/commit/?id=a4543a9ffcc52f205a8c2aaa56909acda4e9d0b1'/>
<id>a4543a9ffcc52f205a8c2aaa56909acda4e9d0b1</id>
<content type='text'>
I assume that the preferred style is to leave one major class each to a
file.  In this case, synchronize the names of the Symtbl class and its
containing module.  Per PEP8, the module is lowercase, and the class
remains Pascal case.

If other memory-oriented utilities are introduced in the future, we may
wish to move them, as well as Symtbl, back into a subpackage named
'mem'.

Signed-off-by: Malfurious &lt;m@lfurio.us&gt;
Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
I assume that the preferred style is to leave one major class each to a
file.  In this case, synchronize the names of the Symtbl class and its
containing module.  Per PEP8, the module is lowercase, and the class
remains Pascal case.

If other memory-oriented utilities are introduced in the future, we may
wish to move them, as well as Symtbl, back into a subpackage named
'mem'.

Signed-off-by: Malfurious &lt;m@lfurio.us&gt;
Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Add the version to the splash screen</title>
<updated>2023-02-24T03:52:58+00:00</updated>
<author>
<name>dusoleil</name>
<email>howcansocksbereal@gmail.com</email>
</author>
<published>2023-02-23T10:41:54+00:00</published>
<link rel='alternate' type='text/html' href='http://normalmode.org/malf/nsploit/commit/?id=f8cabdb49cbbc993790efd0d9844cde3d4617347'/>
<id>f8cabdb49cbbc993790efd0d9844cde3d4617347</id>
<content type='text'>
Print the current version (sourced from git describe) when sploit
starts up.

Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
Reviewed-by: Malfurious &lt;m@lfurio.us&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Print the current version (sourced from git describe) when sploit
starts up.

Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
Reviewed-by: Malfurious &lt;m@lfurio.us&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Dynamically source version in toml from git</title>
<updated>2023-02-24T03:52:57+00:00</updated>
<author>
<name>dusoleil</name>
<email>howcansocksbereal@gmail.com</email>
</author>
<published>2023-02-23T10:29:21+00:00</published>
<link rel='alternate' type='text/html' href='http://normalmode.org/malf/nsploit/commit/?id=9f4648dae644f2fb9deb4c68859d6cdfd0bc0530'/>
<id>9f4648dae644f2fb9deb4c68859d6cdfd0bc0530</id>
<content type='text'>
Instead of hard-coding the version into the pyproject.toml, we can
dynamically source it at build time.  Ideally, we want to use git
describe as a single authority source on the version.  The version is
stored in sploit.__version__ and can be consumed during sploit runtime
or during a build/package to populate the project's core metadata
version in the toml file.

hatchling provides a tool.hatch.version plugin that can read out the
variable during a build/package.  Because this variable is populated
from a git command, if the source tree isn't in a git repo, it will
fail.  In this case, sploit will report a PEP 440 compliant fake version
"0+unknown.version" to let the user know.

Because a packaged distribution doesn't exist in a git repo, we want to
bake in the version at build time into the package.  hatchling provides
a plugin to help with this, but it had some technical limitations that
didn't quite work for our use case.  Instead, I added a custom build
hook which will take the version sourced from the package (and by proxy
the git command), and overwrite the __init__.py with a hard-coded
version in the __version__ variable. This means that built/packaged
distributions of this project will have a fixed version hard-coded in
rather than dynamically sourcing from git.

The build hook operates just before the build executes.  It seems that
most build/packager front-ends (e.g. build, pip) will just run it in the
current source tree rather than making a temp copy.  This means that
when we modify the __init__.py, it is modifying our git tree.  Ideally,
we want this to be restored at the end of the build.  The build hook
interface allows us to write a hook that happens after the build, but it
won't run in the case of a crash or failed build.  Instead, I added a
custom solution to this using a member variable deconstructor.  If the
build ends in any way, the original contents of __init__.py are written
back out.

Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
Reviewed-by: Malfurious &lt;m@lfurio.us&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Instead of hard-coding the version into the pyproject.toml, we can
dynamically source it at build time.  Ideally, we want to use git
describe as a single authority source on the version.  The version is
stored in sploit.__version__ and can be consumed during sploit runtime
or during a build/package to populate the project's core metadata
version in the toml file.

hatchling provides a tool.hatch.version plugin that can read out the
variable during a build/package.  Because this variable is populated
from a git command, if the source tree isn't in a git repo, it will
fail.  In this case, sploit will report a PEP 440 compliant fake version
"0+unknown.version" to let the user know.

Because a packaged distribution doesn't exist in a git repo, we want to
bake in the version at build time into the package.  hatchling provides
a plugin to help with this, but it had some technical limitations that
didn't quite work for our use case.  Instead, I added a custom build
hook which will take the version sourced from the package (and by proxy
the git command), and overwrite the __init__.py with a hard-coded
version in the __version__ variable. This means that built/packaged
distributions of this project will have a fixed version hard-coded in
rather than dynamically sourcing from git.

The build hook operates just before the build executes.  It seems that
most build/packager front-ends (e.g. build, pip) will just run it in the
current source tree rather than making a temp copy.  This means that
when we modify the __init__.py, it is modifying our git tree.  Ideally,
we want this to be restored at the end of the build.  The build hook
interface allows us to write a hook that happens after the build, but it
won't run in the case of a crash or failed build.  Instead, I added a
custom solution to this using a member variable deconstructor.  If the
build ends in any way, the original contents of __init__.py are written
back out.

Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
Reviewed-by: Malfurious &lt;m@lfurio.us&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>comm: Localize stdin nonblock to interact's readall</title>
<updated>2023-02-19T01:30:10+00:00</updated>
<author>
<name>dusoleil</name>
<email>howcansocksbereal@gmail.com</email>
</author>
<published>2023-02-19T01:30:10+00:00</published>
<link rel='alternate' type='text/html' href='http://normalmode.org/malf/nsploit/commit/?id=eb8e5caaca1349bc10a61b1fa58f3d9b31df7e13'/>
<id>eb8e5caaca1349bc10a61b1fa58f3d9b31df7e13</id>
<content type='text'>
In interact(), we set stdin to be nonblocking for the duration of the
function.  As an unexpected side-effect, this was setting stdout to be
nonblocking as well.  This has caused at least one crash in the past.

Localizing the nonblock to just when we're reading from stdin should
solve this.

Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In interact(), we set stdin to be nonblocking for the duration of the
function.  As an unexpected side-effect, this was setting stdout to be
nonblocking as well.  This has caused at least one crash in the past.

Localizing the nonblock to just when we're reading from stdin should
solve this.

Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Use buffered read throughout Comm</title>
<updated>2023-02-18T19:33:14+00:00</updated>
<author>
<name>dusoleil</name>
<email>howcansocksbereal@gmail.com</email>
</author>
<published>2023-02-18T19:33:14+00:00</published>
<link rel='alternate' type='text/html' href='http://normalmode.org/malf/nsploit/commit/?id=1130206afaf5a4cf192c8cb3626ed475930b07bb'/>
<id>1130206afaf5a4cf192c8cb3626ed475930b07bb</id>
<content type='text'>
We had originally decided to use the os.read() function instead of the
actual buffered file object's read function.  This was due to the
blocking behavior or os.read() being closer to POSIX read than the other
function.

As it turns out, os.read() is an unbuffered read.  Every other read call
in this interface is buffered.  This causes some undefined behavior in
certain cases and leads to some really confusing bugs.

After some discussion, we've decided that, in this application's domain,
the blocking behavior of the buffered file object's read is actually
often more useful anyways.  Changing this call will deal with both
issues.

Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We had originally decided to use the os.read() function instead of the
actual buffered file object's read function.  This was due to the
blocking behavior or os.read() being closer to POSIX read than the other
function.

As it turns out, os.read() is an unbuffered read.  Every other read call
in this interface is buffered.  This causes some undefined behavior in
certain cases and leads to some really confusing bugs.

After some discussion, we've decided that, in this application's domain,
the blocking behavior of the buffered file object's read is actually
often more useful anyways.  Changing this call will deal with both
issues.

Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Read once at the beginning of interact mode.</title>
<updated>2023-02-18T19:29:05+00:00</updated>
<author>
<name>dusoleil</name>
<email>howcansocksbereal@gmail.com</email>
</author>
<published>2023-02-18T19:29:05+00:00</published>
<link rel='alternate' type='text/html' href='http://normalmode.org/malf/nsploit/commit/?id=5fc3b61980e3f964b4d3834d31844ccb76986ba4'/>
<id>5fc3b61980e3f964b4d3834d31844ccb76986ba4</id>
<content type='text'>
This behavior was accidentally removed in dcba5f2

interact mode works by polling for IO events, but it will miss any
unread data already in the buffer when it is first entered.  We can
ensure this gets caught by just doing a read once at the beginning.

Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This behavior was accidentally removed in dcba5f2

interact mode works by polling for IO events, but it will miss any
unread data already in the buffer when it is first entered.  We can
ensure this gets caught by just doing a read once at the beginning.

Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>comm: Strip \n character from readline()</title>
<updated>2023-02-18T19:06:32+00:00</updated>
<author>
<name>Malfurious</name>
<email>m@lfurio.us</email>
</author>
<published>2023-02-17T22:17:04+00:00</published>
<link rel='alternate' type='text/html' href='http://normalmode.org/malf/nsploit/commit/?id=d69fc63e9f41acd95f12b20bea305125cb574eb0'/>
<id>d69fc63e9f41acd95f12b20bea305125cb574eb0</id>
<content type='text'>
Line-oriented reads now strip the newline from the end of their returned
string.  Additionally, readall() strips the newline, but only from the
string that gets logged to the user's terminal (goodbye to all the "\n"
printed at the end of each line).

Of course, these functions are called by other parts of the read API and
have downstream effects.  Consideration was given to the entire API with
these rules in mind:

    - Raw reads (or non-line-oriented reads) will not filter ANY of
      their read content.  They are logged to the screen as one "line"
      of log text with \n characters shown in-place (not actually
      resetting the terminal cursor).  If reading binary, these bytes
      dont actually mean line termination anyway.

      functions: read, readall(_nonblock) *, readuntil

    - Line-oriented reads will strip the terminating \n, log the single
      line to the screen, and return it.

      functions: readline, readlineuntil **

* readall(_nonblock) functions turn out to be a special case.  They will
operate as raw reads, returning a blob of content.  However, we
generally want to run them on line-oriented input, so they log according
to the line-oriented rules.

** Although content returned from readlineuntil will have \n's stripped,
the lines are returned in an array, so we can still distinguish them.

Signed-off-by: Malfurious &lt;m@lfurio.us&gt;
Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Line-oriented reads now strip the newline from the end of their returned
string.  Additionally, readall() strips the newline, but only from the
string that gets logged to the user's terminal (goodbye to all the "\n"
printed at the end of each line).

Of course, these functions are called by other parts of the read API and
have downstream effects.  Consideration was given to the entire API with
these rules in mind:

    - Raw reads (or non-line-oriented reads) will not filter ANY of
      their read content.  They are logged to the screen as one "line"
      of log text with \n characters shown in-place (not actually
      resetting the terminal cursor).  If reading binary, these bytes
      dont actually mean line termination anyway.

      functions: read, readall(_nonblock) *, readuntil

    - Line-oriented reads will strip the terminating \n, log the single
      line to the screen, and return it.

      functions: readline, readlineuntil **

* readall(_nonblock) functions turn out to be a special case.  They will
operate as raw reads, returning a blob of content.  However, we
generally want to run them on line-oriented input, so they log according
to the line-oriented rules.

** Although content returned from readlineuntil will have \n's stripped,
the lines are returned in an array, so we can still distinguish them.

Signed-off-by: Malfurious &lt;m@lfurio.us&gt;
Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>comm: Add default argument for writeline()</title>
<updated>2023-02-18T19:06:32+00:00</updated>
<author>
<name>Malfurious</name>
<email>m@lfurio.us</email>
</author>
<published>2023-02-17T22:17:03+00:00</published>
<link rel='alternate' type='text/html' href='http://normalmode.org/malf/nsploit/commit/?id=9635fefa61f889da10feabfdd43be90e5701f314'/>
<id>9635fefa61f889da10feabfdd43be90e5701f314</id>
<content type='text'>
The writeline function will now default to send an empty line when
called without an argument.  I don't believe any such default makes
sense for the plain write function, as writing nothing should have no
effect.

Signed-off-by: Malfurious &lt;m@lfurio.us&gt;
Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The writeline function will now default to send an empty line when
called without an argument.  I don't believe any such default makes
sense for the plain write function, as writing nothing should have no
effect.

Signed-off-by: Malfurious &lt;m@lfurio.us&gt;
Signed-off-by: dusoleil &lt;howcansocksbereal@gmail.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
