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
Post a Comment