this code reads the ds2k .GEL files, and dumps the DXE streams, and individual blocks - still no clue on the bytes behind the version/hw though ...
currently adding that code to the IDAPro rigol_ldr from rigol homebrew - results are promising, more than 8000 subs autodiscovered by IDA ;-) so something is right here ...
compile with:
gcc -funsigned-bitfields reader.c -o reader
//////////////////////////////////////////////////////////////
// RIGOL DS2XXX .GEL firmware reader
// (c) cybernet 2013
//////////////////////////////////////////////////////////////
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef unsigned char uchar;
typedef unsigned short int uint16;
typedef unsigned long int uint32;
#define BFLAG_FINAL 0x8000
#define BFLAG_FIRST 0x4000
#define BFLAG_INDIRECT 0x2000
#define BFLAG_IGNORE 0x1000
#define BFLAG_INIT 0x0800
#define BFLAG_CALLBACK 0x0400
#define BFLAG_QUICKBOOT 0x0200
#define BFLAG_FILL 0x0100
#define BFLAG_AUX 0x0020
#define BFLAG_SAVE 0x0010
struct gel_hdr {
uchar hw[16];
uchar ver[16];
uchar u1[1];
uint32 recs;
};
struct bfn_hdr {
uint16 flg;
uchar chk;
uchar sgn;
uint32 taddr;
uint32 count;
uint32 arg;
};
uchar is_flag(uint32 flag, uchar *buff, uint32 offset)
{
struct bfn_hdr *h;
// overlay
h=(struct bfn_hdr*)(buff+offset);
return((h->flg & flag) == flag);
}
void print_bfn_hdr(uchar *buff, uint32 offset)
{
int i;
unsigned char *c;
struct bfn_hdr *h;
// overlay
h=(struct bfn_hdr*)(buff+offset);
//for(i=0;i<16;i++)
// printf("%02X ",(uchar)*(buff+i));
// printf("\n");
printf("\tHeader Sign: %02X - Checksum: %02X\n", h->sgn, h->chk);
printf("\tFlags: %04X [", h->flg);
if ((h->flg & BFLAG_FINAL) == BFLAG_FINAL) printf(" FINAL ");
if ((h->flg & BFLAG_FIRST) == BFLAG_FIRST) printf(" FIRST ");
if ((h->flg & BFLAG_INDIRECT) == BFLAG_INDIRECT) printf(" INDIRECT ");
if ((h->flg & BFLAG_IGNORE) == BFLAG_IGNORE) printf(" IGNORE ");
if ((h->flg & BFLAG_INIT) == BFLAG_INIT) printf(" INIT ");
if ((h->flg & BFLAG_CALLBACK) == BFLAG_FIRST) printf(" CALLBACK ");
if ((h->flg & BFLAG_QUICKBOOT) == BFLAG_QUICKBOOT) printf(" QUICKBOOT ");
if ((h->flg & BFLAG_FILL) == BFLAG_FILL) printf(" FILL ");
if ((h->flg & BFLAG_AUX) == BFLAG_AUX) printf(" AUX ");
if ((h->flg & BFLAG_SAVE) == BFLAG_SAVE) printf(" SAVE ");
printf("]\n");
printf("\tTAddr: %08X - Count: %08X - Arg: %08X\n", (uint32)h->taddr, (uint32)h->count, (uint32)h->arg);
}
void main(int argc, char *argv)
{
uint32 len;
uint32 buff_offset=0;
uint32 next_dxe=0;
uint32 block_offset=0;
uint32 dxe_count=0;
uint32 block_count=0;
uchar *buff;
FILE *f;
struct gel_hdr *hdr;
struct bfn_hdr *bfn;
f = fopen("DS2000_2.GEL", "rb");
if (!f)
{
fprintf(stderr, "Unable to open file\n");
return;
}
// get size
fseek(f, 0, SEEK_END);
len=ftell(f);
fseek(f, 0, SEEK_SET);
// alloc buff
buff=(char*)malloc(len+1);
if (!buff)
{
fprintf(stderr, "Unable to allocate buffer\n");
return;
}
fread(buff, len, 1, f);
hdr=(struct gel_hdr*)buff;
printf("hw: %s\n", hdr->hw);
printf("version: %s\n", hdr->ver);
printf("recs: %d\n",hdr->recs);
buff_offset=32+8+(hdr->recs*28);
while (!is_flag(BFLAG_FINAL, buff, buff_offset))
{
printf("\n====================\n");
printf(" DXE #%d at %08X\n", dxe_count, buff_offset);
printf("====================\n");
block_offset=buff_offset;
while (1)
{
printf("\n BLOCK #%d at %08X\n", block_count, buff_offset);
print_bfn_hdr(buff, buff_offset);
bfn=(struct bfn_hdr*)(buff+buff_offset);
// evaluate flags
if (is_flag(BFLAG_FIRST, buff, buff_offset))
{
if (!next_dxe)
next_dxe=bfn->arg+sizeof(struct bfn_hdr);
}
if (is_flag(BFLAG_FINAL, buff, buff_offset) ||
is_flag(BFLAG_INIT, buff, buff_offset)
)
break;
if (!is_flag(BFLAG_FILL, buff, buff_offset))
{
buff_offset+=bfn->count;
}
buff_offset+=sizeof(struct bfn_hdr);
block_count++;
}
buff_offset=next_dxe+block_offset;
next_dxe=0;
dxe_count++;
block_count=0;
}
fclose(f);
free(buff);
}