Synalyze It! Icon

Using the Script Editor

Synalyze It! Pro offers powerful functions for the analysis of binary files. However, there's so much more you can do when you leverage the functionality with own scripts. Scripts can be stored either globally in the Application Support folder (e. g. ~/Library/Containers/com.synalyze-it.SynalyzeItPro/Data/Library/Application Support/Synalyze It! Pro/Scripts) or inside grammar files.
There are five different types of scripts:

  1. Grammar - Automize the modification and usage of grammars
  2. File - Write scripts that modify binary files
  3. Generic - Scripts that do tasks not related to grammars or files
  4. Process results - Interpret the parsing results with a script
  5. Data type - Interpret the parsing results with a script
  6. Element - A single scriptable element of a structure in a grammar. These scripts are edited in the grammar editor directly.

Depending on whether a grammar or binary file window are active, grammar or file scripts can be run via the Script menu. The scripts that process parsing results can be chosen in the pop-up menu in the toolbar of a file once a grammar has been applied. Generic scripts are always available in the Script menu.

Grammar scripts

These scripts are intended to work on grammars, be it reading or writing. As an example you could dump the structures of a grammar to some custom format or build the structures from some external source.

File scripts

File scripts work on (binary) files, both reading and writing. The changes can be reversed using undo but better make sure you have a backup, just in case. A sample application for a file script is to apply a patch.

Generic scripts

Since these scripts can always be run when Synalyze It! Pro is active, they can be used for any task that's not related to certain grammars or binary files.

Process results scripts

Displaying the parsing results of binary files is nice but with a script you can process the results tree automatically.

Data type scripts

Data type scripts implement the parsing of custom data types. Additionally they can implement a method to translate changed values back to a file.

Annotated Python Example

# DOS date/time structure
#                24                16                 8                 0
# +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
# |Y|Y|Y|Y|Y|Y|Y|M| |M|M|M|D|D|D|D|D| |h|h|h|h|h|m|m|m| |m|m|m|s|s|s|s|s|
# +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
#  \___________/\________/\_________/ \________/\____________/\_________/
#      year        month       day      hour       minute        second

from datetime import datetime

def parseByteRange(element, byteView, bitPos, bitLength, results):
	"""parseByteRange method"""

	# read four bytes into two integer variables
	highWord = byteView.readUnsignedInt(bitPos/8, 2, ENDIAN_BIG)
	lowWord = byteView.readUnsignedInt(bitPos/8+2, 2, ENDIAN_BIG)

	# extract date
	year = (highWord >> 9) + 1980
	month = (highWord >> 5) & 0x1F
	day = highWord & 0x1F

	hour = lowWord >> 11
	minute = (lowWord >> 5) & 0x3F
	second = (lowWord & 0x1F) * 2

	# create datetime object
	dt = datetime(year, month, day, hour, minute, second)

	# create string value with formatted date
	value = Value()
	value.setString(dt.isoformat(' '))

	# add result to results tree - 4 bytes, iteration 0
	# the element needs to be passed here to enable the translation
	# of changed values back to the file
	results.addElement(element, 4, 0, value)

	return 4

def fillByteRange(value, byteArray, bitPos, bitLength):
	"""fillByteRange method"""

	if (bitLength < 32):
		print "Not enough space for DOS Date/Time structure, 32 bits needed"

	# get the string after change by user
	dateTimeString = value.getString()

	# parse string
	dt = datetime.strptime(dateTimeString, "%Y-%m-%d %H:%M:%S")

	# create values to be written
	highWord = ((dt.year - 1980) << 9) + (dt.month << 5) + dt.day
	lowWord = (dt.hour << 11) + (dt.minute << 5) + (dt.second / 2)

	# update file with modified values
	byteArray.writeUnsignedInt(highWord, bitPos/8, 2, ENDIAN_BIG)
	byteArray.writeUnsignedInt(lowWord, bitPos/8+2, 2, ENDIAN_BIG)

Script Editor

See also

Scripting Class Reference