Strings

Strings

[] Russificated Diablo 3 Login screen

Strings in Diablo 3 uses container that used by some other data (e.g, fonts .fnt). It is a struct

typedef struct { 	uint32_t magic;	//0xDEADBEEF uint32_t unk1;	//0x27, this is a string uint64_t free1; //0 uint32_t unk2; //sno of file uint32_t free2; //0 uint64_t free3; //0 uint64_t free4; //0 uint32_t unk3;	//0x28 uint32_t data_start;	//Start of raw Utf-8 strings - sizeof(STL_header) uint64_t free5; //0 } STL_header;

After that header there are some number of structs that describe each string:

typedef struct { 	uint32_t type;	//0 - normal, -1 - end of STL_desc uint32_t free1; //0 uint32_t start; //Start of string - 0x10 for type 0 or 0 for -1 uint32_t lenght; //Length of string (with 0x00 byte) for type 0 or 0 for type -1 } STL_record;

STL_rec combined into arrays of 5 strings:

typedef struct { 	STL_record data[5]; } STL_desc;

Name, Value, Addition1, Addition2, End Name and Value are always non-empty

Addition1 and Addition2 in most cases are empty (length = 1, only zero byte), but not always End in most cases have type -1 and length = start = 0, but in some places it seems to have type 0 and length = start = 0.

Simple C program that reads and displays strings: // STL.h #ifndef __STL_H__ #define __STL_H__ #include  typedef struct { 	uint32_t magic;	//0xDEADBEEF uint32_t unk1;	//0x27, version, maybe uint64_t free1; //0 uint32_t unk2; //Always different, possibly ID of STL file uint32_t free2; //0 uint64_t free3; //0 uint64_t free4; //0 uint32_t unk3;	//0x28 uint32_t data_start;	//Start of data - sizeof(STL_header) uint64_t free5; //0 } STL_header; /* 	Maybe STL_desc can contain variable number of string descriptions, but I only see STL_desc with 4 strings and one end. */ typedef struct { 	uint32_t type;	//0 - normal, -1 - end of STL_desc uint32_t free1; //0 uint32_t start; //Start of string - 0x10 for type 0 or 0 for -1 uint32_t lenght; //Length of string (with 0x00 byte) for type 0 or 0 for type -1 } STL_record; typedef struct { 	STL_record data[5]; } STL_desc; typedef struct { 	uint32_t start; uint32_t lenght; char *data; } STL_my; #endif	// __STL_H__ // STL.c #include   #include   #include   #include "STL.h"  STL_my *data[1024]; int count = 0; int main(int argc, char* argv[]) { 	FILE *f = fopen("Test.stl", "rb"); if(f) { 		STL_header *h = (STL_header *)malloc(sizeof(STL_header)); fseek(f, 0, SEEK_SET); fread(h, sizeof(STL_header), 1, f); if(h->magic != 0xDEADBEEF) { 			printf("Not an D3 file\n"); fclose(f); return -2; } 		if(h->unk1 != 0x27) { 			printf("Not an STL resource file\n"); fclose(f); return -3; } 		printf("Unk2 field = %d (0x%x)\n", h->unk2, h->unk2); h->unk2 = 1; // Let's the battle begin int i,j; STL_desc *d = (STL_desc *)malloc(sizeof(STL_desc));; for(i = sizeof(STL_header); i < (h->data_start + sizeof(STL_header)); i += sizeof(STL_desc)) { 			fseek(f, i, SEEK_SET); fread(d, sizeof(STL_desc), 1, f); for(j = 0; j < 5; j++) { 				if(d->data[j].type == 0xFFFFFFFF)	//End of STL_desc break; /*if(d->data[j].lenght == 1)	//Empty string continue;*/ data[count] = (STL_my *)malloc(sizeof(STL_my)); data[count]->data = (char *)malloc(d->data[j].lenght); fseek(f, d->data[j].start + 0x10, SEEK_SET); fread(data[count]->data, d->data[j].lenght, 1, f); data[count]->lenght = d->data[j].lenght; data[count]->start = 0; printf("%s\n", data[count]->data); count++; } 		}  		//free(d); fclose(f); // Now we have strings in array data[] // Generate output file f = fopen("Hero.stl", "wb"); fwrite(h, sizeof(STL_header), 1, f); int pos = h->data_start + sizeof(STL_header); // Write string description for(i = 0; i < count; i++) { 			j = i & 0x03; d->data[j].free1 = 0; d->data[j].lenght = data[i]->lenght; d->data[j].type = 0; d->data[j].start = pos - 0x10; pos += data[i]->lenght; // Align on 8-byte boundary // Original STL files uses this alignment, // but Diablo 3 doesn't check for it, so it 			// can be ignored (and save for us some bytes) //pos += (8 - (pos % 8)) % 8; if(j == 3) { 				// Write end of packet d->data[4].free1 = 0; d->data[4].lenght = 0; d->data[4].type = -1; d->data[4].start = 0; // Write packet to file fwrite(d, sizeof(STL_desc), 1, f); } 		}  		// Write strings for(i = 0; i < count; i++) { 			fwrite(data[i]->data, data[i]->lenght, 1, f); free(data[i]->data); free(data[i]); } 		free(h); free(d); fclose(f); } 	else { 		printf("Open file error!\n"); return -1; } 	return 0; } Qt Program that can edit STL files (with sources) Sourceforge.net