mitxela.com forum
Welcome. Please log in or register.

« PreviousNext »Pages: 1 2 3 [4] 5

Beken BK3231
timschu Posted: 24 Jul 2022, 10:11 AM
Avatar


Member
Posts: 2
Joined: 23-July 22
FYI. You can read/erase/write the JDY-31 BK3231S flash with a CH341A programmer.

(User posted image)


(User posted image)


Last edit by timschu at 24 Jul 2022, 10:11 AM

-------------
[top]
timschu Posted: 24 Jul 2022, 05:16 PM
Avatar


Member
Posts: 2
Joined: 23-July 22
BK3231

erase chip
W 31 02 A5
W 31 03 C3
W 25
wait 100 ms
W 31 02 00
W 31 03 00

erase sector
W 31 02 A5
W 31 03 C3
W 24 aa aa
wait 50 ms
W 31 02 00
W 31 03 00

read 4 bytes
W 22 aa aa
R dd dd dd dd

program 4 bytes
W 31 02 A5
W 31 03 C3
W 21 aa aa dd dd dd dd
W 31 02 00
W 31 03 00

"aa aa" is address / 4, high byte first

"dd dd dd dd" is 4 bytes of data

1 sector is 0x1000 bytes, sector containing specified address will be erased

JDY-30 BK3231 firmware is read-protected, returns FF FF FF FF ... :(

MSB of programmed bytes 0, 4, 8, 12, 16, 20, 24, ... flip ~50% of the time, not sure why. Maybe BK3231 is not 100% compatible with my CH341A programmer.

-------------
[top]
iscle Posted: 12 Sep 2022, 10:44 PM
Avatar


Member
Posts: 6
Joined: 23-January 21
That's interesting! I had completely forgot about this thread/device but being able to talk to it with a CH341 is awesome!

I'll play with it if I have some time in the future :D

-------------
[top]
shenron Posted: 26 Oct 2022, 04:34 PM
Avatar


Member
Posts: 1
Joined: 26-October 22
Hi, i bought a JDY-31 SPP-C.
The chip on the PCB is a BK3431S.
Do you think i could update the firmware to RN42 ?
Can it be done with a Arduino Mega 2560 R3 or a Arduino Leonardo ?
Do you know a good tutorial to perform the task ?

(User posted image)


(User posted image)


Last edit by shenron at 26 Oct 2022, 04:35 PM

-------------
[top]
davidalfa Posted: 26 Dec 2022, 05:59 PM
Avatar


Member
Posts: 1
Joined: 26-December 22
I wrote a script for the BK3231, using AsProgrammer so I could easily perform most operations with a CH341A.
Read works, erase works, blank check works...but on writing, the verification fails every 32 bytes, so there must be something related to the CRC we're missing.

Interestingly, tried writing random things, filling the entire flash with "Hi!!", the verification worked!
Seems like the MSB bit (0x80) of every 32th byte means something!

Additionally, it seems the maximum speed it can handle is 2MHz, which is pretty close to what the CH341A uses (~1.7MHz).
I tested it with a BusPirate, at 4.5MHz it returned garbage.


Here you have my FLASH DUMP.

You will notice every group of 4 bytes is reversed compared to other backups.
That's because they dumped it wrong, reversing the endianess!

Even more strange, after erasing the flash and writing back the dump (Ignoring those errors), the device is working normally!



// Contents will be written to the editor buffer
{$ READ_TO_EDITOR}
begin
blocks:=$10000; // 64K blocks
block_sz:=4; // each block is 4 bytes
block:=0; // read block address
address:=0; // Output buffer position
readBuf:=CreateByteArray(block_sz);
OutBuf:=CreateByteArray(blocks*block_sz);
LogPrint('--------------------------------------------------------------------------------------------------');
if not SPIEnterProgMode (_SPI_SPEED_MAX) then
begin
LogPrint ('SPI Error!');
exit;
end;
LogPrint('Block Start: ' + inttohex(0,4) + ', End: ' + inttohex(blocks-1,4));
LogPrint('Reading...');
while address < (blocks*block_sz) do
begin
if (block and $FFF)=0 then
LogPrint('BLOCK: ' + inttohex(block,4));
SPIWrite (0, 3, $22, (block shr 8), block);
SPIRead(1, block_sz, readBuf);
for i:=0 to (block_sz-1) do
SetArrayItem(OutBuf, address+i, GetArrayItem(readBuf, i));
Inc(block, 1);
Inc(address, block_sz);
end;
ReadToEditor((blocks*block_sz), 0, OutBuf);
SPIExitProgMode();
LogPrint('Success!');
LogPrint('--------------------------------------------------------------------------------------------------');
end

// You must open a file in the editor before writing!
{$ WRITE_FROM_EDITOR}
begin
blocks:=$10000; // 64K blocks
block_sz:=4; // each block is 4 bytes
block:=0; // write block address
address:=0; // Input buffer position
stop_on_error:=0; // Choose whether to stop on first error
verify:=1; // Choose whether to verify
error:=0;
cs:=0;
readBuf:=CreateByteArray(block_sz*4);
writeBuf:=CreateByteArray(blocks*block_sz);
WriteFromEditor(blocks*block_sz, 0, writeBuf);
LogPrint('--------------------------------------------------------------------------------------------------');
if not SPIEnterProgMode (_SPI_SPEED_MAX) then
begin
LogPrint ('SPI Error!');
exit;
end;
LogPrint ('Erasing chip...');
SPIWrite (1, 3, $31, $02, $A5); // Unlock flash
SPIWrite (1, 3, $31, $03, $C3);
SPIWrite (1, 1, $25);
LogPrint ('Wait 100ms...');
Delay (100);
LogPrint('Block Start: ' + inttohex(0,4) + ', End: ' + inttohex(blocks-1,4));
LogPrint('Writing...');
while address < (blocks*block_sz) do
begin
if (block and $FFF)=0 then
LogPrint('BLOCK: ' + inttohex(block,4));

SPIWrite (1, 7, $21, (block shr 8), block, // Write 4 bytes
GetArrayItem(writeBuf, address), GetArrayItem(writeBuf, address+1),
GetArrayItem(writeBuf, address+2), GetArrayItem(writeBuf, address+3));
if(verify) then
begin
SPIWrite (0, 3, $22, (block shr 8), block); // Read back 4 bytes
SPIRead(1, block_sz, readBuf);
for i:=0 to (block_sz-1) do // Verify what we just sent
begin
if not (GetArrayItem(readBuf, i) = GetArrayItem(writeBuf, address+i)) then
begin
LogPrint('ERROR at address: ' + inttohex(address+i,4) +
', Written: ' + inttohex(GetArrayItem(writeBuf, address+i),2) +
', Read: ' + inttohex(GetArrayItem(readBuf, i),2));
if (stop_on_error) then
begin
error:=1;
break;
end;
end;
end;
end;
if error then break;
Inc(block, 1);
Inc(address, block_sz);
end;
SPIWrite (1, 3, $31, $02, $00); // Lock flash
SPIWrite (1, 3, $31, $03, $00);
SPIExitProgMode();
if error then LogPrint('Error!')
else LogPrint('Success!');
LogPrint('--------------------------------------------------------------------------------------------------');
end

// Verify contents. You must first open a file in the editor!
{$ VERIFY}
begin
blocks:=$10000; // 64K blocks
block_sz:=4; // each block is 4 bytes
block:=0; // write block address
address:=0; // Input buffer position
stop_on_error:=0; // Choose whether to stop on first error
error:=0;
readBuf:=CreateByteArray(block_sz);
editBuf:=CreateByteArray(blocks*block_sz);
WriteFromEditor(blocks*block_sz, 0, editBuf);
LogPrint('--------------------------------------------------------------------------------------------------');
if not SPIEnterProgMode (_SPI_SPEED_MAX) then
begin
LogPrint ('SPI Error!');
exit;
end;
LogPrint('Block Start: ' + inttohex(0,4) + ', End: ' + inttohex(blocks-1,4));
LogPrint('Verifying...');
while address < (blocks*block_sz) do
begin
if (block and $FFF)=0 then
LogPrint('BLOCK: ' + inttohex(block,4));
SPIWrite (0, 3, $22, (block shr 8), block);
SPIRead(1, block_sz, readBuf);
for i:=0 to (block_sz-1) do
begin
if not (GetArrayItem(readBuf, i) = GetArrayItem(editBuf, address+i)) then
begin
if (stop_on_error) then
begin
error:=1;
break;
end;
end;
end;
if error then break;
Inc(block, 1);
Inc(address, block_sz);
end;
SPIExitProgMode();
if error then LogPrint('Error!')
else LogPrint('Success!');
LogPrint('--------------------------------------------------------------------------------------------------');
end

// Erases the entire chip
{$ ERASE_CHIP}
begin
LogPrint('--------------------------------------------------------------------------------------------------');
if not SPIEnterProgMode (_SPI_SPEED_MAX) then
begin
LogPrint ('SPI Error!');
exit;
end;
LogPrint ('Erasing chip...');
SPIWrite (1, 3, $31, $02, $A5);
SPIWrite (1, 3, $31, $03, $C3);
SPIWrite (1, 1, $25);
LogPrint ('Wait 200ms...');
Delay (200);
SPIWrite (1, 3, $31, $02, $00);
SPIWrite (1, 3, $31, $03, $00);
LogPrint('Run a blank check if you want to ensure correct erase operation!');
LogPrint('Success!');
LogPrint('--------------------------------------------------------------------------------------------------');
end

// Verify contents. You must first open a file in the editor!
{$ BLANK_CHECK}
begin
blocks:=$10000; // 64K blocks
block_sz:=4; // each block is 4 bytes
block:=0; // write block address
address:=0; // Input buffer position
stop_on_error:=0; // Choose whether to stop on first error
error:=0;
readBuf:=CreateByteArray(block_sz);
LogPrint('--------------------------------------------------------------------------------------------------');
if not SPIEnterProgMode (_SPI_SPEED_MAX) then
begin
LogPrint ('SPI Error!');
exit;
end;
LogPrint('Block Start: ' + inttohex(0,4) + ', End: ' + inttohex(blocks-1,4));
LogPrint('Performing blank check...');
while address < (blocks*block_sz) do
begin
if (block and $FFF)=0 then
LogPrint('BLOCK: ' + inttohex(block,4));
SPIWrite (0, 3, $22, (block shr 8), block);
SPIRead(1, block_sz, readBuf);
for i:=0 to (block_sz-1) do
begin
if not (GetArrayItem(readBuf, i) = $FF) then
begin
LogPrint('Blank check failed at address: ' + inttohex(address+i,4) +
', Read: ' + inttohex(GetArrayItem(readBuf, i),2));
if (stop_on_error) then
begin
error:=1;
break;
end;
end;
end;
if error then break;
Inc(block, 1);
Inc(address, block_sz);
end;
SPIExitProgMode();
if error then LogPrint('Error!')
else LogPrint('Success!');
LogPrint('--------------------------------------------------------------------------------------------------');
end


A capture from the logic analyzer:
(User posted image)



(User posted image)


Last edit by davidalfa at 27 Dec 2022, 01:23 PM

-------------
[top]
PookyFan Posted: 11 Feb 2024, 11:21 PM
Avatar


Member
Posts: 8
Joined: 11-February 24
Hello. Just digging out this thread after over a year - don't mind me.

I'm trying to figure out how to customize firmware on JDY-31 (the BT module with BK3231S MCU). There is some information on how to access its flash memory in this thread already, but there are some missing pieces, so I'd like to sum it up somehow, as I experimented with this module myself and as of now am able to dump the firmware. I am currently in the process of figuring out building custom firmware, and I'd eventually try to flash it and test how (if) it works.

Let's start with connecting JDY-31 to SPI programmer. I personally use Raspberry Pi Pico as serial programmer, but any other 3V3 SPI programmer (like CH341A - just remember to have it modded!) should also work. On this thread's page 2 diizuka made pretty accurate assumptions on pins locations and how they should be connected:
QUOTE (diizuka)
(User posted image)

From my observations, however, it looks like you don't have to connect WP_FLA pin to VCC (you may leave it floating, connecting it to VCC doesn't seem to change anything). Also, instead of pulling CSN_FLA pin to ground, it's better to connect it to SPI programmer's CS line. So in the end, you should end up connecting JDY-31 pins like so:
TESTEN => VCC
P30_ADC0 => VCC
HOLD_FLA => VCC
SI_FLA => SPI prog MOSI
SCK_FLA => SPI prog SCK
CSN_FLA => SPI prog CS
SO_FLA => SPI prog MISO

Now BK3231S should be visible to SPI programmer as normal flash memory. For the purpose of reading its content, I'm using flashrom tool (available for all major OS like Linux, Windows or MacOS).

(User posted image)


As you can see, flashrom detected it as EN25F40 chip with 512 kB of memory - that's rather plenty. The firmware doesn't take up entire flash, so large region at the end of it is blank (filled with 0xFF). Next thing worth noting (that was already spotted by others in this thread) is that every 32 byte of actual firmware, there are two bytes that turned up to be CRC (I'll talk about it later). So unless you do some cleanup, it would be hard to do ahything with it (in terms of reverse engineering).

(User posted image)


That would be it for reading MCU's firmware. Now we'd like to write our own and make JDY-31 do as we please. It turns out there is SDK available on Github for this chip (also posted earlier in this thread, by iscle). I haven't tried building it yet, but here are some interesting things about it.Turns out they actually pushed binary files together with the code. Among them are two files containing final firmware - "BK3231S_Test_Firmware.bin" and "BK3231S_Test_Firmware_crc.bin". And you've probably guessed it already, but the second one matches (at least its start does) firmware dumped from JDY-31's MCU. The first one, on the other hand, doesn't have CRC every 32 bytes. Looking at this project's configuration file, it looks like CRC version is prepared using some "encrypt" tool, which is unfortunately not included in this repo, but it's the one mentioned by diizuka:
QUOTE (diizuka)
BTW, the misterious on 16 + 2 bytes is solved.
encrypt.exe adds 2bytes CRC for each 32 bytes.
https://github.com/cornrn/bk7231_freertos_sdk/tree/master/tool/crc%20binary

encript.exe CRComitted.bin 0
will generate same binary got from flash.

Using this tool on non-CRC'd firmware file from the repository results in adding the same two bytes every 32 byte that are present in firmware we've just dumped.

So now it's time to make use of this SDK and program JDY-31 with something more custom. But this is something I'm yet to deal with. I'll report any progress on that in the following posts.

-------------
[top]
mr_woggle Posted: 17 Feb 2024, 02:33 PM
Avatar


Member
Posts: 8
Joined: 17-February 24
@Pookyfun Thanks for all the info. I'm trying to repurpose a bluetooth tag with a similar chipset.

(User posted image)


Took me a while to realise that this is S version. So there is no PPROG, but instead the TESTEN and P30 should are used and should be high to allow for read/write access.
The SPI is very generic and any tool will suffice. (I used and ESP32 to read out the flash). And as you can see:

00000000: 18F0 9FE5 18F0 9FE5 18F0 9FE5 18F0 9FE5  ................
00000010: 18F0 9FE5 00A0 E118 18F0 9FE5 18F0 9FE5 ................


Next bytes are 0xAFF4 So same checksum on that.

Any progress on the SDK / compilation efforts?


-------------
[top]
PookyFan Posted: 19 Feb 2024, 02:36 AM
Avatar


Member
Posts: 8
Joined: 11-February 24
QUOTE (mr_woggle)
Any progress on the SDK / compilation efforts?
I only managed to get it to compile. That's already a big step, since the quality of the code is questionable at best. Plus its project was created and managed by some old uVision IDE version, and even outdated tool like that needs some kind of ARM license I obviously don't have. So I decided to migrate it to cmake project with GCC.
Even though it compiles, I'm still half way there, since I haven't corrected all compilation warnings yet (and I'd rather do that since, as I said, the code is of questionable quality). I also need to migrate assembly files which I didn't include into compilation process yet (the format differs slightly from GNU assembly used by GCC). Then migrate linker script so to make use of these assembly files setting up interrupt vectors and whatnot... Lots of work ahead of me.

In the long run it may be worth to completely rewrite this SDK, but for the time being I just want to have something to flash my BT module with to test if it works fine. I'm also starting to have some suspicions about binary blob that is statically linked to the firmware (the BK3231S_LIB.lib file), it may be just some generic Bluetooth stack rather than close-to-hardware library, as I suspected it to be at the beginning. If it's just a BT stack thing, then it may be possible to replace it with something more open source (like btstack), but again - this is more of a long-run action to make firmware for BK3231S truly open source and of acceptable quality.

-------------
[top]
mr_woggle Posted: 19 Feb 2024, 11:53 AM
Avatar


Member
Posts: 8
Joined: 17-February 24
QUOTE (PookyFan)
Even though it compiles, I'm still half way there, since I haven't corrected all compilation warnings yet (and I'd rather do that since, as I said, the code is of questionable quality). I also need to migrate assembly files which I didn't include into compilation process yet (the format differs slightly from GNU assembly used by GCC). Then migrate linker script so to make use of these assembly files setting up interrupt vectors and whatnot... Lots of work ahead of me.

A lot of work indeed! Keep me updated on your efforts :) I'd love to join at some point.

So according to the datasheet it *should have* JTAG. Although this is not specified. It's an ARM968E-S arch. Not sure where the TCK, TMS, TDI and TDO would be. It would kind of speed of debugging if that would be possible.

Also found this evaluation kit board layout a while back:
(User posted image)

The OTP part (one time programmable for what?) at the right top also have CS, CK SI and SO. Mapping of pins is a bit weird though.

-------------
[top]
mr_woggle Posted: 19 Feb 2024, 12:49 PM
Avatar


Member
Posts: 8
Joined: 17-February 24
QUOTE (PookyFan)
I'm also starting to have some suspicions about binary blob that is statically linked to the firmware (the BK3231S_LIB.lib file)

ar -x BK3231S_LIB.lib


Gives me only the (non-stripped) object files.
     97K feb 19 13:24 bt_addr_sync.o
91K feb 19 13:24 bt_fhs_impl.o
335K feb 19 13:24 bt_init.o
339K feb 19 13:24 bt_mini_sched.o
317K feb 19 13:24 bt_pump.o
365K feb 19 13:24 bt_tester.o
325K feb 19 13:24 bt_test.o
247K feb 19 13:24 bt_timer.o
4,5K feb 19 13:24 devicebtj_adapter.o
183K feb 19 13:24 devicebtj_debuger.o
194K feb 19 13:24 devicebtj_endians.o
186K feb 19 13:24 devicebtj_fcs.o
4,4K feb 19 13:24 devicebtj.o
209K feb 19 13:24 devicebtj_stack_hci_cmd.o
228K feb 19 13:24 devicebtj_stack_hci_evt.o
194K feb 19 13:24 devicebtj_stack_hid.o
213K feb 19 13:24 devicebtj_stack_l2c.o
213K feb 19 13:24 devicebtj_stack_rfc.o
189K feb 19 13:24 devicebtj_stack_sdpdb_parser.o
197K feb 19 13:24 devicebtj_stack_sdp.o
185K feb 19 13:24 devicebtj_utils_key.o
187K feb 19 13:24 devicebtj_utils.o
314K feb 19 13:24 dl_dev_impl.o
406K feb 19 13:24 hc_cmd_disp.o
353K feb 19 13:24 hc_event_gen.o
336K feb 19 13:24 hc_flow_control.o
90K feb 19 13:24 hci_generic.o
91K feb 19 13:24 hci_params_impl.o
239K feb 19 13:24 hw_delay.o
91K feb 19 13:24 hw_lc_impl.o
306K feb 19 13:24 hw_lc.o
227K feb 19 13:24 hw_pta.o
574K feb 19 13:24 lc_interface.o
309K feb 19 13:24 lc_log.o
318K feb 19 13:24 lmp_acl_connection.o
327K feb 19 13:24 lmp_acl_container.o
384K feb 19 13:24 lmp_afh.o
477K feb 19 13:24 lmp_ch.o
343K feb 19 13:24 lmp_cmd_disp.o
327K feb 19 13:24 lmp_config.o
313K feb 19 13:24 lmp_con_filter.o
367K feb 19 13:24 lmp_ecc.o
338K feb 19 13:24 lmp_encode_pdu.o
314K feb 19 13:24 lmp_init.o
353K feb 19 13:24 lmp_inquiry.o
354K feb 19 13:24 lmp_link_control_protocol.o
318K feb 19 13:24 lmp_link_key_db.o
534K feb 19 13:24 lmp_link_policy.o
442K feb 19 13:24 lmp_link_policy_protocol.o
91K feb 19 13:24 lmp_link_power_control.o
479K feb 19 13:24 lmp_link_qos.o
365K feb 19 13:24 lmp_scan.o
91K feb 19 13:24 lmp_sco_container.o
378K feb 19 13:24 lmp_sec_core.o
140K feb 19 13:24 lmp_sec_engine.o
396K feb 19 13:24 lmp_sec_peer.o
348K feb 19 13:24 lmp_sec_upper.o
146K feb 19 13:24 lmp_ssp_engine.o
407K feb 19 13:24 lmp_ssp.o
325K feb 19 13:24 lmp_timer.o
130K feb 19 13:24 lmp_utils.o
429K feb 19 13:24 lslc_access.o
319K feb 19 13:24 lslc_afh.o
350K feb 19 13:24 lslc_assmnt.o
293K feb 19 13:24 lslc_class.o
235K feb 19 13:24 lslc_clk.o
331K feb 19 13:24 lslc_freq.o
263K feb 19 13:24 lslc_hop.o
309K feb 19 13:24 lslc_irq.o
364K feb 19 13:24 lslc_pkt.o
370K feb 19 13:24 lslc_slot.o
302K feb 19 13:24 lslc_stat.o
184K feb 19 13:24 sys_atomic.o
90K feb 19 13:24 sys_config_impl.o
104K feb 19 13:24 sys_config.o
99K feb 19 13:24 sys_rand_num_gen.o
328K feb 19 13:24 tc_cmd_disp.o
321K feb 19 13:24 tc_event_gen.o
513K feb 19 13:24 tc_interface.o
90K feb 19 13:24 tra_combined.o
342K feb 19 13:24 tra_hcit.o
352K feb 19 13:24 tra_queue.o
270K feb 19 13:24 tra_uart.o
150K feb 19 13:24 tra_usb.o
351K feb 19 13:24 uslc_chan_ctrl.o
325K feb 19 13:24 uslc_inquiry.o
333K feb 19 13:24 uslc_inquiryscan.o
375K feb 19 13:24 uslc_master_slave_switch.o
337K feb 19 13:24 uslc_page.o
363K feb 19 13:24 uslc_pagescan.o
319K feb 19 13:24 uslc_park_master.o
316K feb 19 13:24 uslc_park_slave.o
347K feb 19 13:24 uslc_return_to_piconet.o
354K feb 19 13:24 uslc_scheduler.o
433K feb 19 13:24 uslc_sleep.o
91K feb 19 13:24 uslc_switch_piconet.o
347K feb 19 13:24 uslc_testmode.o

This is 1:1 with the headers in src/Core
/btj_src

Seems to be some kind of ancient bt stack

-------------
[top]
mr_woggle Posted: 23 Feb 2024, 12:42 AM
Avatar


Member
Posts: 8
Joined: 17-February 24
So, the so-called encryption is just a pretty standard 16-bit crc checksum, start value 0xFFFF, polynominal = 0x8005

The following code should reproduce the same output as the beken encrypt tool (not sure if they use this tool on other mcu/flash chips, or they have something more sophistecated in the mean time)

Edge case is: if last chunk is less than 32 bytes it is filled with all 0xFF


# by mr_woggle - 2024
# free for all :D
import os

POLY = 0x8005
START_VAL = 0xFFFF

IN_FILE = "test.bin"
OUT_FILE = "test_encrypted.bin"

def crc16(data, poly, init_value=0):
crc = init_value
for byte in data:
crc ^= byte << 8
for _ in range(8):
if crc & 0x8000:
crc = (crc << 1) ^ poly
else:
crc <<= 1
return crc & 0xFFFF

test_message = bytearray(b'\x00' * 3 + b'\x02' + b'\x00' * 28) # test message, ignore

def add_crc16(input_file, output_file):
val = START_VAL
with open(input_file, 'rb') as infile, open(output_file, 'wb') as outfile:
chunk_size = 32
while True:
chunk = infile.read(chunk_size)
if not chunk:
break
if len(chunk) < chunk_size:
chunk += b'\xFF' * (chunk_size - len(chunk))
chunk = chunk[:-1] + b'\xFF' # last byte also 0xFF?
outfile.write(chunk)
out = crc16(chunk, POLY, val)
crc_bytes = out.to_bytes(length=2, byteorder='big')
outfile.write(crc_bytes) # Add two bytes (16-bit crc)

add_crc16(IN_FILE, OUT_FILE)
print("size after adding crc: ", hex(os.path.getsize(OUT_FILE)))

#crc = crc16(message, POLY, START_VAL)
#print("crc value:", hex(crc))



Binaries are idential if I sdiff between the two.


Last edit by mr_woggle at 23 Feb 2024, 12:43 AM

-------------
[top]
PookyFan Posted: 23 Feb 2024, 11:02 PM
Avatar


Member
Posts: 8
Joined: 11-February 24
Wow, I was just investigating this, as it was the last piece to my toolchain (using blackbox .exe binary, especially on Linux, is hardly appealing). How did you figure it out? I'm very curious.

-------------
[top]
mr_woggle Posted: 24 Feb 2024, 12:56 PM
Avatar


Member
Posts: 8
Joined: 17-February 24
Yeah, depending on those .exe files really suck. Similar to all those other flash upload tools. These companies somehow reinvent the wheel instead of just using something standard.

For the hack: I encrypted an all zero binary. 2-bytes crc output is 0x8029 (after every 32 bytes like you said). Did not seem anything special or custum. So I went for the most common option, which is poly=0x8005 and some start value. You can just bruteforce the start values. And then check when the output is also 0x8029. (did not even had to that, because I just luckily picked 0xFFFF :D)

You can write something yourself, but there are some cool tools out there (this one also has an overview of commonly used poly's etc) https://github.com/resilar/crchack


$ dd if=/dev/zero of=zero.bin bs=1 count=32
$ wine encrypt.exe zero.bin
$ wine encrypt.exe zero.bin zero_crc.bin
$ ./crchack -v -w16 -p 0x8005 -i 0xFFFF zero.bin
len(msg) = 32 bytes = 256 bits
CRC(msg) = 8029
8029


Some other chipsets of beken do use some sort encryption. I briefly looked at it. It uses 128-bit keys. So my guess is either AES or SM4 (chinese standard). Seems to have different outcome on consequetive blocks with the same data. So it is probably not ECB mode, but uses the outcome of previous block in some form.

-------------
[top]
PookyFan Posted: 24 Feb 2024, 01:06 PM
Avatar


Member
Posts: 8
Joined: 11-February 24
Very clever, I haven't thought about that method you used.
I allowed myself to grab your python code and use it in my post-build script (to hell with bash and external apps). This way I can easily transform binary from ELF into CRC'd build, integrated with default configuration blob (just took it from dumped firmware), pad it with 0xFF to have output image with size of the flash, and also have configuration at the right address in the image.

So basically everything is ready. There is just one small problem: my image doesn't seem to work. Like, at all. I flashed it yesterday and seems it doesn't even reach main() (no output from UART, and yeah having working JTAG would help here a lot). I'll be investigating this today and hopefully resolve it ASAP, so that I could finally publish my port of this SDK for everyone to use (it's still crapload of poorly written Chinese code, but at least buildable without ARM's proprietary tools).

-------------
[top]
PookyFan Posted: 26 Feb 2024, 02:13 AM
Avatar


Member
Posts: 8
Joined: 11-February 24
Allright, so there are some good news and some bad news.

The good news is that I am pretty much done with porting original SDK, and have it now as CMAKE project hosted on Github. You can clone it, build it and test it for yourself, if you want. The code is still horrible and I only applied necessary changes to make it work (while not making it any better overall). Plus some minor changes for traceability, but these are really small. I built it with arm-none-eabi-gcc so I don't make any guarantee to it working with other compilers (CLANG for example, although I'm not sure if CLANG supports ARM anyway). And you'll need python3 to run post-build script (thanks again to mr_woggle for providing CRC algorithm).

The bad news is that Bluetooth doesn't work at all. Everything else does though, or at least should - I only tested UART communication, but device also reads its configuration from flash properly, so I guess GPIO and whatnot should also be functionable. Although lack of Bluetooth kind of defeats the purpose of using this project, I'll be continuing with efforts to get it to work. If anyone would like to help, you are more than welcome, as this may be not easy for me to troubleshoot alone (majority of Bluetooth related code sits in the static library, so debugging it without JTAG would be a challenge, and most probably problem is either there or on the connection of the lib and SDK).

To make it work out of the box, I put the configuration from firmware I dumped from my JDY-31 as binary blob that is merged with final image. Default UART config is 9600 baud, one stop bit and no parity.

You can flash the image to JDY-31 using the same methods as for dumping original firmware from it. The flashrom tool I mentioned in my first post manages it without problem. It seems that the device needs to be powered off for a moment before it can run off with new firmware, though (to be confirmed).

So yeah, that's it for now. What a weekend it was, trying to get it to work...

-------------
[top]

« PreviousNext »Pages: 1 2 3 [4] 5

Sign in to post a reply.