PFP - Python Format Parser¶
Pfp (python format parser) is a python interpreter for 010 Editor template scripts.
Pfp uses py010parser to parse 010 templates into an AST, which is then interpreted by pfp. Pfp then returns a DOM object which can be used to access individual fields of the defined data structure.
Please read the Getting Started section for a better introduction.
TL;DR¶
Installation¶
pip install pfp
Console Script¶
Pfp comes with a console script that will print parsed data:
$> pfp --help
usage: pfp [-h] -t TEMPLATE [--show-offsets] [-k] input
Run pfp on input data using a specified 010 Editor template for parsing
positional arguments:
input The input data stream or file to parse. Use '-' for
piped data
optional arguments:
-h, --help show this help message and exit
-t TEMPLATE, --template TEMPLATE
The template to parse with
--show-offsets Show offsets in the parsed data of parsed fields
-k, --keep Keep successfully parsed data on error
Example usages:
pfp --keep -t png.bt test.png
cat test.png | pfp --keep -t png.bt -
pfp --keep -t png.bt - <test.png
PNG Parsing Example¶
Below is a simple PNG template that will parse the PNG image into chunks.
The tEXt
chunk of the PNG image will also specifically be parsed:
typedef struct {
// null-terminated
string label;
char comment[length - sizeof(label)];
} TEXT;
typedef struct {
uint length<watch=data, update=WatchLength>;
char cname[4];
union {
char raw[length];
if(cname == "tEXt") {
TEXT tEXt;
}
} data;
uint crc<watch=cname;data, update=WatchCrc32>;
} CHUNK;
uint64 magic;
while(!FEof()) {
CHUNK chunks;
}
The python code below will use the template above to parse a PNG image,
find the tEXt
chunk, and change the comment:
import pfp
dom = pfp.parse(data_file="image.png", template_file="png_template.bt")
for chunk in png.chunks:
if chunk.cname == "tEXt":
print("Comment before: {}".format(chunk.data.tEXt.comment))
chunk.data.tEXt.comment = "NEW COMMENT"
print("Comment after: {}".format(chunk.data.tEXt.comment))
Notes¶
A few differences do exist between 010 Editor and pfp. See the Differences Between 010 and pfp section for specific, documented differences.
Contents:
-
pfp.
create_interp
(template_file=None, template=None)[source]¶ Create an Interp instance with the template preloaded
Template: template contents (str) Template_file: template file path Returns: Interp
-
pfp.
parse
(data=None, template=None, data_file=None, template_file=None, interp=None, debug=False, predefines=True, int3=True, keep_successful=False, printf=True)[source]¶ Parse the data stream using the supplied template. The data stream WILL NOT be automatically closed.
Data: Input data, can be either a string or a file-like object (StringIO, file, etc) Template: template contents (str) Data_file: PATH to the data to be used as the input stream Template_file: template file path Interp: the interpretor to be used (a default one will be created if None
)Debug: if debug information should be printed while interpreting the template (false) Predefines: if built-in type information should be inserted (true) Int3: if debugger breaks are allowed while interpreting the template (true) Keep_successful: return any succesfully parsed data instead of raising an error. If an error occurred and keep_successful
is True, then_pfp__error
will be contain the exception objectPrintf: if False
, all calls toPrintf
(pfp.native.compat_interface.Printf
) will be noops. (default=``True``)Returns: pfp DOM