Git Product home page Git Product logo

snowbirdopter's Introduction

snowbirdopter

The snowbirdopter is a tool which can be used to get memory dumps from the tiptoi pen1, to load arbitrary memory (code and data) into the pen's processor's memory and to execute binaries. This can either be done via UART boot mode or via USB/SCSI in mass boot mode for firmware update (not the "normal" mass boot mode). It can also be used to exchange serial data (transmit and receive) over the UART interface with the pen.

It can be used to find out more about the processor and the the whole tiptoi pen's execution environment, e.g. how embedded games can be analyzed, debugged or developed. The communication with the pen is based on its UART boot mode (details in the "Usage" section below).

IMPORTANT: This software has been developed on an information basis compiled from information freely available on the Internet and confirmed by own experiments. It is provided without any guarantee and may be erroneous! We are not responsible when you brick your tiptoi pen!

Contributing

Feel free to make contributions to the source code to improve snowbirdopter by fixing bugs and adding new functionalities or examples! Please also check the github issues page for known issues and enhancement requests.

Dependencies

snowbirdopter is a command-line tool based on the Python3 scripting language, i.e. you currently need a Python3 interpreter running on your machine.

It also depends on the pySerial package which It provides backends for Python running on Windows, OSX, Linux and others. There are various ways to install the package, which are described on their website.

If the package is not installed you will get the following or a similar error message:

   Traceback (most recent call last):
     File "snowbirdopter.py", line 3, in <module>
       import serial
   ModuleNotFoundError: No module named 'serial'

If you want to do compile, load and execute your own source code, you'll need an ARM cross-compiler. The installation process is described in another section below.

Usage

To show the snowbirdopter's usage enter:

python3 snowbirdopter.py -h

The output should look similar to:

usage: snowbirdopter.py [-h] [-p SERPORT] [-s SCSIDEV] -c COMMAND [-a ADDRESS] [-e ENDADDRESS] [-n VALUE] [-b TXBYTE] [-f FILE]
                        [-v VERBOSITY] [--version]

snowbirdopter.py

optional arguments:
  -h, --help     show this help message and exit
  -p SERPORT     serial device port name (e.g. '/dev/ttyUSB0' or 'COM1')
  -s SCSIDEV     generic SCSI device file name (e.g. '/dev/sg2')
  -c COMMAND     command (dump, set[val[ue]], go, load, exec, txb, rxb, trxb, txbrxl)
  -a ADDRESS     start address as hex string, without '0x' prefix
  -e ENDADDRESS  end address as hex string, without '0x' prefix
  -n VALUE       value to be set in setvalue command, as hex string, without '0x' prefix
  -b TXBYTE      byte to be transmitted in txb command
  -f FILE        path to a binary file
  -v VERBOSITY   print detailed output
  --version      show program's version number and exit

Commands

The currently supported commands are:

command addresss required? description
dump Dump memory from a specific address or address range
(dumps to stdout in a human-readable format, optionally also dumps to a raw binary file)
set[val[ue]] Set a single 32-bit word at a specific address (given by -a)
go Execute the code located at a given address (address given by -a)
load Load a binary executable from the file system to the target (at address given by -a)
exec Load a binary executable from the file system to the target and execute it
txb Transmit a single byte (-b) to the serial
rxb Receive a single byte from the serial
trxb Transmit a single byte (-b) to serial and immediately read back a single response byte from the serial
txbrxl Transmit a single byte (-b) to serial and immediately read back one or several lines from the serial
rxl Read one or several lines from the serial

Tiptoi special pins

The following information is taken from https://github.com/entropia/tip-toi-reveng/wiki/PEN-Hardware-Details:

Pin Function
GPIO13 (pin 39) UART TX* pin + mass storage boot selector pin
(pull to low by a 1 kOhm resistor to enter mass boot mode for firmware update)
GPIO9 (pin 37) UART boot selector pin
(pulled to low by a 1 kOhm resistor to enter UART boot mode)
GPIO12 (pin 36) UART RX* pin

*TX/RX as seen from the device, i.e. RX/TX as seen from the PC.

To enter and manually use boot mode:

  • Connect your USB/serial converter to the UART TX and RX pins.
  • Open a serial terminal program, e.g. moserial, HTerm, etc. and connect with 38400 baud, 8N1 and no handshakes.
  • Pull GPIO9 high.
  • Power the tiptoi pen.
  • The string "SNOWBIRD2-BIOS>#" is sent via UART TX pin immediately after start-up.

Serial connection

Connect your USB/serial converter to the tiptoi pen (with 3.3V logic levels!). Enter the pen's UART boot mode (at your own risk!).

Find out the serial device's port name on your system, e.g. "/dev/ttyUSB0" or "COM1". Under Windows this can be done by opening the device manager. Under Linux you can open a command line window, go to the /dev/ directory and list all USB tty devices, i.e. ls -al ttyUSB*.

The serial port settings 38400 baud, 8N1 and no handshakes are automatically configured by the Python script.

If snowbirdopter reports

[ERROR] Internal error occured. Exception: "Serial device is not available."

and you are sure that the given device exists you should check the access rights for your serial device's port and change them if necessary, e.g. execute sudo chmod 666 /dev/ttyUSB0. Please check the web for alternatives like udev rules or permission groups.

How to build a loadable and executable binary

You will find pre-compiled binaries in the examples/ subfolder. To modify them or run your own code you'll need to get an ARM cross-compiler, e.g. GCC. For Linux the process looks as follows:

sudo apt install binutils-arm-linux-gnueabi

For MacOS you can use the following command in the terminal:

brew install gcc-arm-embedded

Build the "hello world" example:

cd examples/standalone/bootrom_uart_hello_world/
make clean
make

Done! You're now able to load and execute it on the target, see next section.

How to load and execute a binary (via serial)

Before executing your first binary, it's recommended to check if the connection to the pen works by dumping the value at address 0x00000000 (addresses need to be given given as hex strings; they do not need to have a "0x" prefix, but they can):

python3 snowbirdopter.py -p /dev/ttyUSB0 -c dump -a 0

The output should look similar to:

[INFO] 0x08100000:  0xea000020

Using a different verbosity level and running under the MacOS terminal this could also look like the following:

% python3 snowbirdopter.py -c dump -a 0 -p /dev/tty.SLAB_USBtoUART -v 1
[DEBUG] Platform: Darwin
[WARNING] Not run under Linux. SCSI commands won't be supported on this platform.
[DEBUG] Serial device port name: '/dev/tty.SLAB_USBtoUART'
[DEBUG] dump from 0x00000000 to 0x00000000
[INFO] 0x00000000:  0xea000006
[DEBUG] Return value from specific dump: True
[INFO] Dump succeeded.

Load the previously built "hello world" example mentioned to the target and execute it by using the following command line:

python3 snowbirdopter.py -p /dev/ttyUSB0 -c exec -f ./examples/uart_hello_world/out.bin -a 08010000

The output should look similar to:

[DEBUG] File './examples/uart_hello_world/out.bin' exists.
[DEBUG] Serial port device name: '/dev/ttyUSB0'
[DEBUG] load_binfile('./examples/uart_hello_world/out.bin' at 0x08010000)
[DEBUG] File size: 120
[DEBUG] setvalue 0xeaffffff at 0x08010000
[DEBUG] setvalue 0xeb000000 at 0x08010004
...
[INFO] Loading binfile succeeded.
[DEBUG] go to address 0x08010000
Read from serial: b'Hello Tiptoi! Hello world!\n'
[INFO] Executing binfile succeeded.

Important note: The pen won't be responsive to further commands and will need to be power-cycled.

There are already some more examples in the examples/ subdirectory. Feel free to analyze, execute them on the pen and modify them according to your needs.

How to interact with executables (loaded via serial)

There's some code in the examples that demonstrates how to interact with an executable using snowbirdopter's command. There's always the way for your code to send something via the serial. Not only that: you can also read characters from the serial - this allows your program to wait or even influence the program flow dependent on the user's input via serial.

Here's an example:

Go to the /examples/standalone/boot_redirect directory. Build (make) and load the executable:

% python3 ../../../snowbirdopter.py -c exec -a 08010000 -p /dev/tty.SLAB_USBtoUART -f out.bin
[WARNING] Not run under Linux. SCSI commands won't be supported on this platform.
[INFO] Loading binfile succeeded.
[DEBUG] go to address 0x08010000
[INFO] Read from serial: b'Boot mode register: 02000001. Boot will be redirected. Which bode mode to use? m/M=massboot, u/U=usbboot, s/S=SPI flash boot, n/N=NAND flash boot (default).\n'

The last line of the printed output signals that the executable is waiting for the user's input - in order to decide which boot mode to use.

Inspecting the code gives us some insighets:

    bootrom_uart_puts(". Boot will be redirected. Which bode mode to use? ");
    bootrom_uart_puts("m/M=massboot, u/U=usbboot, s/S=SPI flash boot, n/N=NAND flash boot (default).\n");

    /* Wait for user input */
    bootrom_uart_getc(&nWord);

Calling the function bootrom_uart_get() in your code will indeed let the processor block until a character has been received via the serial. In order to send the response we could either open a serial terminal, send the character and wait for the next output. Instead we can call snowbirdopter again in order to do that exact thing. Let's send the character n by using command txbrxl (send a single byte, but receive multiple lines as response) and specifying the character wiht option -b. As we want to see what's going on, we also specify verbosity level 1 by using -v 1:

% python3 ../../../snowbirdopter.py -c txbrxl -b n -p /dev/tty.SLAB_USBtoUART -v 1
[DEBUG] Platform: Darwin
[WARNING] Not run under Linux. SCSI commands won't be supported on this platform.
[DEBUG] Serial device port name: '/dev/tty.SLAB_USBtoUART'
[INFO] Tx: 'b'n''
[INFO] Read from serial: b'Trying to boot via NAND flash.\n'
[INFO] Transceiving byte succeeded.

Next, we should hear the tiptoi pen start sound - it's now ready to play as it has re-booted from NAND flash as in normal operation as if we just had pressed the power button on it.

Finally having another glimpse at the code helps us understand what has happened and why:

(...)
        case 'n':
        case 'N':
        default:
            bootrom_uart_puts("Trying to boot via NAND flash.\n");
            bootrom_nandflash_boot();
            break;
    }

    /* Program flow should not reach this line */
    bootrom_uart_puts("Unexpectedly continued execution to this point.\n");

How to analyze binary files

In general, you can create hex dumps of binary files. The xxd tool allows you to view the binary content with one 32-bit word per line:

xxd -ps -c 4 -e:4 ./examples/uart_hello_world/out.bin
00000000: eaffffff  ....
00000004: eb000000  ....
00000008: eafffffe  ....

(...)

As this might not be very convenient, there are some more elaborated ways to analyze a binary file.

Disassemble a binary file which has been built for the ARM architecture, e.g. one of our compiled examples:

arm-none-eabi-objdump --architecture=arm -b binary -D ./examples/uart_hello_world/out.bin
./examples/uart_hello_world/out.bin:     file format binary

Disassembly of section .data:

00000000 <.data>:
   0:	eaffffff 	b	0x4
   4:	eb000000 	bl	0xc
   8:	eafffffe 	b	0x8
   c:	e92d4800 	push	{fp, lr}
(...)

Of course, you can also use your favorite reverse engineering framework for disassembly and analysis, like radare2 or Ghidra or ...

What about the strange name of the tool?

The name snowbirdopter derives from the codename of the tiptoi pen's ARM processor2 snowbird and the greek word pteron "wing". The snowbirdopter shall be used to let the snowbird's wings move so that it can fly3! In addition, in the English language an opter is someone who opts, or makes a choice4 - e.g. to run own open-source software on the target.

Footnotes

  1. tip-toi-reveng github repository

  2. probably with an ARM926EJ-S core

  3. Have you ever heard about ornithopters?

  4. Wiktionary: opter

snowbirdopter's People

Contributors

b-g-t avatar maehw avatar nomeata avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

snowbirdopter's Issues

"Setval" gives no confirmation

Setval should report success even if it's not called with the verbose option.

Example:

user@Ubuntu:~/Documents/snowbirdopter-master$ python3 snowbirdopter.py -p /dev/ttyUSB0 -c setval -n 25 -a 08000000 -v 9
[DEBUG] Platform: Linux
[DEBUG] Serial device port name: '/dev/ttyUSB0'
[DEBUG] setvalue value 0x00000025 at address 0x08000000
[INFO] Setting value succeeded.
user@Ubuntu:~/Documents/snowbirdopter-master$ python3 snowbirdopter.py -p /dev/ttyUSB0 -c setval -n 25 -a 08000000 

Add binaries of examples to repo

In order to allow users to test without prior installation of the ARM compiler, it would be great to include also the binaries of the examples into the repo.

Dump command gives no output without the verbose option

Example:

user@Ubuntu:~/Documents/snowbirdopter-master$ python3 snowbirdopter.py -s /dev/sg2 -c dump -a 0 -e ff -p /dev/ttyUSB0
user@Ubuntu:~/Documents/snowbirdopter-master$ python3 snowbirdopter.py -s /dev/sg2 -c dump -a 0 -e ff -p /dev/ttyUSB0 -v9
[DEBUG] Platform: Linux
[DEBUG] Serial device port name: '/dev/ttyUSB0'
[DEBUG] Generic SCSI device file name: '/dev/sg2'
[DEBUG] SCSI inquiry successful.
[DEBUG] SCSI device identification successful.
[DEBUG] dump from 0x00000000 to 0x000000ff
[DEBUG] Calculated length (from start to end address): 255
[DEBUG] Rounded dump length: 256 / 0x00000100
[DEBUG] proc: CompletedProcess(args=['sg_raw', '-r', '256', '/dev/sg2', 'F1', '7F', '00', '00', '00', b'00', b'00', b'00', b'00', b'00', b'01', b'00', b'00', '88', '00', '00'], returncode=0, stdout='', stderr='SCSI Status: Good \n\nReceived 256 bytes of data:\n 00     06 00 00 ea a8 f0 9f e5  a8 f0 9f e5 a8 f0 9f e5    ................\n 10     a8 f0 9f e5 a8 f0 9f e5  a8 f0 9f e5 a8 f0 9f e5    ................\n 20     63 10 a0 e3 a4 00 9f e5  00 10 80 e5 13 00 a0 e3    c...............\n 30     00 f0 29 e1 98 10 9f e5  01 d0 a0 e1 00 00 a0 e3    ..).............\n 40     9e 03 00 eb 03 00 50 e3  88 f0 9f 05 01 00 50 e3    ......P.......P.\n 50     84 f0 9f 05 02 00 50 e3  80 f0 9f 05 80 00 9f e5    ......P.........\n 60     05 14 a0 e3 00 10 80 e5  00 00 a0 e3 fa 02 00 eb    ................\n 70     01 00 50 e3 02 f3 a0 03  64 00 9f e5 01 13 a0 e3    ..P.....d.......\n 80     00 10 80 e5 00 00 a0 e3  76 02 00 eb 01 00 50 e3    ........v.....P.\n 90     02 f3 a0 03 48 00 9f e5  06 14 a0 e3 00 10 80 e5    ....H...........\n a0     40 f0 9f e5 38 00 9f e5  02 14 a0 e3 00 10 80 e5    @...8...........\n b0     34 f0 9f e5 04 00 00 08  08 00 00 08 0c 00 00 08    4...............\n c0     10 00 00 08 14 00 00 08  18 00 00 08 1c 00 00 08    ................\n d0     0c 00 00 04 00 ef 02 08  60 42 00 00 40 28 00 00    ........`B..@(..\n e0     a4 00 00 00 54 00 00 04  60 42 00 00 50 0a 00 00    ....T...`B..P...\n f0     0d c0 a0 e1 00 d8 2d e9  04 b0 4c e2 08 d0 4d e2    ......-...L...M.\n')
[DEBUG] Return value from specific dump: True
[INFO] Dump succeeded.

Commands report "failed" even if the process executed fine

Examples:

user@Ubuntu:~/Documents/snowbirdopter-master$ sudo python3 snowbirdopter.py -p /dev/ttyUSB0 -c dump -a 0 -e ff
[ERROR] Dump failed.
user@Ubuntu:~/Documents/snowbirdopter-master$ sudo python3 snowbirdopter.py -p /dev/ttyUSB0 -c dump -a 0 -e ff -v9
[DEBUG] Platform: Linux
[DEBUG] Serial device port name: '/dev/ttyUSB0'
[DEBUG] dump from 0x00000000 to 0x000000ff
[DEBUG] 0x00000000:  0xea000006  0xe59ff0a8  0xe59ff0a8  0xe59ff0a8
[DEBUG] 0x00000010:  0xe59ff0a8  0xe59ff0a8  0xe59ff0a8  0xe59ff0a8
[DEBUG] 0x00000020:  0xe3a01063  0xe59f00a4  0xe5801000  0xe3a00013
[DEBUG] 0x00000030:  0xe129f000  0xe59f1098  0xe1a0d001  0xe3a00000
[DEBUG] 0x00000040:  0xeb00039e  0xe3500003  0x059ff088  0xe3500001
[DEBUG] 0x00000050:  0x059ff084  0xe3500002  0x059ff080  0xe59f0080
[DEBUG] 0x00000060:  0xe3a01405  0xe5801000  0xe3a00000  0xeb0002fa
[DEBUG] 0x00000070:  0xe3500001  0x03a0f302  0xe59f0064  0xe3a01301
[DEBUG] 0x00000080:  0xe5801000  0xe3a00000  0xeb000276  0xe3500001
[DEBUG] 0x00000090:  0x03a0f302  0xe59f0048  0xe3a01406  0xe5801000
[DEBUG] 0x000000a0:  0xe59ff040  0xe59f0038  0xe3a01402  0xe5801000
[DEBUG] 0x000000b0:  0xe59ff034  0x08000004  0x08000008  0x0800000c
[DEBUG] 0x000000c0:  0x08000010  0x08000014  0x08000018  0x0800001c
[DEBUG] 0x000000d0:  0x0400000c  0x0802ef00  0x00004260  0x00002840
[DEBUG] 0x000000e0:  0x000000a4  0x04000054  0x00004260  0x00000a50
[DEBUG] 0x000000f0:  0xe1a0c00d  0xe92dd800  0xe24cb004  0xe24dd008
[DEBUG] 
[DEBUG] Return value from specific dump: False
[ERROR] Dump failed.

Address comand line argument `-a` is currently mandatory

The comand line argument -a is currently mandatory and used to define a start address (as hex string without the "0x" prefix). Commands to trigger raw operations on the serial interface, like writing a character and receiving a character or whole line of text do not really require that info.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.