Open swiftgeek opened 1 year ago
Great, glad to hear it works.
I'm using optiboot bootloader in my Arduino board and have SUT fuses set to 4.1ms pre-delay, so I didn't have to complicate it.
Out of curiosity, what is that keyboard you have tested it on?
I've another keyboard - Genesis Thor 300 RGB. There is SH68F90 on PCB. I'll try it to check if it works on different chip too.
Setup with relying on quick bootloader doesn't work for me, because, I would also need to connect external UART and complicate it even further, but detecting vref is rather clean though I will probably need to also add high side switch to mess with other ~opcodes so hopefully I can erase and write soon. (sadly there aren't many erased bytes remaining in my stock fw, and I don't have idea about opcode for mass/sector erase so I guess I will just try all 0x40-x4F until some sector erases)
Mechanical keyboard with single color LEDs (each row having different color) RE-K70-BYK800 on PCB silkscreen, HYKKER branding on case. I have some very partial pinouts for SH68F88 and they match so far (Power/USB/JTAG/Reset).
Not entirely sure which one should be VDP, but one of those two :)
@swiftgeek Why do you need to connect external UART? Optiboot just jump to sketch directly in case of POR, UART stuff should work the same as with stock one. Did you measure with oscilloscope what is going on in your case? How long was that boot delay?
When I started to experiment with this, I had it all on breadboard with power controlling circuit, but ultimately just wires to Arduino Nano was the most convenient solution when I got rid of boot delay.
Thanks for the info. I read that BYK800 chip is supposed to be a clone of some SinoWealth MCU, but I wouldn't guess it's 1:1 copy of SH68F881 with the same part number programmed inside.
It's just some company hiding MCU used, BYKxxx is using variety of chips and vendors. Sadly removing markings/replacing with your own markings is a common practice those days. I have seen even regular classic opamps parts having markings scratched off/replaced, to pretend device is much smarter than it is.
Additionally sinowealth supplies dice so it would be technically feasible to package it yourself with entirely different pinout/package, but I haven't seen that much effort put into hiding your supply chain chain yet.
If I hotplug UART with atmega, I have to deal not only with atmega boot time, but also that one from UART chip, and UART console app on host and entire enumeration. Sensing DUT Vcc is trivial in comparison, and pretty much eliminates all timing/enumeration issues.
You do what you need to do, but now I'm lost completely. What is your setup here? You don't need to do any of that. Just get your ATmega to execute code within first 20ms for first power-up to establish the connection, then any additional delays won't matter.
But you're right about that chinese practice of sanding out of IC markings or replacing them, find datasheets for those chips is pure luck. I'm surprised that SinoWealth let firmwares for their programmers to be downloaded without some NDA bullshit. I wish every IC manufacturer were like Microchip or Renesas...
BTW, I've failed to dump firmware of SH68F90 in second keyboard. It has all security bits set, even executing MOVC instruction is blocked at hardware level :(
I prefer having less race conditions in my setup, and less things changing at a time. Makes debugging/troubleshooting easier (but cost/benefit also needs to be taken into account ofc, and the less connections/setup is actually required the better too)
As for SH68F90 I guess "mass erase" would unlock it, but I have no expectations on how would that opcode look like / what parameters would it take (or additional opcodes required like address opcodes for read/write operations), so it's up to your reversing skills there. It's probably better to test that on SH68F88 and related dies since it doesn't seem to mention code protection capabilities but I might be wrong about that. In any case I think I can test any ideas about remaining opcodes if you run into any (I'm starting to guess that 0xFF
is a NOP
opcode, but need to test that more).
The mass erase operation will erase all the contents of program code, code option, code protect bit and customer code ID, regardless the status of code-protect control mode
Ah sorry now I get that making dump is important for backing up stock firmware, then I would guess it would easily fall to voltage glitching attacks. I have so little interest in original firmware that it completely went over my head.
Though SH68F90 exposes less rails than SH68F88 so it might be a bit challenging
Mass erase would help, but my goal is to dump the firmware, not programming or erasing the chip. I broke some firmwares out of protected chips before, but I have a feeling that this one will be hard.
There is no 0xFF
opcode, if it works for you, it just skipped it because it's invalid.
It would help to get boot ROM from one of these chips, I guess there is communication protocol implemented. But I don't have chip that have boot ROM programmable, don't know if it's possible to read it from the chips we're dealing with now.
I'm just going off sinowealth using 0xFF
in sorta that way, and making the most sense I can out of it, likening it to other programming protocols like serprog. If it skips on invalid opcodes then that's great to hear.
I don't know if it skip invalid commands, but if 0xFF
does nothing for you, it seems so. What I can say, programmer firmware never send such command to the chip. It does send 0x46 0xFF command to it every few ms when it's in connection mode 150 (0x96 for you :)), so I suppose it's some PING or SYNC or whatever.
I already started using defines heavily in hexed
branch, but if my 0xFF
guess is correct then my changes are currently misguiding in few places. Not trying to push that any time soon to not give you more troubles with reversing JET51, and would prefer to be more confident first in what each opcode does.
I don't know what opcode 0x46
does yet, but it seems to take a parameter, other possible value than 0xFE
being 0xF0
.
Do you have a list of opcodes used by programmer (especially erase if identified that far)?
It's not just single opcode to do flash erase/program, I'll try to document it.
As I'm looking on it now, 0x46
is probably some connection state:
0x46 0xFF
- idle
0x46 0xFE 0xFF
- during programming/erasing? (chip type 0)
0x46 0xF0 0xFF
- during programming/erasing? (chip type 2,6)
If 0xFF
is indeed NOP
, then I would guess it's similar stuffing as last extra bit after each 8bit word - some commands have shifted output by 1 cycle (like what happens with/during 0xAA
opcode), so I guess they added it to account for that. I mean I guess NOP
would give MCU more time to finish some operation.
If programmer give MCU time to do something, it just wait or emits clock pulses. It never sends 0xFF
alone, but who knows.
It sends NOPs instructions in JTAG mode, but this is completely different story. In that mode raw instruction opcodes can be send and CPU executes them directly. That is why MOVC can be blocked with security bit.
I just realized I mixed it up. The command that is sent every few milliseconds (PING, SYNC?) is 0x49 0xFF, command sent during programming is 0x46.
Hey,
Just reporting that I was able to do a partially successful dump firmware from a NuPHY Air60 which has an SH68F90A (labeled as BYK916
, reports as 68F90A0000
).
Firmware seems to be intact:
$ strings docs/dumps/nuphy-air60-flash-dump.bin -e l
Gaming KB
SINO WEALTH
0001
BY Tech
USB Descriptor:
Bus 001 Device 003: ID 05ac:024f Apple, Inc. Aluminium Keyboard (ANSI)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x05ac Apple, Inc.
idProduct 0x024f Aluminium Keyboard (ANSI)
bcdDevice 1.10
iManufacturer 1 BY Tech
iProduct 2 Air60
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x003b
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 1 Keyboard
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 89
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 227
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0010 1x 16 bytes
bInterval 1
Device Status: 0x0000
(Bus Powered)
P.S. Yes, it really does use Apple's idVendor (probably the idProduct too)
@carlossless Many thanks for the valuable info :)
Started working on recreating schematics and boardview in kicad for my board, based on CCD scans annotated in gimp. So far I have following results that could be applicable for more BYKxxx boards:
Pushed early WIP schematics, waiting for new kicad release to hit distro's repo to generate boardview
Turns out my part is SH68F881 (I don't have markings on package)
Binary was recreated using
xxd -r -p test.hex > test.bin
and it contains strings found in USB descriptorFirst block of ~code/data starts at
0x1000
, next0x3000
, then0x5000
, then0x7000
, and finally two tiny binary portions at0x7F00
(65 bytes) and 5 bytes at0x7FA0
Since my arduino board take quite a long time to start a sketch, I ended up using digital pin 6 as vref detection (using analog pin for this would be a massive overkill). https://github.com/swiftgeek/sinowealth-8051-dumper/commit/8b356de8aebf0a08b9e456207b836cfc9bcb71d5