-
-
Save the6p4c/6ba6bf2461a1215d94e7ba54d1a2a8c3 to your computer and use it in GitHub Desktop.
Code for Part 2 of "Hacking the fx-CP400"
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
import argparse | |
import gzip | |
GZIP_COMPRESSION_LEVEL = 6 | |
def parse_args(): | |
""" | |
@brief Parses the arguments passed into the firmware packing utility. | |
@return A dictionary, representing the arguments passed in. | |
""" | |
argument_parser = argparse.ArgumentParser( | |
description=( | |
'Tool to pack a firmware image, ready to be inserted into an OSupdateDLL.dll file.' | |
) | |
) | |
argument_parser.add_argument( | |
'fw_bin_file_path', | |
help='Path to the uncompressed firmware file.' | |
) | |
argument_parser.add_argument( | |
'fw_cbin_file_path', | |
default='fw.cbin', | |
nargs='?', | |
help='Path to save the compressed firmware file to (default: fw.cbin).' | |
) | |
return argument_parser.parse_args() | |
def main(): | |
args = parse_args() | |
with open(args.fw_bin_file_path, 'rb') as fw_bin_file: | |
# skip in by 0xA to skip the header | |
compressed_data = gzip.compress(fw_bin_file.read(), GZIP_COMPRESSION_LEVEL)[0xA:] | |
with open(args.fw_cbin_file_path, 'wb') as fw_cbin_file: | |
fw_cbin_file.write(compressed_data[:0x2FF6]) | |
fw_cbin_file.write(compressed_data[0x2FF7:]) | |
print(f'Missing byte: {compressed_data[0x2FF6]}\nIf this missing byte does not match the missing byte in the OSupdateDLL.dll file you\'re using, you must modify the DLL before flashing.') | |
if __name__ == '__main__': | |
main() |
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
! Move the Debug_SetCursorPosition function into r8, since it's preserved through function calls | |
mov.l Debug_SetCursorPosition, r8 | |
! Prepare our arguments to set the cursor to position 0, 0 | |
mov #0, r4 | |
mov #0, r5 | |
! Call the function | |
jsr @r8 ! Debug_SetCursorPosition | |
nop | |
! Move the Debug_PrintString function into r9, which is also preserved | |
mov.l Debug_PrintString, r9 | |
! mova can only move into r0, so load the address of the string into r0 then move it into r4 to serve as the argument to Debug_PrintString | |
mova string1, r0 | |
mov r0, r4 | |
! Move 0 into the second argument (r5) like we saw in our disassembly | |
mov #0, r5 | |
! Call the function | |
jsr @r9 ! Debug_PrintString | |
nop | |
! Move to a different position | |
mov #2, r4 | |
mov #3, r5 | |
jsr @r8 ! Debug_SetCursorPosition | |
nop | |
! Print a different string | |
mova string2, r0 | |
mov r0, r4 | |
mov #0, r5 | |
jsr @r9 ! Debug_PrintString | |
nop | |
! Draw our screen | |
mov.l Debug_DrawScreen, r10 | |
jsr @r10 ! Debug_DrawScreen | |
nop | |
! Halt by looping indefinitely | |
halt: | |
bra halt | |
nop | |
! Store the addresses of the functions we discovered, aligned at a word boundary | |
.align 4 | |
Debug_SetCursorPosition: | |
.long 0x8002E430 | |
Debug_PrintString: | |
.long 0x8002DA0C | |
Debug_DrawScreen: | |
.long 0x8003733E | |
! Store our strings, both aligned at word boundaries | |
.align 4 | |
string1: | |
.string "Hello, fx-CP400 world!" | |
.align 4 | |
string2: | |
.string "the6p4c.github.io" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment