MHL kindly pointed out that the string wasn't truncating, and it turns
out I misread the struct documentation, which truncates or pads with
\x00s to ensure the appropriate length. We now truncate to the first
null we find.
This template type allows objects that have not been able to be resolved
to exist within the symbol system. It emits a debug message on creation
so that intermediate format developers can identify potential issues,
but does not raise an exception so as to allow partial tables to be
used.
If the UnresolvedTemplate is called (to create an object) before the
symbol has been added to the symbolspace, it will fail with a
SymbolError (as thrown by the individual SymbolTable). For this reason,
the class has been made private to the SymbolSpace class to prevent
unexpected use.
Since a Union is identical to a Struct (and at the moment a struct
doesn't enforce non-overlapping members), these are identical and a
Union is a descendent of Struct. If this ever becomes a problem there
is a filthy way to fix it, but it's really bad and will likely cause
more subtle and difficult to diagnose problems. Stick with inheritance.
This is in contrast to volatility-2.x where object were automatically
instantiated with a native_vm (or native_layer in 3.x parlance) and then
any dereferences occurred in the correct layer.
The space savings are now minimal since each object carries around only
a layer name, and not a reference to the entire space. However, given
situations such as kernel structures containing pointers into
process spaces, where the native_vm is useless, this decision is
designed to make working on a particular layer explicit and therefore
more obvious. It may mean exposing that up through levels of functions,
but hopefully it will make all the code more obvious and less
automagical.