Skip to content

Instantly share code, notes, and snippets.

@the6p4c
Last active May 2, 2021 13:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save the6p4c/6ba6bf2461a1215d94e7ba54d1a2a8c3 to your computer and use it in GitHub Desktop.
Save the6p4c/6ba6bf2461a1215d94e7ba54d1a2a8c3 to your computer and use it in GitHub Desktop.
Code for Part 2 of "Hacking the fx-CP400"
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()
! 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