Skip to content

Instantly share code, notes, and snippets.

@knight-ryu12
Created October 8, 2019 03:00
Show Gist options
  • Save knight-ryu12/3c3b603713c11aa5d024c43e545f61b5 to your computer and use it in GitHub Desktop.
Save knight-ryu12/3c3b603713c11aa5d024c43e545f61b5 to your computer and use it in GitHub Desktop.
blep.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <iconv.h>
#define _3DSX_MAGIC 0x58534433 // '3DSX'
#define _SMDH_MAGIC 0x48444d53 // 'SMDH'
#define _IVFC_MAGIC 0x43465649 // 'IVFC'
typedef struct
{
uint32_t magic;
uint16_t headerSize, relocHdrSize;
uint32_t formatVer;
uint32_t flags;
// Sizes of the code, rodata and data segments +
// size of the BSS section (uninitialized latter half of the data segment)
uint32_t codeSegSize, rodataSegSize, dataSegSize, bssSize;
// offset and size of smdh
uint32_t smdhOffset, smdhSize;
// offset to filesystem
uint32_t fsOffset;
} _3DSX_Header;
typedef struct {
uint64_t logicalOfs;
uint64_t hashDataSize;
uint32_t blocksize; // in log2
uint32_t reserved;
} _LevelData;
typedef struct {
uint32_t magic1; // "IVFC"
uint32_t magic2; //0x10000
uint32_t masterhashSize;
_LevelData level1Data;
_LevelData level2Data;
_LevelData level3Data;
uint32_t reserved;
uint32_t optionalInfoSize;
} _IVFC_Header;
typedef struct {
// Each one is UTF-16 encoded.
uint8_t shortDesc[0x80];
uint8_t longDesc[0x100];
uint8_t Publisher[0x80];
} _APPT_Header;
typedef struct
{
// Applicaiton settings
uint8_t ageRating[0x10];
uint32_t regLockout;
uint8_t mmID[0xC]; //M(atch)M(aker)ID
uint32_t flag;
uint16_t vEula;
uint16_t reserved;
uint32_t OADF; // Optimal Animation Default Frame ???
uint32_t CECID; // Street pass ID
} _APPS_Header;
typedef struct {
uint8_t small[0x480]; // these encoding is word-order crap.
uint8_t large[0x1200];
} _ICON_Header;
typedef struct {
uint32_t magic;
uint16_t version, reserved1;
_APPT_Header titles[16]; // 0x200 bytes long
_APPS_Header applicationSetting;
uint64_t reserved2;
_ICON_Header iconGraphic;
} _SMDH_Header;
void print_help(char *filename) {
printf("Usage %s [file.3dsx]\n", filename);
}
int main(int argv, char *argc[]) {
FILE *f = NULL;
_3DSX_Header _3dsx_header;
_SMDH_Header _smdh_header;
iconv_t cd;
uint32_t buf;
uint8_t *utf8buf;
int mode = 0;
if (argv == 2) {
f = fopen(argc[1], "rb");
cd = iconv_open("utf-16","utf-8");
} else {
print_help(argc[0]);
return 1;
}
if (f == NULL) {
printf("ERROR: can't open file\n");
print_help(argc[0]);
return 2;
}
fread(&buf, 1, 4, f); // read 4 byte off
rewind(f);
printf("Detected magic %08X\n",buf);
if (buf == _3DSX_MAGIC) {
// 3DSX.
fread(&_3dsx_header,1,sizeof(_3DSX_Header),f);
printf("smdhOffset %d\n",_3dsx_header.smdhOffset);
fseek(f,_3dsx_header.smdhOffset,SEEK_SET);
fread(&_smdh_header,1,sizeof(_SMDH_Header),f);
rewind(f);
} else if (buf == _SMDH_MAGIC) {
mode = 1;
// SMDH.
} else if (buf == _IVFC_MAGIC) {
mode = 2;
// IVFC.
} else {
printf("This file isn't supported! bailing out.\n");
return 3;
}
printf("Mode %d\n",mode);
switch(mode) {
case 0:
utf8buf = malloc(1024);
uint32_t utf8bufsz = 1024;
uint32_t insz = 80;
iconv(cd,(char**)&_smdh_header.titles[0].shortDesc[0],&insz,(char**)&utf8buf,&utf8bufsz);
printf("Title %ls\n",_smdh_header.titles[0].longDesc);
free(utf8buf);
break;
}
//FILE *f = fopen("test.3dsx", "rb");
iconv_close(cd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment