### Install tox Source: https://hachoir.readthedocs.io/en/latest/developer.html Install the tox automation tool if it is not already present in the environment. ```bash python3 -m pip install tox ``` -------------------------------- ### Install Hachoir Source: https://hachoir.readthedocs.io/en/latest/_sources/install.rst.txt Use this command to install the core Hachoir library. It is recommended to use pip for installation and to upgrade to the latest version. ```bash python3 -m pip install -U hachoir ``` -------------------------------- ### Install hachoir-wx Source: https://hachoir.readthedocs.io/en/latest/_sources/install.rst.txt Install the hachoir-wx component, which requires the wxPython library. Ensure wxPython is installed using pip. ```bash python3 -m pip install -U wxPython ``` -------------------------------- ### Install hachoir-urwid Source: https://hachoir.readthedocs.io/en/latest/_sources/install.rst.txt Install the hachoir-urwid component, which requires the urwid library. Ensure urwid is installed using pip. ```bash python3 -m pip install -U urwid ``` -------------------------------- ### Hachoir Metadata Example Source: https://hachoir.readthedocs.io/en/latest/_sources/developer.rst.txt Example demonstrating Hachoir's metadata parsing capabilities. This snippet is loaded from an external file. ```python .. literalinclude:: examples/metadata.py ``` -------------------------------- ### Hachoir Metadata Extraction Example Source: https://hachoir.readthedocs.io/en/latest/developer.html A Python code example demonstrating how to use Hachoir to parse a file and extract its metadata. ```APIDOC ## Hachoir Metadata Example ### Description This Python script demonstrates how to extract metadata from a file using Hachoir's parser and metadata extraction functionalities. ### Code Example ```python from hachoir.parser import createParser from hachoir.metadata import extractMetadata from sys import argv, stderr, exit if len(argv) != 2: print("usage: %s filename" % argv[0], file=stderr) exit(1) filename = argv[1] parser = createParser(filename) if not parser: print("Unable to parse file", file=stderr) exit(1) with parser: try: metadata = extractMetadata(parser) except Exception as err: print("Metadata extraction error: %s" % err) metadata = None if not metadata: print("Unable to extract metadata") exit(1) for line in metadata.exportPlaintext(): print(line) ``` ### Usage Run the script with a filename as an argument: ```bash python your_script_name.py ``` ``` -------------------------------- ### Find files in a hard drive Source: https://hachoir.readthedocs.io/en/latest/_sources/subfile.rst.txt Example output of searching a hard drive device with size limits and quiet mode. ```bash $ hachoir-subfile /dev/sda --size=34200100 --quiet [+] Start search (32.6 MB) [+] Found file at 0: MS-DOS hard drive with Master Boot Record (MBR) [+] Found file at 32256: FAT16 filesystem [+] Found file at 346112 size=308280 (301.1 KB): Microsoft Bitmap version 3 [+] Found file at 32157696: MS-DOS executable [+] Found file at 32483328: MS-DOS executable [+] Found file at 32800768: MS-DOS executable [+] Found file at 32851968: MS-DOS executable [+] Found file at 32872448: MS-DOS executable [+] Found file at 33058816: MS-DOS executable [+] Found file at 33112064: MS-DOS executable [+] Found file at 33142784: MS-DOS executable [+] Found file at 33949936: Microsoft Windows Portable Executable: Intel 80386 or greater [+] Search done -- offset=34200100 (32.6 MB) Total time: 20.08 sec -- 1.6 MB/sec ``` -------------------------------- ### Filter Metadata with --level Option Source: https://hachoir.readthedocs.io/en/latest/_sources/metadata.rst.txt This example shows how to limit the verbosity of the metadata output by using the --level option to skip information beyond a certain level. ```bash You can skip useless information (here, only until level 7):: ``` -------------------------------- ### Run tests with tox Source: https://hachoir.readthedocs.io/en/latest/_sources/hacking.rst.txt Executes the test suite using the tox automation tool. Requires tox to be installed via pip. ```bash tox ``` -------------------------------- ### Hachoir Code Download and Testing Source: https://hachoir.readthedocs.io/en/latest/developer.html Instructions on how to clone the Hachoir Git repository, navigate into the directory, and run tests using tox. It also includes instructions for installing tox if it's not already present. ```APIDOC ## Hachoir Code Download and Testing ### Description This section provides instructions for developers to clone the Hachoir Git repository, set up their environment, and run tests. ### Steps 1. **Clone the Git repository:** ```bash git clone https://github.com/vstinner/hachoir ``` 2. **Enter the Hachoir directory:** ```bash cd hachoir ``` 3. **Run tests using tox:** ```bash tox ``` 4. **Install tox if not already installed:** ```bash python3 -m pip install tox ``` ### See also Hachoir on the Travis CI. ``` -------------------------------- ### Analyze PowerPoint document Source: https://hachoir.readthedocs.io/en/latest/_sources/subfile.rst.txt Example output of searching a PowerPoint file for embedded images and other objects. ```bash $ hachoir-subfile chiens.PPS [+] Start search (828.5 KB) [+] Found file at 0: Microsoft Office document [+] Found file at 537 size=28449 (27.8 KB): JPEG picture: 433x300 pixels [+] Found file at 29011 size=34761 (33.9 KB): JPEG picture: 433x300 pixels [+] Found file at 63797 size=40326 (39.4 KB): JPEG picture: 433x300 pixels [+] Found file at 104148 size=30641 (29.9 KB): JPEG picture: 433x300 pixels [+] Found file at 134814 size=22782 (22.2 KB): JPEG picture: 384x325 pixels [+] Found file at 157621 size=24744 (24.2 KB): JPEG picture: 443x313 pixels [+] Found file at 182390 size=27241 (26.6 KB): JPEG picture: 443x290 pixels [+] Found file at 209656 size=27407 (26.8 KB): JPEG picture: 443x336 pixels [+] Found file at 237088 size=30088 (29.4 KB): JPEG picture: 388x336 pixels [+] Found file at 267201 size=30239 (29.5 KB): JPEG picture: 366x336 pixels [+] Found file at 297465 size=81634 (79.7 KB): JPEG picture: 630x472 pixels [+] Found file at 379124 size=36142 (35.3 KB): JPEG picture: 599x432 pixels [+] Found file at 415291 size=28801 (28.1 KB): JPEG picture: 443x303 pixels [+] Found file at 444117 size=28283 (27.6 KB): JPEG picture: 433x300 pixels [+] Found file at 472425 size=95913 (93.7 KB): PNG picture: 433x431x8 [+] Found file at 568363 size=219252 (214.1 KB): PNG picture: 532x390x8 [+] Found file at 811308 size=20644 (20.2 KB): Microsoft Windows Metafile (WMF) picture [+] Search done -- offset=848384 (828.5 KB) Total time: 1.30 sec -- 635.1 KB/sec ``` -------------------------------- ### Apply regex repetition Source: https://hachoir.readthedocs.io/en/latest/_sources/regex.rst.txt Examples of parsing regular expressions that involve repetition operators. ```python >>> parse("(a{2,}){3,4}") >>> parse("(a*|b)*") >>> parse("(a*|b|){4,5}") ``` -------------------------------- ### Extract Default Metadata from PNG Image Source: https://hachoir.readthedocs.io/en/latest/_sources/metadata.rst.txt This example demonstrates the default output of hachoir-metadata when run on a PNG image file, showing various image properties. ```bash $ hachoir-metadata logo-Kubuntu.png Image: - Image width: 331 - Image height: 90 - Bits/pixel: 8 - Image format: Color index - Creation date: 2006-05-26 09:41:46 - Compression: deflate - MIME type: image/png - Endian: Big endian ``` -------------------------------- ### Extract Metadata from AVI Video Source: https://hachoir.readthedocs.io/en/latest/_sources/metadata.rst.txt This example shows how to extract detailed metadata from an AVI video file using the hachoir-metadata program. It displays information about common properties, video stream, and audio stream. ```bash $ hachoir-metadata pacte_des_gnous.avi Common: - Duration: 4 min 25 sec - Comment: Has audio/video index (248.9 KB) - MIME type: video/x-msvideo - Endian: Little endian Video stream: - Image width: 600 - Image height: 480 - Bits/pixel: 24 - Compression: DivX v4 (fourcc:"divx") - Frame rate: 30.0 Audio stream: - Channel: stereo - Sample rate: 22.1 KHz - Compression: MPEG Layer 3 ``` -------------------------------- ### View metadata after stripping Source: https://hachoir.readthedocs.io/en/latest/strip.html After using hachoir-strip, use hachoir-metadata again on the new file to verify that the desired information has been removed. This example shows the file after 'creation date' and 'producer' metadata were stripped. ```bash $ hachoir-metadata KDE_Click.wav.new Common: - MIME type: audio/x-wav - Endian: Little endian Audio: - Duration: 39 ms ... ``` -------------------------------- ### Lazy Feature Example Source: https://hachoir.readthedocs.io/en/latest/_sources/developer.rst.txt Demonstrates Hachoir's lazy parsing behavior by showing how fields and values are only read when explicitly requested. ```APIDOC ## Lazy Feature Example ### Description This example illustrates Hachoir's lazy parsing. Fields and values are not processed until they are accessed, optimizing performance by avoiding unnecessary computations. ### Method Python interactive session ### Endpoint N/A ### Parameters N/A ### Request Example ```python >>> root = MyFormat(stream) >>> (root.current_length, root.current_size) (0, 0) >>> print(root["signature"].display) "MYF" >>> (root.current_length, root.current_size, root["signature"].size) (1, 24, 24) >>> print(root["point[0]/letter"].display) 'a' >>> (root.current_length, root.current_size) (3, 48) ``` ### Response #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Search for Patterns with PatternMatching Source: https://hachoir.readthedocs.io/en/latest/regex.html Use the search() method to find all occurrences of added patterns in a string. The output provides start and end indices along with the matched pattern object. ```python for start, end, item in p.search("a b c d"): print("%s..%s: %s" % (start, end, item)) ``` -------------------------------- ### Accessing Fields and Checking Length in Hachoir Source: https://hachoir.readthedocs.io/en/latest/_sources/internals.rst.txt Demonstrates accessing fields of a custom Hachoir parser and checking the current length of parsed fields. This example shows how accessing a field can trigger its creation and update the stream's parsed length. ```python from hachoir.stream import StringInputStream stream = StringInputStream(b"\x2A\x00\x04\x05") p = Point(stream) print(p.current_length) x = p["x"].value print(p.current_length) ``` -------------------------------- ### Verify Field Size Computation in Hachoir Source: https://hachoir.readthedocs.io/en/latest/_sources/internals.rst.txt Verify that the size attribute of Hachoir fields is computed correctly for both static and dynamic size parsers. This example also checks that no data is read from the stream until explicitly accessed. ```python from hachoir.stream import StringInputStream # Assuming FourBytes and DynamicSize classes are defined as above stream = StringInputStream(b"\x2A\x00\x04\x05") a = FourBytes(stream) b = DynamicSize(stream, 1) print(a.size, b.size) print(a.current_length, b.current_length) ``` -------------------------------- ### Set Endianness for Hachoir Parser Source: https://hachoir.readthedocs.io/en/latest/_sources/internals.rst.txt Demonstrates how to set the endianness for a Hachoir parser by defining the 'endian' class attribute. This example uses LITTLE_ENDIAN, showing how to specify byte order for fields within the parser. ```python from hachoir.field import Parser from hachoir.core.endian import LITTLE_ENDIAN class UseLittleEndian(Parser): endian = LITTLE_ENDIAN ``` -------------------------------- ### Define Dynamic Size Field in Hachoir Source: https://hachoir.readthedocs.io/en/latest/_sources/internals.rst.txt Define a custom field parser 'DynamicSize' with a dynamically calculated size. This example shows how to set the '_size' instance attribute in the constructor based on external parameters, such as the number of items. ```python from hachoir.field import Parser, Integer from hachoir.core.endian import BIG_ENDIAN class DynamicSize(Parser): endian = BIG_ENDIAN def __init__(self, stream, nb_items): Parser.__init__(self, stream) assert 0 < nb_items self.nb_items = nb_items self._size = nb_items * 32 # 32 is the size of one item def createFields(self): for index in range(self.nb_items): yield Integer(self, "item[]", "uint32") ``` -------------------------------- ### Define Custom Field Parser in Hachoir Source: https://hachoir.readthedocs.io/en/latest/_sources/internals.rst.txt Define a custom field parser 'Point' by inheriting from Hachoir's Parser class. This example shows how fields are created dynamically based on conditions within the constructor and createFields method. It demonstrates accessing fields by name and conditional field creation. ```python from hachoir.field import Parser, Int8 from hachoir.core.endian import BIG_ENDIAN class Point(Parser): endian = BIG_ENDIAN def __init__(self, stream): Parser.__init__(self, stream) if self["color"].value == -1: self._description += " (no color)" def createFields(self): yield Int8(self, "color", "Point color (-1 for none)") yield Int8(self, "use_3d", "Does it use Z axis?") yield Int8(self, "x", "X axis value") yield Int8(self, "y", "Y axis value") if self["use_3d"] == 1: yield Int8(self, "z", "Z axis value") ``` -------------------------------- ### Add Patterns to PatternMatching Source: https://hachoir.readthedocs.io/en/latest/regex.html Initialize PatternMatching and add string and regex patterns. Use this to set up patterns before searching. ```python from hachoir.regex import PatternMatching p = PatternMatching() p.addString("a") p.addString("b") p.addRegex("[cd]") ``` -------------------------------- ### Initialize a Parser and access fields Source: https://hachoir.readthedocs.io/en/latest/internals.html Shows how field list length grows as specific fields are accessed from the stream. ```python >>> from hachoir.stream import StringInputStream >>> stream = StringInputStream(b"\x2A\x00\x04\x05") >>> p = Point(stream) >>> p.current_length 1 ``` ```python >>> x = p["x"].value >>> p.current_length 3 ``` -------------------------------- ### Accessing fields using path syntax Source: https://hachoir.readthedocs.io/en/latest/internals.html Demonstrates various path syntaxes for navigating the field tree relative to the current node or the root. ```python field["content"] ``` ```python field["../brother"] ``` ```python field["/header/key"] ``` -------------------------------- ### Initialize pattern matching Source: https://hachoir.readthedocs.io/en/latest/regex.html Sets up a PatternMatching object to search for multiple strings or regex patterns. ```python >>> from hachoir.regex import PatternMatching >>> p = PatternMatching() >>> p.addString("a") >>> p.addString("b") >>> p.addRegex("[cd]") ``` -------------------------------- ### Define static and dynamic size parsers Source: https://hachoir.readthedocs.io/en/latest/internals.html Illustrates using static_size for fixed-length parsers and setting _size in the constructor for dynamic-length parsers. ```python >>> from hachoir.field import Parser >>> class FourBytes(Parser): ... endian = BIG_ENDIAN ... static_size = 32 ... def createFields(self): ... yield Integer(self, "four", "uint32") ... >>> class DynamicSize(Parser): ... endian = BIG_ENDIAN ... def __init__(self, stream, nb_items): ... Parser.__init__(self, stream) ... assert 0 < nb_items ... self.nb_items = nb_items ... self._size = nb_items * 32 # 32 is the size of one item ... ... def createFields(self): ... for index in range(self.nb_items): ... yield Integer(self, "item[]", "uint32") ... >>> a = FourBytes(stream) >>> b = DynamicSize(stream, 1) >>> a.size, b.size (32, 32) >>> # Check that nothing is really read from stream ... a.current_length, b.current_length (0, 0) ``` -------------------------------- ### Initialize HachoirSubfile with Metadata Filter Source: https://hachoir.readthedocs.io/en/latest/_sources/subfile.rst.txt This snippet demonstrates how to create a HachoirSubfile object and apply a metadata filter to it. This is useful for processing specific parts of a file based on metadata criteria. ```python subfile = HachoirSubfile(...) subfile.filter = metadataFilter ``` -------------------------------- ### List All Strings in a Binary File Source: https://hachoir.readthedocs.io/en/latest/_sources/grep.rst.txt Use the --all option to list all identifiable strings within a binary file. This command helps in quickly surveying the textual content of a file. ```bash $ .hachoir-grep --all sheep_on_drugs.mp3 ``` -------------------------------- ### Create a RegexRange Source: https://hachoir.readthedocs.io/en/latest/_sources/regex.rst.txt Demonstrates the creation of a regex range object. ```python >>> regex = regex | createRange("4"); regex ``` -------------------------------- ### Define and use a basic parser Source: https://hachoir.readthedocs.io/en/latest/developer.html Create a custom parser class to interpret binary data as structured fields. ```python >>> from hachoir.field import Parser, CString, UInt16 >>> class Point(Parser): ... endian = LITTLE_ENDIAN ... def createFields(self): ... yield CString(self, "name", "Point name") ... yield UInt16(self, "x", "X coordinate") ... yield UInt16(self, "y", "Y coordinate") ... >>> point = Point(stream) >>> for field in point: ... print("%s) %s=%s" % (field.address, field.name, field.display)) ... 0) name="point" 48) x=3 64) y=2 ``` -------------------------------- ### Display File Type Description Source: https://hachoir.readthedocs.io/en/latest/_sources/metadata.rst.txt The --type option displays a short description of the file type, similar to the UNIX 'file' command. ```bash $ hachoir-metadata --type logo-Kubuntu.png sheep_on_drugs.mp3 wormux_32x32_16c.ico logo-Kubuntu.png: PNG picture: 331x90x8 (alpha layer) sheep_on_drugs.mp3: MPEG v1 layer III, 128.0 Kbit/sec, 44.1 KHz, Joint stereo wormux_32x32_16c.ico: Microsoft Windows icon: 16x16x32 ``` -------------------------------- ### Create and optimize regex Source: https://hachoir.readthedocs.io/en/latest/_sources/regex.rst.txt Demonstrates creating regex objects using string concatenation and parsing, which automatically triggers optimization. ```python >>> from hachoir.regex import parse, createRange, createString >>> createString("bike") + createString("motor") >>> parse('(foo|fooo|foot|football)') ``` -------------------------------- ### Extract file metadata Source: https://hachoir.readthedocs.io/en/latest/developer.html Demonstrates how to use createParser and extractMetadata to retrieve and print file information. ```python from hachoir.parser import createParser from hachoir.metadata import extractMetadata from sys import argv, stderr, exit if len(argv) != 2: print("usage: %s filename" % argv[0], file=stderr) exit(1) filename = argv[1] parser = createParser(filename) if not parser: print("Unable to parse file", file=stderr) exit(1) with parser: try: metadata = extractMetadata(parser) except Exception as err: print("Metadata extraction error: %s" % err) metadata = None if not metadata: print("Unable to extract metadata") exit(1) for line in metadata.exportPlaintext(): print(line) ``` -------------------------------- ### Define Static Size Field in Hachoir Source: https://hachoir.readthedocs.io/en/latest/_sources/internals.rst.txt Define a custom field parser 'FourBytes' with a statically defined size. This example shows how to use the 'static_size' class attribute to set a fixed size for the field, which is 32 bits in this case. ```python from hachoir.field import Parser, Integer from hachoir.core.endian import BIG_ENDIAN class FourBytes(Parser): endian = BIG_ENDIAN static_size = 32 def createFields(self): yield Integer(self, "four", "uint32") ``` -------------------------------- ### Associate User Data with Patterns Source: https://hachoir.readthedocs.io/en/latest/_sources/regex.rst.txt Demonstrates associating custom user values with patterns during the addition process. ```python >>> p2 = PatternMatching() >>> p2.addString("un", 1) >>> p2.addString("deux", 2) >>> p2.addRegex("(trois|three)", 3) >>> for start, end, item in p2.search("un deux trois"): ... print("%r at %s: user=%r" % (item, start, item.user)) ... at 0: user=1 at 3: user=2 at 8: user=3 ``` -------------------------------- ### Navigate to Hachoir directory Source: https://hachoir.readthedocs.io/en/latest/developer.html Change the current working directory to the cloned Hachoir folder. ```bash cd hachoir ``` -------------------------------- ### Edit gzip file to add extra data Source: https://hachoir.readthedocs.io/en/latest/_sources/editor.rst.txt Demonstrates using the editor module to inject extra data into a gzip file. ```python .. literalinclude:: examples/editor_add_extra.py ``` -------------------------------- ### Create character ranges Source: https://hachoir.readthedocs.io/en/latest/_sources/regex.rst.txt Shows how to build character ranges using the OR operator and the createRange function. ```python >>> regex = createString("1") | createString("3") >>> regex >>> regex |= createRange("2", "4") >>> regex ``` -------------------------------- ### Search with case sensitivity and path display Source: https://hachoir.readthedocs.io/en/latest/grep.html Use --path and --case flags to perform a case-sensitive search and include the internal field path for each match. ```bash $ hachoir-grep --path --case Car sheep_on_drugs.mp3 78:/id3v2/field[2]/content/text:Car music ``` -------------------------------- ### Apply regex operators Source: https://hachoir.readthedocs.io/en/latest/_sources/regex.rst.txt Demonstrates the use of AND and OR operators for combining regex objects. ```python >>> createString("bike") & createString("motor") >>> createString("bike") | createString("motor") >>> createString("big ") + createString("bike") >>> r=parse('(cat|horse)') >>> r.minLength(), r.maxLength() (3, 5) ``` -------------------------------- ### Optimize regex groups Source: https://hachoir.readthedocs.io/en/latest/_sources/regex.rst.txt Shows how the library automatically optimizes regex expressions by grouping common prefixes. ```python >>> createString("blue") | createString("brown") >>> createString("moto") | parse("mot.") >>> parse("(ma|mb|mc)") >>> parse("(maa|mbb|mcc)") ``` -------------------------------- ### Display MIME Type of Files Source: https://hachoir.readthedocs.io/en/latest/_sources/metadata.rst.txt Use the --mime option to display the MIME type of specified files. This command is similar to the UNIX 'file --mime' command. ```bash $ hachoir-metadata --mime logo-Kubuntu.png sheep_on_drugs.mp3 wormux_32x32_16c.ico logo-Kubuntu.png: image/png sheep_on_drugs.mp3: audio/mpeg wormux_32x32_16c.ico: image/x-ico ``` -------------------------------- ### Search Substring with Case Sensitivity and Path Display Source: https://hachoir.readthedocs.io/en/latest/_sources/grep.rst.txt Conduct a case-sensitive search for a substring and display the full path to the string within the file structure. This is useful for precise searching and understanding the context of the match. ```bash $ hachoir-grep --path --case Car sheep_on_drugs.mp3 ``` -------------------------------- ### hachoir.field: Basic Parser Source: https://hachoir.readthedocs.io/en/latest/developer.html Illustrates how to define and use a basic parser in Hachoir to parse custom data structures, demonstrating field creation and access. ```APIDOC ## hachoir.field: Basic Parser ### Description This section demonstrates how to create a custom parser using Hachoir's `Parser` class to define and parse structured data. It shows how to define fields like `CString` and `UInt16` and access their properties. ### Code Example ```python >>> from hachoir.field import Parser, CString, UInt16 >>> from hachoir.stream import LITTLE_ENDIAN >>> # Assuming 'stream' is an initialized Hachoir stream object >>> # For demonstration, let's recreate the stream from the previous example: >>> data = b"point\x00\x03\x00\x02\x00" >>> from hachoir.stream import StringInputStream >>> stream = StringInputStream(data) >>> class Point(Parser): ... endian = LITTLE_ENDIAN ... def createFields(self): ... yield CString(self, "name", "Point name") ... yield UInt16(self, "x", "X coordinate") ... yield UInt16(self, "y", "Y coordinate") ... >>> point = Point(stream) >>> for field in point: ... print(f"{field.address}) {field.name}={field.display}") ... 0) name="point" 48) x=3 64) y=2 >>> # Accessing field properties >>> x = point["x"] >>> x.path '/x' >>> x.value 3 >>> x.parent == point True >>> x.description 'X coordinate' >>> x.index 1 >>> x.address, x.absolute_address (48, 48) ``` ### Key Concepts - Define custom parsers by inheriting from `hachoir.field.Parser`. - Use `createFields` method to define the structure of the data. - Hachoir fields have attributes like `address`, `name`, `display`, `path`, `value`, `parent`, `description`, `index`, and `absolute_address`. ``` -------------------------------- ### Search for specific file types Source: https://hachoir.readthedocs.io/en/latest/_sources/subfile.rst.txt Commands to search for specific file formats or categories within an input stream. ```bash hachoir-subfile input --parser=jpeg ``` ```bash hachoir-subfile input --category=image ``` ```bash hachoir-subfile input --category=image,video --parser=swf ``` -------------------------------- ### Define a Parser with conditional fields Source: https://hachoir.readthedocs.io/en/latest/internals.html Demonstrates creating a custom Parser class where fields are generated dynamically based on previous field values. ```python >>> from hachoir.field import Parser, Int8 >>> from hachoir.core.endian import BIG_ENDIAN >>> class Point(Parser): ... endian = BIG_ENDIAN ... def __init__(self, stream): ... Parser.__init__(self, stream) ... if self["color"].value == -1: ... self._description += " (no color)" ... ... def createFields(self): ... yield Int8(self, "color", "Point color (-1 for none)") ... yield Int8(self, "use_3d", "Does it use Z axis?") ... yield Int8(self, "x", "X axis value") ... yield Int8(self, "y", "Y axis value") ... if self["use_3d"] == 1: ... yield Int8(self, "z", "Z axis value") ... ``` -------------------------------- ### Attach user data to patterns Source: https://hachoir.readthedocs.io/en/latest/_sources/regex.rst.txt Associates custom user data with patterns during the matching process. ```python >>> p = PatternMatching() >>> p.addString("un", 1) >>> p.addString("deux", 2) >>> for start, end, item in p.search("un deux"): ... print("%r at %s: user=%r" % (item, start, item.user)) ... at 0: user=1 at 3: user=2 ``` -------------------------------- ### Print All Decoded Fields with hachoir-list Source: https://hachoir.readthedocs.io/en/latest/_sources/list.rst.txt Use this command to display all decoded fields of a binary file. The output format is designed for easy parsing by text-oriented tools. ```bash $ hachoir-list cd_0008_5C48_1m53s.cda signature : "RIFF" filesize : 36 bytes type : "CDDA" cdda tag : "fmt " size : 24 bytes cda_version : 1 track_no : 4 disc_serial : 0008-5C48 hsg_offset : 19477 hsg_length : 8507 rb_offset frame : 52 second : 21 minute : 4 notused : "\0" rb_length frame : 32 second : 53 minute : 1 notused : "\0" ``` -------------------------------- ### Parse regex from strings Source: https://hachoir.readthedocs.io/en/latest/_sources/regex.rst.txt Creates regex objects by parsing standard regex string syntax. ```python >>> from hachoir.regex import parse >>> parse('') >>> parse('abc') >>> parse('[bc]d') >>> parse('a(b|[cd]|(e|f))g') >>> parse('([a-z]|[b-])') >>> parse('^^..$$') >>> parse('chats?') >>> parse(' +abc') ``` -------------------------------- ### String Stream Manipulation Source: https://hachoir.readthedocs.io/en/latest/_sources/developer.rst.txt Demonstrates basic stream manipulation using StringInputStream, including reading bytes and bits with specified endianness. Note that sizes and addresses are in bits. ```python data = b"point\x00\x03\x00\x02\x00" from hachoir.stream import StringInputStream, LITTLE_ENDIAN stream = StringInputStream(data) print(stream.source) print(len(data), stream.size) print(data[1:6], stream.readBytes(8, 5)) print(data[6:8], stream.readBits(6*8, 16, LITTLE_ENDIAN)) print(data[8:10], stream.readBits(8*8, 16, LITTLE_ENDIAN)) ``` -------------------------------- ### Search for a substring in a binary file Source: https://hachoir.readthedocs.io/en/latest/grep.html Provide a search string as an argument to locate matching content within the file. ```bash $ hachoir-grep "il" sheep_on_drugs.mp3 17:Bilmusik vol 1. Stainless Steel Providers 154:Stainless Steel Provider is compilated to the car of Twinstar. ``` -------------------------------- ### Clone Hachoir repository Source: https://hachoir.readthedocs.io/en/latest/developer.html Use this command to clone the Hachoir source code from GitHub. ```bash git clone https://github.com/vstinner/hachoir ``` -------------------------------- ### Store extracted subfiles Source: https://hachoir.readthedocs.io/en/latest/_sources/subfile.rst.txt Command to search for all subfiles and save them to a specified directory. ```bash hachoir-subfile input /tmp/subfiles/ ``` -------------------------------- ### Manipulate data streams Source: https://hachoir.readthedocs.io/en/latest/developer.html Shows how to use StringInputStream to read data at the bit level. ```python >>> data = b"point\0\3\0\2\0" >>> from hachoir.stream import StringInputStream, LITTLE_ENDIAN >>> stream = StringInputStream(data) >>> stream.source '' >>> len(data), stream.size (10, 80) >>> data[1:6], stream.readBytes(8, 5) (b'oint\x00', b'oint\x00') >>> data[6:8], stream.readBits(6*8, 16, LITTLE_ENDIAN) (b'\x03\x00', 3) >>> data[8:10], stream.readBits(8*8, 16, LITTLE_ENDIAN) (b'\x02\x00', 2) ``` -------------------------------- ### Configure Hachoir logging verbosity Source: https://hachoir.readthedocs.io/en/latest/developer.html Set the global configuration to quiet mode to suppress Hachoir output. ```python from hachoir.core import config config.quiet = True ``` -------------------------------- ### Apply regex operators Source: https://hachoir.readthedocs.io/en/latest/regex.html Uses logical operators to combine regex objects. ```python >>> createString("bike") & createString("motor") >>> createString("bike") | createString("motor") >>> createString("big ") + createString("bike") ``` -------------------------------- ### Run tests manually Source: https://hachoir.readthedocs.io/en/latest/_sources/hacking.rst.txt Executes the test suite directly using the provided Python script. ```python python3 runtests.py ``` -------------------------------- ### View metadata before stripping Source: https://hachoir.readthedocs.io/en/latest/strip.html Use hachoir-metadata to inspect the metadata of a file before applying hachoir-strip. This helps identify information that can be removed. ```bash $ hachoir-metadata KDE_Click.wav.new Common: - Creation date: 2001-02-21 <== here they are - Producer: Sound Forge 4.5 <== spy informations :-) - MIME type: audio/x-wav - Endian: Little endian Audio: - Duration: 39 ms ... ``` -------------------------------- ### Search multiple categories and specific parsers with hachoir-subfile Source: https://hachoir.readthedocs.io/en/latest/subfile.html Combine --category and --parser options to refine search criteria. This command searches for images and SWF files. ```bash hachoir-subfile input --category=image,video --parser=swf ``` -------------------------------- ### Define a hierarchical parser with sub-field sets Source: https://hachoir.readthedocs.io/en/latest/developer.html Create a nested structure by inheriting from FieldSet and yielding fields within createFields. ```python >>> from hachoir.field import FieldSet, UInt8, Character, String >>> class Entry(FieldSet): ... def createFields(self): ... yield Character(self, "letter") ... yield UInt8(self, "code") ... >>> class MyFormat(Parser): ... endian = LITTLE_ENDIAN ... def createFields(self): ... yield String(self, "signature", 3, charset="ASCII") ... yield UInt8(self, "count") ... for index in range(self["count"].value): ... yield Entry(self, "point[]") ... >>> data = b"MYF\3a\0b\2c\0" >>> stream = StringInputStream(data) >>> root = MyFormat(stream) ``` -------------------------------- ### Extract metadata with hachoir-metadata Source: https://hachoir.readthedocs.io/en/latest/_sources/metadata.rst.txt Use the hachoir-metadata command to extract file information. The --level option controls the verbosity of the output. ```bash $ hachoir-metadata --level=7 logo-Kubuntu.png ``` ```bash $ hachoir-metadata --level=3 logo-Kubuntu.png ``` ```bash $ hachoir-metadata --help ``` -------------------------------- ### Configure endianness for a Parser Source: https://hachoir.readthedocs.io/en/latest/internals.html Demonstrates setting the endian class attribute to LITTLE_ENDIAN for a custom parser. ```python >>> from hachoir.core.endian import LITTLE_ENDIAN >>> class UseLittleEndian(Parser): ... endian = LITTLE_ENDIAN ... ``` -------------------------------- ### Create regex via API Source: https://hachoir.readthedocs.io/en/latest/_sources/regex.rst.txt Constructs regex objects using the explicit API functions instead of parsing strings. ```python >>> from hachoir.regex import createString, createRange >>> createString('') >>> createString('abc') >>> createRange('a', 'b', 'c') >>> createRange('a', 'b', 'c', exclude=True) ``` -------------------------------- ### hachoir.stream: Stream Manipulation Source: https://hachoir.readthedocs.io/en/latest/developer.html Demonstrates the usage of Hachoir's stream manipulation API, specifically `StringInputStream`, for reading data in bits and bytes. ```APIDOC ## hachoir.stream: Stream Manipulation ### Description This section introduces the `hachoir.stream` API, focusing on how to work with data streams. It primarily uses `StringInputStream` for demonstration purposes, illustrating how to read data in bytes and bits with specified endianness. ### Usage Example ```python >>> data = b"point\x00\x03\x00\x02\x00" >>> from hachoir.stream import StringInputStream, LITTLE_ENDIAN >>> stream = StringInputStream(data) >>> stream.source '' >>> len(data), stream.size (10, 80) >>> data[1:6], stream.readBytes(8, 5) (b'oint\x00', b'oint\x00') >>> data[6:8], stream.readBits(6*8, 16, LITTLE_ENDIAN) (b'\x03\x00', 3) >>> data[8:10], stream.readBits(8*8, 16, LITTLE_ENDIAN) (b'\x02\x00', 2) ``` ### Key Concepts - Sizes and addresses are stored in bits, not bytes. - `readBytes(address, size)` reads data as bytes. - `readBits(address, size, endian)` reads data as bits with a specified endianness. ``` -------------------------------- ### Associate User Values with Patterns Source: https://hachoir.readthedocs.io/en/latest/regex.html Add patterns to PatternMatching and associate custom user values (integers or any Python object) with them. These values can be retrieved with the matched pattern. ```python p2 = PatternMatching() p2.addString("un", 1) p2.addString("deux", 2) p2.addRegex("(trois|three)", 3) for start, end, item in p2.search("un deux trois"): print("%r at %s: user=%r" % (item, start, item.user)) ``` -------------------------------- ### Parser Field Creation Source: https://hachoir.readthedocs.io/en/latest/_sources/developer.rst.txt Internal documentation regarding the createFields method used by Hachoir parsers. ```APIDOC ## Method: createFields() ### Description The main function responsible for creating fields within a parser. This function is intended for internal use by the Hachoir framework and should not be called directly by the user. ``` -------------------------------- ### Search images with hachoir-subfile Source: https://hachoir.readthedocs.io/en/latest/subfile.html Use the --category option to search for files belonging to a specific category. This command searches for all files categorized as 'image'. ```bash hachoir-subfile input --category=image ``` -------------------------------- ### Basic Hachoir Parser Definition Source: https://hachoir.readthedocs.io/en/latest/_sources/developer.rst.txt Defines a basic Hachoir parser 'Point' with string and unsigned integer fields. It demonstrates how to create fields and access their attributes like address, name, and display value. ```python from hachoir.field import Parser, CString, UInt16 from hachoir.stream import LITTLE_ENDIAN class Point(Parser): endian = LITTLE_ENDIAN def createFields(self): yield CString(self, "name", "Point name") yield UInt16(self, "x", "X coordinate") yield UInt16(self, "y", "Y coordinate") point = Point(stream) for field in point: print("%s) %s=%s" % (field.address, field.name, field.display)) ``` -------------------------------- ### Perform pattern matching Source: https://hachoir.readthedocs.io/en/latest/_sources/regex.rst.txt Uses PatternMatching to search for multiple strings or regex patterns within a target string. ```python >>> from hachoir.regex import PatternMatching >>> p = PatternMatching() >>> p.addString("a") >>> p.addString("b") >>> p.addRegex("[cd]") ``` ```python >>> for start, end, item in p.search("a b c d"): ... print("%s..%s: %s" % (start, end, item)) ... 0..1: a 2..3: b 4..5: [cd] 6..7: [cd] ``` -------------------------------- ### PatternMatching Class API Source: https://hachoir.readthedocs.io/en/latest/regex.html Methods for adding patterns and searching for them within a string using the PatternMatching class. ```APIDOC ## PatternMatching Class ### Description The PatternMatching class is used to find multiple strings or regex patterns in a target string. Patterns can be associated with user-defined objects for identification. ### Methods - **addString(string, user=None)**: Adds a literal string pattern to the matcher. Optional user object can be associated. - **addRegex(regex, user=None)**: Adds a regular expression pattern to the matcher. Optional user object can be associated. - **search(text)**: Searches the provided text for all registered patterns. Returns an iterator yielding (start, end, item) tuples. ### Usage Example ```python from hachoir.regex import PatternMatching p = PatternMatching() p.addString("un", 1) p.addRegex("(trois|three)", 3) for start, end, item in p.search("un trois"): print(f"Found {item} at {start}: user={item.user}") ``` ``` -------------------------------- ### Configure Hachoir Verbosity Source: https://hachoir.readthedocs.io/en/latest/_sources/developer.rst.txt Demonstrates how to suppress Hachoir log output by modifying the global configuration. ```APIDOC ## Configuration: Hachoir Verbosity ### Description Adjusts the logging verbosity of the Hachoir library. Setting `config.quiet` to `True` suppresses standard output logs. ### Request Example ```python from hachoir.core import config config.quiet = True ``` ``` -------------------------------- ### Search for a Substring in a Binary File Source: https://hachoir.readthedocs.io/en/latest/_sources/grep.rst.txt Perform a case-insensitive search for a specific substring within a binary file. The output shows the address and the string value where the substring is found. ```bash $ hachoir-grep "il" sheep_on_drugs.mp3 ``` -------------------------------- ### Strip metadata from a file Source: https://hachoir.readthedocs.io/en/latest/strip.html Execute hachoir-strip on a file to remove 'useless' information. The program indicates which fields are removed and the resulting file size change. A new file is saved with the .new extension. ```bash $ hachoir-strip KDE_Click.wav [+] Process file KDE_Click.wav Remove field /info Remove 56 bytes (3.1%) Save new file into KDE_Click.wav.new ``` -------------------------------- ### FieldSet Class Details Source: https://hachoir.readthedocs.io/en/latest/_sources/developer.rst.txt Details the attributes and methods of the FieldSet class, including read-only attributes and lazy attributes. ```APIDOC ## Field Set Class ### Description This section describes the attributes and methods available for the FieldSet class in Hachoir, which represents a collection of fields. ### Method N/A ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) **Read-only attributes:** * endian: The byte order (BIG_ENDIAN or LITTLE_ENDIAN). * stream: The input stream object. * root: The root FieldSet of the field hierarchy. * eof: Boolean indicating if the end of the file has been reached. * done: Boolean indicating if the parser has completed. **Read-only and lazy attributes:** * current_size: The current total size in bits of the fields processed. * current_length: The current number of child fields processed. **Methods:** * connectEvent(event, handler, local=True): Connects a handler to an event. * raiseEvent(event, *args): Raises an event. * reset(): Clears caches but retains known size. * setUniqueFieldName(): Sets unique identifiers for fields ending in "[]". * seekBit(address, ...): Seeks to a specific bit address. * seekByte(address, ...): Seeks to a specific byte address. * replaceField(name, fields): Replaces an existing field with new fields. * getFieldByAddress(address, feed=True): Retrieves a field at a specific address. * writeFieldsIn(old, address, new): Helper for replaceField. * getFieldType(): Returns the field type as a string. * array(): Creates a FakeArray for index-based field access. * __len__(): Returns the number of children. * readFirstFields(number): Reads a specified number of initial fields. * readMoreFields(number): Reads a specified number of additional fields. * __iter__(): Iterates over child fields. #### Response Example N/A ``` -------------------------------- ### Filter metadata output verbosity Source: https://hachoir.readthedocs.io/en/latest/metadata.html Control the amount of metadata displayed by adjusting the verbosity level. ```bash $ hachoir-metadata logo-Kubuntu.png Image: - Image width: 331 - Image height: 90 - Bits/pixel: 8 - Image format: Color index - Creation date: 2006-05-26 09:41:46 - Compression: deflate - MIME type: image/png - Endian: Big endian ``` ```bash $ hachoir-metadata --level=7 logo-Kubuntu.png Image: - Image width: 331 - Image height: 90 - Bits/pixel: 8 - Image format: Color index - Creation date: 2006-05-26 09:41:46 - Compression: deflate ``` ```bash $ hachoir-metadata --level=3 logo-Kubuntu.png Image: - Image width: 331 - Image height: 90 - Bits/pixel: 8 - Image format: Color index ``` -------------------------------- ### Search patterns in string Source: https://hachoir.readthedocs.io/en/latest/regex.html Executes a search across a string to find all added patterns. ```python >>> for start, end, item in p.search("a b c d"): ... print("%s..%s: %s" % (start, end, item)) ... 0..1: a 2..3: b 4..5: [cd] 6..7: [cd] ```