Author Topic: Siglent .ads firmware file format  (Read 60372 times)

0 Members and 1 Guest are viewing this topic.

Online tv84

  • Frequent Contributor
  • **
  • Posts: 796
  • Country: pt
Re: Siglent .ads firmware file format
« Reply #325 on: June 10, 2019, 04:34:28 pm »
Out of curiosity, I've lately seen that xor with 0xFF in few places, and I have been thinking why not using the operator that does the same without the 2nd parameter (or the only parameter written explicitly when using compound assignment variants), i.e. bitwise complement (~).  That is "buf1[i1] = ~buf1[i1];"  (To me the complement is also "clearer" to read as it doesn't have the "unnecessary" 2nd parameter, but this may very well be a matter of opinion.)

Only a question of habit. The compiler should do it's magic...
 

Online tv84

  • Frequent Contributor
  • **
  • Posts: 796
  • Country: pt
Re: Siglent .ads firmware file format
« Reply #326 on: July 04, 2019, 07:39:57 pm »
The SDL1000X-E FW has been released.

It has a FW format different from all previous Siglent equipment's FW.

Nonetheless the first 0x70 bytes are the file header with the usual Siglent 3DES encryption:

Code: [Select]
File Header Size: 00000070
00000000 - File Header Checksum: FFFFF9C9 [00000004-0000006F]   CKSM OK
00000004 - File Size: 000DA5F4
0000000C - Product_ID: 700
00000026 - Vendor/Brand: SIGLENT
0000003A - USB Host Controller: ISP1763

The rest of the file may be sporadically encrypted or obfuscated but haven't discovered more details...

Janekivi, what's your opinion?

Proc seems to be STM32F427VGT6.
 
The following users thanked this post: BillB

Offline janekivi

  • Frequent Contributor
  • **
  • Posts: 362
  • Country: ee
Re: Siglent .ads firmware file format
« Reply #327 on: July 05, 2019, 01:45:04 pm »
No reverse, no FF.
screen.bmp at 0x000D70DC where are couple icons for the screen
like network, battery and yellow exclamation triangle.
 

Online tv84

  • Frequent Contributor
  • **
  • Posts: 796
  • Country: pt
Re: Siglent .ads firmware file format
« Reply #328 on: July 13, 2019, 05:01:29 pm »
Just for the record:

The SDL1000X(-E) .ADS has a 0x70 bytes encrypted header (usual Siglent 3DES).

After that, it has 3 concatenated blocks which start with executable STM32 ARM programs. These are unencrypted and unobfuscated.

The final parsing of the 1st public release is attached.

Until now, no other Siglent FW had this format.

Edit1: I tried to add the loading addresses for IDA. I'm not 100% sure they are correct but they do a pretty good job in disassembling.
If anyone knows a better way to automatically determine the correct Loading addresses of the STM32 blocks, etc please contact me.
« Last Edit: July 14, 2019, 12:26:09 pm by tv84 »
 

Offline wgoeo

  • Contributor
  • Posts: 10
  • Country: 00
Re: Siglent .ads firmware file format
« Reply #329 on: July 24, 2019, 10:26:00 pm »
For the SDS1000X-E, I summarized the replies so far in the Python 3 code below. You only need to recover the key in sds1000b.app. Without the correct key the .app will be corrupted but you can force extract and analyze it.

Code: [Select]
import sys
import codecs
import struct
 # Reply #25
import pyDesSiglent

 # Reply #186
key = codecs.decode('00000000000000000000000000000000', 'hex')
des = pyDesSiglent.triple_des(key)

 # Reply #74
def checksum(b):
return -sum(b) & 0xffffffff

 # Specify the .ads file as a command line argument
b = open(sys.argv[1], 'rb').read(-1)
 # Reply #235
b = des.decrypt(b[:0x70]) + b[0x70:]
 # Compare with parsing (Reply #99)
csum, size = struct.unpack('<LL', b[:8])
print('file size w/o header', hex(size), 'checksum', hex(csum), '=?', hex(checksum(b[4:])))
 # skip header
b = b[0x70:]
 # Reply #21, #186
b = des.decrypt(b[:0x2800]) \
+ b[0x2800:0x2E777] \
+ des.decrypt(b[0x2E777:0x2E777+0x1400]) \
+ b[0x2E777+0x1400:]
 # Reply #24 (modified)
b = bytearray(b[::-1])
a = 1
i = len(b)
j = 1
while j < i:
b[j] ^= 0xff
a += 1
j += a
i = len(b)
j = len(b) - len(b)//2
while j < i:
b[j] ^= 0xff
j += 1

 # Compare with parsing (Reply #99)
i = 0
while (i < len(b)):
csum, size = struct.unpack('<LL', b[i:i+8])
section = b[i+8]
payload = b[0x34:0x34+size]
print('section', section, 'size', hex(size), 'checksum', hex(csum), '=?', hex(checksum(payload)))
open('section%d.zip' % b[i+8], 'wb').write(payload)
i += 0x34 + size

Edit: to those who want a faster DES implementation I attached some code derived from mbedtls with just the necessary parts.
« Last Edit: July 27, 2019, 01:38:48 am by wgoeo »
 

Offline wgoeo

  • Contributor
  • Posts: 10
  • Country: 00
Re: Siglent .ads firmware file format
« Reply #330 on: July 29, 2019, 12:51:41 am »
If anyone knows a better way to automatically determine the correct Loading addresses of the STM32 blocks

These are only heuristics so not very reliable.
One way is to search for the pattern of the reset handler:
Code: [Select]
48__    ldr  r0, [pc, #__]
4780    blx  r0
48__    ldr  r0, [pc, #__]
4700    bx   r0
e7fe    b    .

Another is the pattern that sets the vector table offset register:
Code: [Select]
62498:       4817            ldr     r0, [pc, #92]   ; (0x624f8)
6249a:       4918            ldr     r1, [pc, #96]   ; (0x624fc)
6249c:       6008            str     r0, [r1, #0]
.
.
624f8:       08040000
624fc:       e000ed08
If it does not exist then 0x08000000 is assumed.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf