Bearmock Python 3 and virtual serial port mods

12.11.2024
Bearmock Python 3 and virtual serial port mods

https://recon.cx/2013/slides/Recon2013-Gabriel%20Tremblay-Reversing%20P25%20Radios.pdf

Hardware used: USB to serial adapter (Aten UC-232A) + USB serial null modem adapter (S6618, cheap device from eBay). Probably it would be quite easy to write Arduino code and use two Arduinos connected with software serial.

I modified this code https://github.com/gabtremblay/Bearmock to run in Python 3 (3.13, pyserial 3.5) and without com0com software virtual serial port.





 



 

from time import sleep
from serial import Serial

__MODEL = 'BCD296D'
__PORT = 'COM21'
__SPEED = 9600
__TIMEOUT = 0  # non-blocking
__READ_SLEEP_SECS = 0
__OUT = 'decoded.s19'


__ACTIONS = {
    '\r': 'UNKNOWN COMMAND\r',  # Empty, just reply
    '*SUM\r': 'CHECKSUM= DEADH\r',  # Fake checksum
    '*SPD 1\r': 'SPEED 9600 bps\r',
    '*SPD 2\r': 'SPEED 19200 bps\r',
    '*SPD 3\r': 'SPEED 38400 bps\r',
    '*SPD 4\r': 'SPEED 57600 bps\r',
    '*SPD 5\r': 'SPEED 115200 bps\r',
    '*PGL 11000000000\r': 'OK\r',
    '*PGL 1000000000000000000\r': 'OK\r',
    '*PGL 1100000\r': 'OK\r',
    '*ULE\r': 'OK\r',
    '*PRG\r': 'OK\r',
    '*MDL\r': __MODEL + '\r',
    '*FDP\r': 'FDP 3.\r',
    '*REG\r': 'R 1\r',
    '*APP\r': 'Version 3.00.00\r',
    '*VER\r': 'Version 3.00.00\r',
    '*SCB 1\r': 'SCB 1\r',
    '*RTS F\r': 'RTS OFF\r',
    '*MOD 1\r': 'MODE 1\r',
    '*WWS N\r': 'WWS 0\r',
    '*SUM 1 0\r': 'CHECKSUM= C68FH\r',
    '*SUM 6 0\r': 'CHECKSUM= DEADH\r',
}

if __name__ == "__main__":
    try:
        port = Serial(__PORT, __SPEED, timeout=__TIMEOUT, bytesize=8, parity='N', stopbits=1)
    except Exception as ex:
        print(ex)
        exit()

    outfile = open(__OUT, 'wb')
    
    print("Reading port... " + __PORT)
    readbuf = ''
    while True:
        try:
            byte = port.read(1)
            if len(byte) > 0:
                #num = int(byte.encode('hex'), 16) Python 2!
                num = int.from_bytes(byte)
                #print str(num) + ' (' + chr(num) + ')'
                readbuf = ''.join([readbuf, chr(num)])
                if num == 13:  # got a \r == EOL
                    if readbuf[0:2] == 'S8':
                        print("End of firmware (updater will crash ;)")
                        readbuf = readbuf.replace('\x0d', '\x0d\x0a')
                        outfile.write(readbuf.encode())
                        outfile.close()
                        port.close()
                        exit()
                    elif readbuf[0:2] == 'S0' or readbuf[0:2] == 'S2':
                        readbuf = readbuf.replace('\x0d', '\x0d\x0a')
                        outfile.write(readbuf.encode())
                    else:
                       
                        print("Received command: ",)
                        print(readbuf)

                        action = __ACTIONS.get(readbuf.strip(''))
                        if not action:
                            print("No corresponding action found")
                        else:
                            print("Sending: " + action + "\n")
                            port.write(str.encode(__ACTIONS.get(readbuf.strip(' '))))
                            if readbuf[0:4] == '*SPD':
                                port.close()
                                if readbuf[0:6] == '*SPD 1':
                                    port.baudrate = 9600
                                elif readbuf[0:6] == '*SPD 2':
                                    port.baudrate = 19200
                                elif readbuf[0:6] == '*SPD 3':
                                    port.baudrate = 38400
                                elif readbuf[0:6] == '*SPD 4':
                                    port.baudrate = 57600
                                elif readbuf[0:6] == '*SPD 5':
                                    port.baudrate = 115200
                                port.open()
                        
                    port.flush()                            
                    readbuf = ''

        except Exception as ex:
            print(ex)
            exit()

        sleep(__READ_SLEEP_SECS)

    port.close()
    outfile.close()

 

A bit tuned actions ...


__ACTIONS = {
    '\r': 'UNKNOWN COMMAND\r',  # Empty, just reply
    '*SUM\r': 'CHECKSUM= DEADH\r',  # Fake checksum
    '*SPD 1\r': 'SPEED 9600 bps\r',
    '*SPD 2\r': 'SPEED 19200 bps\r',
    '*SPD 3\r': 'SPEED 38400 bps\r',
    '*SPD 4\r': 'SPEED 57600 bps\r',
    '*SPD 5\r': 'SPEED 115200 bps\r',
    '*PGL 11000000000\r': 'OK\r',
    '*PGL 1000000000000000000\r': 'OK\r',
    '*PGL 1100000\r': 'OK\r',
    '*PGL 110000000\r': 'OK\r',
    '*ULE\r': 'OK\r',
    '*PRG\r': 'OK\r',
    '*MDL\r': __MODEL + '\r',
    '*FDP\r': 'FDP 3.\r',
    '*REG\r': 'R 1\r',
    '*APP\r': 'Version 3.00.00\r',
    '*VER\r': 'Version 3.00.00\r',
    '*SCB 1\r': 'SCB 1\r',
    '*SCB 2\r': 'SCB 2\r',
    '*RTS F\r': 'RTS OFF\r',
    '*MOD 1\r': 'MODE 1\r',
    '*WWS N\r': 'WWS 0\r',
    '*SUM 1 0\r': 'CHECKSUM= C68FH\r',
    '*SUM 6 0\r': 'CHECKSUM= DEADH\r',
    '*RMV\r': 'OK\r',
    '*OFF\r': 'OK\r',
}

Comments

Popular posts from this blog

Mods for SDR# TETRA demod plugin 1.0.14.0 - 2

Modifying old SDR# TETRA demod plug-in