Skip to content

Latest commit

 

History

History
247 lines (186 loc) · 6.7 KB

File metadata and controls

247 lines (186 loc) · 6.7 KB

Module Structure

In a dictionary, resources need a different structure than regular blocks, so modules are used instead. Modules have more metadata than a block and can also use multiple blocks for each module-specific purpose.

Each module has three blocks: a name block, a data block, and a directory block.

Name blocks store the names of each resource inside that module. Modules themselves can have names as well. The module's own name is stored in block 2 at a specific offset that's specified in the module table.

Data blocks store the actual resource data, like script source code, script documentation, constants, globals, etc. Each resource type gets its own data block.

Directory blocks contain information about the actual resources that are stored inside of a module. They contain two tables and a header. The header contains the module's ID, and how many type slots and resource slots are allocated.

The first table in a directory block is the type table, which contains a list of resource types and how many resources have that type inside the module. Since each type has its own set of resource IDs, you first have to find the resource type that you want to access. From there, you can see how many resources are allocated for that specific type, as well as where the slots are on the resource table. One record in the type table can have multiple resources associated with it, but a resource can only have one type.

The second table is the resource table. It contains information that's unique to a specific resource like the resource's name block, data block, and resource ID.

The header comes first in a directory block, then the type table, then the resource table. The type table should always be at offset 14 (0xE) in the block. To calculate the resource table offset, add the used type slot count with the unused type slot count, multiply by 16, then add 14.

Pseudocode example:

uint ResourceTableOffset = ((UsedTypes + UnusedTypes) * 16) + 14;

Module Table Header

The module table header is 9 bytes in size. Offset is from the beginning of the module table block. The unknown field in this instance might be the block number for the module names block but I haven't found any evidence to support that theory.

Offset (hex) Purpose Data type
00 Used Module Count UInt16
01
02 Unused Module Count UInt16
03
04 Unknown
05
06
07

Module Table Records

Module table records are 16 (0x10) bytes in size. Offset is from the beginning of the record. The name offset and name length refer to block 2, which is for the name of the module itself.

Offset (hex) Purpose Data type
00 Module Type UInt16
01
02 Module ID UInt32
03
04
05
06 Directory Block Number UInt32
07
08
09
0A Name Offset UInt32
0B
0C
0D
0E Name Length UInt16
0F

Module Directory Header

The module directory block header is 14 (0xE) bytes in size. Offset is from the beginning of the directory block.

Offset (hex) Purpose Data type
00 Module Type UInt16
01
02 Module ID UInt32
03
04
05
06 Used Type Count UInt16
07
08 Unused Type Count UInt16
09
0A Allocated Resource Count UInt16
0B
0C Unallocated Resource Count UInt16
0D

Module Directory Type Table Records

Module directory type table records are 16 (0x10) bytes in size. Offset is from the beginning of the record. "First Resource Slot" is the index of the first record in the resource table that's associated with this type.

Offset (hex) Purpose Data type
00 Resource Type UInt16
01
02 Name Block Number UInt32
03
04
05
06 Data Block Number UInt32
07
08
09
0A First Resource Slot UInt16
0B
0C Used Resource Count UInt16
0D
0E Unused Resource Count UInt16
0F

Module Directory Resource Table Records

Module directory resource table records are 16 (0x10) bytes in length. Offset is from the beginning of the record. The version field's purpose is unknown, but that's what it's called by Dex Utils. Name/data length and name/data offset refer to the name/data block that's defined in the types table (see above section).

Offset (hex) Purpose Data type
00 Resource ID UInt16
01
02 Version Byte
03 Name Length Byte
04 Name Offset UInt32
05
06
07
08 Data Offset UInt32
09
0A
0B
0C Data Length UInt32
0D
0E
0F