Декомпиляция двоичного файла 8051, чтение из EEPROM - PullRequest
0 голосов
/ 06 февраля 2020

Я пытаюсь декомпилировать прошивку беспроводного джойстика Logitech Freedom 2.4. Мне удалось получить что-то из EEPROM. ( здесь ) Используемая EEPROM - это микросхема 25AA320, которая является 32-битной SPI-EEPROM. MCU - это nRF24E1G, который содержит 8051 MCU. ПЗУ должно быть 4096 байт, поэтому я думаю, что моя программа чтения зациклилась на нем 4 раза. Мне удалось извлечь 4 КБ ПЗУ ( здесь ), но начало файла не выглядит чистым.

Я загрузил оба файла в IDA Pro и Ghidra и выбрал процессор 8051. Они не генерируют ничего полезного.

Может ли кто-нибудь помочь мне декомпилировать этот ПЗУ?

Я использовал этот Arduino Sketch, чтобы выгрузить диск. Вместе с этим python скрипт

## Author: Arpan Das
## Date:   Fri Jan 11 12:16:59 2019 +0530
## URL: https://github.com/Cyberster/SPI-Based-EEPROM-Reader-Writer

## It listens to serial port and writes contents into a file
## requires pySerial to be installed 
import sys 
import serial
import time
start = time.time()

MEMORY_SIZE = 4096 # In bytes
serial_port = 'COM5'
baud_rate = 115200 # In arduino, Serial.begin(baud_rate)
write_to_file_path = "dump.rom"

output_file = open(write_to_file_path, "wb")
ser = serial.Serial(serial_port, baud_rate)

print("Press d for dump ROM else CTRL+C to exit.")
ch = sys.stdin.read(1)

if ch == 'd':
    ser.write('d')
    for i in range(MEMORY_SIZE/32): # i.e. MEMORY_SIZE / 32
        # wait until arduino response with 'W' i.e. 1 byte of data write request
        while (ser.read() != 'W'): continue
        ser.write('G') # sends back write request granted signal

        for j in range(32):
            byte = ser.read(1);
            output_file.write(byte);

        print(str(MEMORY_SIZE - (i * 32)) + " bytes remaining.")

print '\nIt took', time.time()-start, ' seconds.'

1 Ответ

1 голос
/ 08 февраля 2020

Это то, что я сделал, следующая часть для вас. Моя машина - ноутбук с Win10, однако я использовал инструменты unix, потому что они так способны.

Прежде всего, я разделил дамп 16 КБ на четыре части по 4 КБ. Первый из них отличался от трех других. И предоставленный дамп 4 КБ отличается от всех этих частей. Я не стал исследовать это дальше, а просто взял одну из трех равных частей.

$ split -b 4K LogitechFreedom2.4CordlessJoystick.rom part
$ cmp partaa partab
partaa partab differ: byte 1, line 1
$ cmp partab partac
$ cmp partac partad
$ cmp dump.rom partaa
dump.rom partaa differ: byte 9, line 1
$ cmp dump.rom partab
dump.rom partab differ: byte 1, line 1

Из таблицы данных микроконтроллера я узнал, что содержимое EEPROM имеет заголовок не менее 3 байтов ( глава 10.2 на стр. 61).

Это следующие байты:

0b   Version = 00, Reserved = 00, SPEED = 0.5MHz, XO_FREQ = 16MHz
03   Offset to start of user program = 3
0f   Number of 256 bytes block = 15 

Кажется, что последняя запись отключена на единицу, поскольку, похоже, в 16-м блоке также есть код.

В любом случае, эти байты выглядят прилично, поэтому я вырезал первые 3 байта.

$ dd if=partad of=rom.bin bs=1 skip=3
4093+0 records in
4093+0 records out
4093 bytes (4,1 kB, 4,0 KiB) copied, 0,0270132 s, 152 kB/s
$ dd if=partad of=head.bin bs=1 count=3
3+0 records in
3+0 records out
3 bytes copied, 0,0043809 s, 0,7 kB/s
$ od -Ax -t x1 rom.bin > rom.hex
$ od -Ax -t x1 head.bin > head.hex

Шестнадцатеричные файлы удобны для загрузки их в редактор и просмотра.

Я загрузил оставшиеся 4093 байта в дизассемблер, который однажды написал, и немного заглянул. Это выглядит многообещающе, поэтому я думаю, что вы можете go без меня сейчас:

C0000:  ljmp    C0F54

C0003:  setb    021H.2
        reti

C000B:  xch     a,r5
        inc     r6
        xrl     a,r6
        mov     a,#0B2H
        movc    a,@a+pc
        movx    @r1,a
        mov     r7,a
        setb    021H.2
        reti

C0F54:  mov     psw,#000H
        mov     sp,#07BH
        mov     r0,#0FFH
        mov     @r0,#000H
        djnz    r0,C0F5C
        ljmp    C0C09
...