Introduction

This page is dedicated to notes about reverse engineering the .sb3d and .sba file formats used by EA games for certain (usually mobile) offerings.

Some of the initial work was done by the user 'Chipicao' on the forums here. I'm not sure this is a continuation of that work, since that thread is fairly old and the format may have changed since.

The Simplest File

This is one of the simplest files I was able to find that follows this format. Presumably it contains some settings, since the filename is 'settings.sb'. If you would like, you can look at this file online here. This is what it looks like:

Structure

The basic structure of this file is actually quite simple. The first few numbers, 5342494E 04000000, specify the header which consists of the string SBIN and the version, 4. From there on out, the file loops with a fixed structure, where a char[4] identifier is read (such as STRU), followed by an int32 length, followed by an int32 checksum. This is then followed by length bytes of data before we hit the next iteration of the loop. Since this is one of the simplest files available in this format, it actually contains nothing in STRU, FIEL, or ENUM. This is what the various sections turn out to be (for this file, we can safely ignore the first three sections):

IdentifierLengthChecksum
1
STRU0-2128831035
2
FIEL0-2128831035
3
ENUM0-2128831035
4
OHDR16-1469493401
5
DATA2961524417315
6
CHDR72-425379895
7
CDAT142-556275866
OHDR

No clue what this is for, in this case contains four int32 values: 481, 33, 193, 1857

DATA

Presumably contains the actual data (more on this below)

CHDR

Contains pairs of values (e.g.: [0,0], [1,5], [7,9]) that are used to read CDAT - These are offsets of where the data is and the length of the data

CDAT

The data in here is strings that are present at the offsets and lengths given by CHDR

Unraveling Data

Since this is a settings file, it presumably contains settings. The names of these settings can be obtained from CHDR and CDAT:

  • imgui
  • streaming
  • general_user
  • user_date_of_birth
  • user_age_over_minimum
  • device_quality_checked
  • googleplay_login_canceled
  • usage_sharing_enabled

The actual values for these settings presumably live in DATA, but how DATA is read is unknown to us. If we read values in DATA as if they were shorts and integers, we can come up with something like this:

Here, I've highlighted the values I chose to read as shorts in red. The grey areas are highlighted because they produce strangely large values, as if they were checksums. This is what the data actually looks like (this is formatted to try and reveal a pattern, asterisks * added to integer values):

0	4
0	4
1	16
1	15	12*	1*
0	4
2	28
1	15	12*	1*
2	15	24*	2*
0	4
3	40
1	15	12*	1*
2	15	24*	2*
3	15	36*	3*
2	29	4	7	12*	-1645643482*	14*
		5	9	28*	1*		0*
3	39	4	7	12*	-1645643482*	14*
		5	9	28*	445697*		9
  				38	0		1
4	49	4	7	12*	-1645643482*	14*
		5	9	28*	445697*		9
  				38	0		-13055	7	9
  				48*	1*		0*
5	59	4	7	12*	-1645643482*	14*
		5	9	28*	445697*		9
  				38	0		-13055	7	9
  				48*	576769*		9
  				58	0		1	0
        

It's pretty clear that a pattern exists here. We can try and guess at what some of the numbers mean. If we ignore the first [0,4], we can imagine that the next [0,4] is an offset and length pair. Reading the next two shorts based on us gives us a header, [1,16], which might mean "read one value, in 16 bytes (including this header)". Those bytes contain what may be another header, [1, 15] (the first number here could be the index in the sequence), as well as the integer values, [12, 1]. This process can be repeated all the way until we read [36, 3].