-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First, primitive version of checksum calc tool
This is a (seemingly) working re-implementation of how to calculate the expected checksum for a Fritz!Box configuration file in Python.
- Loading branch information
Bernhard Kirchen
committed
Sep 3, 2015
1 parent
e9188dc
commit 326f4f8
Showing
1 changed file
with
107 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#!/usr/bin/python | ||
|
||
import binascii | ||
import sys, re | ||
|
||
print "CRC32 test: %08X" % (binascii.crc32("some\n bullshit\r test\0\0 to compare to PHP equivalent") & 0xffffffff); | ||
print "unhexlify test: %s (<- should read \"Hallo\")" % binascii.unhexlify("48616C6c6F00"); | ||
print "stripcslashes test: %s" % re.sub("\\\\\\\\", "\\\\", "foo\\\\bar\\blupp") | ||
|
||
# TODO credits | ||
# TODO windows line endings? | ||
|
||
# global pre-compiled regex objects for later matching | ||
# matches a key-value pair found on the top of the config | ||
# TODO do we need to allow optional whitespaces before the end of the line? | ||
var_val_pair_regex = re.compile("^([\w]+)=([\S]+)$"); | ||
|
||
# matches the begin marker of a config file name | ||
cfg_file_start_regex = re.compile("^\*{4} CFGFILE:([\S]+)$") | ||
|
||
bin_file_start_regex = re.compile("^\*{4} BINFILE:([\S]+)$") | ||
|
||
any_file_end_regex = re.compile("^\*{4} END OF FILE \*{4}$") | ||
|
||
def read_config_file(filename, lines): | ||
#print "amount of lines: %i" % len(lines) | ||
#for line in lines: | ||
# print line, | ||
#sys.exit(2) | ||
result = str(filename) + '\0' | ||
for line in lines[:-1]: | ||
result += re.sub("\\\\\\\\", "\\\\", line) # TODO stripcslashes | ||
if lines[-1] != str("\n"): | ||
# TODO does the fritzbox also accept configs with no such newline? | ||
print "Whoops, I was expecting an empty line at the end of file \"%s\"!" % filename | ||
sys.exit(2) | ||
return result | ||
|
||
def read_binary_file(filename, lines): | ||
result = str(filename) + '\0' | ||
for line in lines: | ||
result += binascii.unhexlify(line.strip()) | ||
return result | ||
|
||
def main(): | ||
config_lines = list() # input (list of lines, line endings included) | ||
checksum_material = str() # accumulated data for CRC32 calculation | ||
|
||
if(len(sys.argv) < 2): | ||
print "Need argument (file to inspect)!" | ||
sys.exit(-1) | ||
|
||
filename = sys.argv[1] | ||
|
||
try: | ||
with file(filename) as f: | ||
config_lines = f.readlines() | ||
except Exception as e: | ||
print "ERROR: File \"%s\" could not be read." % filename | ||
if hasattr(e, "strerror"): print "ERROR: %s" % e.strerror | ||
sys.exit(-1); | ||
|
||
line_index = int(0) | ||
while line_index < len(config_lines): | ||
#print "processing line: %i" % (line_index + 1) | ||
line = config_lines[line_index] | ||
|
||
# determine the type of this (and maybe the following) input line(s) | ||
match = re.match(var_val_pair_regex, line); | ||
if match: | ||
checksum_material += match.group(1) + match.group(2) + '\0'; | ||
#print "%s" % checksum_material | ||
line_index += 1 | ||
continue | ||
|
||
match = re.match(cfg_file_start_regex, line); | ||
if match: | ||
file_start = line_index + 1 | ||
file_end = file_start + 1 | ||
while not re.match(any_file_end_regex, config_lines[file_end]): | ||
file_end += 1 | ||
checksum_material += read_config_file(match.group(1), config_lines[file_start:file_end]) | ||
#print "%s" % checksum_material, | ||
#sys.exit(2) | ||
line_index = file_end + 1 | ||
continue | ||
|
||
match = re.match(bin_file_start_regex, line); | ||
if match: | ||
file_start = line_index + 1 | ||
file_end = file_start + 1 | ||
while not re.match(any_file_end_regex, config_lines[file_end]): | ||
file_end += 1 | ||
checksum_material += read_binary_file(match.group(1), config_lines[file_start:file_end]) | ||
line_index = file_end + 1 | ||
continue | ||
|
||
# line is ignored | ||
line_index += 1 | ||
|
||
#with open("python-out.bin", "w") as f: | ||
# f.write(checksum_material) | ||
|
||
print "presumably proper checksum: %08X" % (binascii.crc32(checksum_material) & 0xffffffff) | ||
|
||
if __name__ == '__main__': | ||
main() |