Ok, here is the script for unpacking chunks and bundles from toc+sb files.
Audio and video are stored in chunks, while textures, levels and cars geometry and other data are in bundles. There is no chunk filenames stored in .toc, only hashes, so extracted filenames will be like "1DBEAD526CD3C6A1652994ACAF4D3C76" - that's normal.
Bundles are unpacked with normal names like "Win32\_c4\ui\flow\graph\frontend\ferootgraph_resourcebundle". Any help on further bundle unpacking is welcomed.
Repacking using quickbms -r should work, but not throughly tested. (with standart repacking limitations like <= size of repacking file)
Use this script on original .toc file (not decrypted with bf3decrypt or any other tool).
Usually script finishes with error "incomplete input file number -1, can't read 1 bytes." - this is normal.
Code: Select all
Open FDDE SB 1
Get DICE_HDR long
If DICE_HDR == 0x00CED100
Get TOC_SIZE asize
Math TOC_SIZE -= 0x22C
CallFunction DecryptTOC
#Log "_decrypted.toc" 0 TOC_SIZE MEMORY_FILE
CallFunction TOCParser
EndIf
##############################
StartFunction DecryptTOC
FileXOR 0x7B
Log MEMORY_FILE2 0x128 0x101
FileXOR ""
Log MEMORY_FILE 0x22C TOC_SIZE
For I = 0 < TOC_SIZE
Math J = I
Math J %= 0x101
GetVarChr KEY MEMORY_FILE2 J byte
GetVarChr B MEMORY_FILE I byte
Math B ^= KEY
PutVarChr MEMORY_FILE I B byte
Next I
EndFunction
##############################
StartFunction GetVLISize
Set SHIFT byte 0
Set ENTRYSIZE long 0
Do
Get B byte MEMORY_FILE
Math MSB = B
Math B & 0x7F
Math B < SHIFT
Math SHIFT + 7
Math ENTRYSIZE | B
Math MSB > 7
While MSB == 1
EndFunction
##############################
StartFunction TOCParser
Math FFLAG = 0
Do
Get TYPECODE byte MEMORY_FILE
Math FLAGS = TYPECODE
Math TYPECODE & 0x1F
Math FLAGS > 5
#Print "T:%TYPECODE% \t F:%FLAGS%"
If FLAGS >= 4
Set KEY string ""
ElseIf TYPECODE == 0
Set KEY string ""
Else
Get KEY string MEMORY_FILE
EndIf
If TYPECODE == 0 # Terminator
Print "End of current LIST or ENTRY"
ElseIf TYPECODE == 1 # List
CallFunction GetVLISize 1
Print "Start of LIST '%KEY%' with size = %ENTRYSIZE%"
CallFunction TOCParser
ElseIf TYPECODE == 2 # Entry
CallFunction GetVLISize 1
Print "Start of ENTRY '%KEY%' with size = %ENTRYSIZE%"
CallFunction TOCParser
ElseIf TYPECODE == 6 # Bool
Get VALUE byte MEMORY_FILE
Print " %KEY% = %VALUE%"
ElseIf TYPECODE == 7 # String
Get STRLEN byte MEMORY_FILE
GetDString VALUE STRLEN MEMORY_FILE
Print " %KEY% = %VALUE%"
ElseIf TYPECODE == 8 # Int32
Get VALUE long MEMORY_FILE
Print " %KEY% = %VALUE%"
ElseIf TYPECODE == 9 # Int64
Get VALUE longlong MEMORY_FILE
Print " %KEY% = %VALUE%"
ElseIf TYPECODE == 15 # UUID
Endian BIG
Get HASH1 long MEMORY_FILE
Get HASH2 long MEMORY_FILE
Get HASH3 long MEMORY_FILE
Get HASH4 long MEMORY_FILE
Endian LITTLE
String VALUE p= "%08X%08X%08X%08X" HASH1 HASH2 HASH3 HASH4
Print " %KEY% = %VALUE%"
Else
Print "Unknown TYPECODE = %TYPECODE%"
CleanExit
EndIf
If KEY == "id"
Set FNAME string VALUE
Math FFLAG | 1
ElseIf KEY == "offset"
Math FOFFSET = VALUE
Math FFLAG | 2
ElseIf KEY == "size"
Math FSIZE = VALUE
Math FFLAG | 4
EndIf
If FFLAG == 7
#Print "%FNAME% %FOFFSET% %FSIZE%"
Log FNAME FOFFSET FSIZE 1
Math FFLAG = 0
EndIf
While TYPECODE != 0
EndFunction
##############################