Writeup by leraton for Midas Touch

hardware

April 15, 2024

Introduction

Two .vcd files are given, one for the screen and one for the touchpad. The image displayed on the touchpad can easily be retrieved from the screen signal with the exact same procedure used in Soupe MISO (see the according write-up).

The touchpad layout look like this:

screen

A python array can be used to represent the layout of the touchpad:

screen = [
    ["5", "3", "2"],
    ["1", "9", "0"],
    ["4", "6", "7"],
    ["8", "#", "OK"],
]

Touchpad signals

Once the layout is known, the touchpad signals can be processed. According to the datasheet, the communication with the touchpad is made using the I2C protocol. The .vcd file can be open in PulseView. It can quickly be seen that:

  • D0 is the sda line
  • D1 is the scl line

Using the protocol decoder, the I2C commands can be extracted as a .txt file (Add protocol decoder -> I2C -> D0 as SDA, D1 as SCL). However, the extracted format is not pretty and a bit of cleaning is necessary to make it easier to process :

5391650-5392357 I²C: Address/Data: Address write: 38
5391549-5391549 I²C: Address/Data: Start
5392357-5392459 I²C: Address/Data: Write
5392460-5392562 I²C: Address/Data: ACK
5392779-5392779 I²C: Address/Data: Stop
5394902-5394902 I²C: Address/Data: Start
5395003-5395711 I²C: Address/Data: Address write: 38
5395711-5395813 I²C: Address/Data: Write
5395814-5395916 I²C: Address/Data: ACK
5396091-5396896 I²C: Address/Data: Data write: 80
5396896-5396997 I²C: Address/Data: ACK
5396999-5397818 I²C: Address/Data: Data write: 28
5397819-5397921 I²C: Address/Data: ACK
5398138-5398138 I²C: Address/Data: Stop
5401027-5401027 I²C: Address/Data: Start
5401128-5401836 I²C: Address/Data: Address write: 38
[...]

To do so, the following python script is used

input_file = "I2C.txt"
output_file = "I2C_command.txt"


def main():
    with open(input_file, "r") as file:
        lines = file.readlines()
    commands = ""
    current_command = ""
    for line in lines:
        line = line.split(": ")
        if len(line) == 4:
            action = line[2]
            if action == "Address read":
                current_command += " R "
            elif action == "Address write":
                current_command += line[3][:2] + " W "
            elif action == "Data read":
                current_command += line[3][:2]
            elif action == "Data write":
                current_command += line[3][:2]

        if len(line) == 3:
            if "Stop" in line[2]:
                current_command += "\n"
                commands += current_command
                current_command = ""
    with open(output_file, "w") as file:
        file.write(commands)


if __name__ == "__main__":
    main()

Processing the I2C commands

The output data are now formatted as one command per line with only the necessary information:

38 W
38 W 8028
38 W A8 R 11
38 W A3 R 06
38 W 02 R 00
38 W 02 R 00
38 W 02 R 00
38 W 02 R 00
38 W 02 R 00
38 W 02 R 00
38 W 02 R 00
38 W 02 R 00
38 W 02 R 00
38 W 02 R 00
[...]

As it can be seen, there is a lot of writing 0x02 and then reading the data. According to the datasheet, in 0x02, is stored the number of point pressed on the screen.

By scrolling in the I2C_command.txt file, the following behavior can be seen:

38 W 02 R 00
38 W 02 R 00
38 W 02 R 00
38 W 02 R 01
38 W 00 R 00000100BB0118FF80FFFFFFFFFFFF00
38 W 02 R 00
38 W 02 R 00
38 W 02 R 00
38 W 02 R 00

It can be assumed that the microcontroller continuously read the number of point pressed on the screen and read the position when the number of point pressed is 1.

By reading the datasheet, it can be seen that the X position in stored in the 0x03 and 0x04 bytes and the Y position is stored in the 0x05 and 0x06 bytes. A python script is then written in order to decode the successive positions touched (which correspond to the PIN). The position has to be reversed in order to finish with the “OK” button which can be assumed to be the validation and therefore not be taken into account for the flag.

input_file = "I2C_command.txt"

screen = [
    ["5", "3", "2"],
    ["1", "9", "0"],
    ["4", "6", "7"],
    ["8", "#", ""],
]

def main():
    with open(input_file, "r") as file:
        lines = file.readlines()
    touch_positions = []
    print("FCSC{", end="")
    for line in lines:
        if len(line) > 18:
            data = line.split(" ")[-1][:-1]
            x_data = data[7:10]
            y_data = data[11:14]
            print(
                screen[(320 - int(y_data, 16)) * 4 // 320][
                    (240 - int(x_data, 16)) * 3 // 240
                ],
                end="",
            )
    print("}")


if __name__ == "__main__":
    main()

And here is the flag : FCSC{53974823417#691}