Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // AVBuster.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <cstdlib>
- #include <cstring>
- #include "zlib.h"
- #pragma pack(push, 1)
- // type 0x8181 = avb header
- typedef struct _AVB_HEADER
- {
- short type;
- short unk;
- } AVB_HEADER, *PAVB_HEADER;
- // type 1 = null-terminated string
- // type 2 = unknown, 2 bytes
- typedef struct _AVB_UNK_HEADER_2
- {
- short unk;
- } AVB_UNK_HEADER_2, *PAVB_UNK_HEADER_2;
- // type 6 = zlib compressed bmp
- typedef struct _AVB_ZLIB_BMP_HEADER
- {
- BITMAPINFOHEADER header;
- int len_decomp;
- int len_comp;
- } AVB_ZLIB_BMP_HEADER, *PAVB_ZLIB_BMP_HEADER;
- typedef struct _AVB_ZLIB_GESTURE_HEADER
- {
- short colors_magic;
- short colors_length;
- short num_colors;
- } AVB_ZLIB_GESTURE_HEADER, *PAVB_ZLIB_GESTURE_HEADER;
- // type 8 = unknown, 2 bytes
- typedef struct _AVB_UNK_HEADER_8
- {
- short unk;
- } AVB_UNK_HEADER_8, *PAVB_UNK_HEADER_8;
- // gesture list entry
- typedef struct _AVB_GESTURE_ENTRY
- {
- int gestureOffset; // 4
- int unknownOffset; // 8
- int poseOffset; // 12
- short unk1; // 14
- int facePosition; // 16
- short unk2; // 20
- short unk3; // 22
- short unk4; // 24
- char unk5; // 25
- } AVB_GESTURE_ENTRY, *PAVB_GESTURE_ENTRY;
- // type 0xA = unknown list
- typedef struct _AVB_UNK_HEADER_A
- {
- short count;
- } AVB_UNK_HEADER_A, *PAVB_UNK_HEADER_A;
- typedef struct _AVB_UNK_HEADER_A_ENTRY
- {
- AVB_GESTURE_ENTRY ent;
- char unk[8];
- } AVB_UNK_HEADER_A_ENTRY, *PAVB_UNK_HEADER_A_ENTRY;
- // type 0xB/0xC = gesture list
- typedef struct _AVB_GESTURE_LIST
- {
- short count;
- } AVB_GESTURE_LIST, *PAVB_GESTURE_LIST;
- // type 0x100 = unknown
- typedef struct _AVB_UNK_HEADER_100
- {
- short size;
- short unk1;
- short unk2;
- short unk3;
- } AVB_UNK_HEADER_100, *PAVB_UNK_HEADER_100;
- // type 0x103 & 0x104 = string entry
- typedef struct _AVB_STRING_HEADER
- {
- short size;
- } AVB_STRING_HEADER, *PAVB_STRING_HEADER;
- // type 0x106 = url protection header
- typedef struct _AVB_PROTECT_HEADER
- {
- short size;
- bool download_protected;
- } AVB_PROTECT_HEADER, *PAVB_PROTECT_HEADER;
- #pragma pack(pop)
- int _tmain(int argc, _TCHAR* argv[])
- {
- printf("AVBuster, extractor for MS Comic Chat AVB and BGB files\nnote: official MS chars are unsupported due to them using a different compression method\n");
- if(argc <= 1)
- {
- printf("usage: avbuster.exe character.avb\n");
- return 0;
- }
- FILE* fp;
- if(_wfopen_s(&fp, argv[1], L"rb") != 0)
- {
- printf("failed to open file!\n");
- return 0;
- }
- fseek(fp, 0L, SEEK_SET);
- bool headerRead = false;
- AVB_HEADER header;
- bool nameRead = false;
- char name[256];
- bool header8Read = false;
- AVB_UNK_HEADER_8 header8;
- bool header2Read = false;
- AVB_UNK_HEADER_2 header2;
- bool header100Read = false;
- AVB_UNK_HEADER_100 header100;
- bool header103Read = false;
- AVB_STRING_HEADER header103;
- char author[256];
- bool header104Read = false;
- AVB_STRING_HEADER header104;
- char download[256];
- bool header105Read = false;
- AVB_STRING_HEADER header105;
- char download2[256];
- bool header106Read = false;
- AVB_PROTECT_HEADER header106;
- bool header107Read = false;
- AVB_STRING_HEADER header107;
- bool hasGestures = false;
- AVB_UNK_HEADER_A headerA;
- AVB_UNK_HEADER_A_ENTRY headerAEntries[256];
- bool headerCisB = false;
- AVB_GESTURE_LIST headerC;
- AVB_GESTURE_ENTRY headerPoses[256];
- AVB_ZLIB_GESTURE_HEADER gestureHdr[256];
- memset(&gestureHdr, 0, sizeof(AVB_ZLIB_GESTURE_HEADER) * 256);
- AVB_ZLIB_BMP_HEADER gestureBmpHdr[256];
- AVB_ZLIB_BMP_HEADER poseBmp[256];
- int zlibOffset = 0;
- memset(&header, 0, sizeof(AVB_HEADER));
- int current = 0;
- int ni = 0;
- while(true)
- {
- if(current > 0 && header.type == 0)
- {
- printf("invalid file?\n");
- return 0;
- }
- unsigned short type;
- fread(&type, sizeof(short), 1, fp);
- printf("Type %x\n", type);
- if(type == 6)
- break;
- switch(type)
- {
- case 0x8181:
- fread(&header, sizeof(AVB_HEADER), 1, fp);
- if(header.type != 1)
- printf("** new header type 0x%x\n", header.type);
- if(header.unk != 2)
- printf("** new header unk 0x%x\n", header.unk);
- if(header.type == 2)
- {
- printf("** unsupported type 2 (OEM/Microsoft?)\n");
- return 0;
- }
- headerRead = true;
- break;
- case 1:
- while(true)
- {
- fread(&name[ni], 1, 1, fp);
- if(name[ni] == 0) break;
- ni++;
- }
- nameRead = true;
- ni = 0;
- break;
- case 2:
- fread(&header2, sizeof(AVB_UNK_HEADER_2), 1, fp);
- if(header2.unk != 5)
- {
- printf("** new header2: unk 0x%x\n", header2.unk);
- }
- header2 = header2;
- header2Read = true;
- break;
- case 8:
- fread(&header8, sizeof(AVB_UNK_HEADER_8), 1, fp);
- if(header8.unk != 1)
- {
- printf("** new header8: unk 0x%x\n", header8.unk);
- }
- header8 = header8;
- header8Read = true;
- break;
- case 0xA:
- fread(&headerA, sizeof(AVB_UNK_HEADER_A), 1, fp);
- for(int i = 0; i < headerA.count; i++)
- fread(&headerAEntries[i], sizeof(AVB_UNK_HEADER_A_ENTRY), 1, fp);
- break;
- case 0xB:
- headerCisB = true;
- case 0xC:
- hasGestures = true;
- fread(&headerC, sizeof(AVB_GESTURE_LIST), 1, fp);
- for(int i = 0; i < headerC.count; i++)
- {
- fread(&headerPoses[i], sizeof(AVB_GESTURE_ENTRY), 1, fp);
- }
- break;
- case 0x100:
- fread(&header100, sizeof(AVB_UNK_HEADER_100), 1, fp);
- if(header100.size != 6)
- printf("** new header100 size: 0x%x\n", header100.size);
- if(header100.unk1 != 0x60)
- printf("** new header100 unk1: 0x%x\n", header100.unk1);
- if(header100.unk2 != 0)
- printf("** new header100 unk2: 0x%x\n", header100.unk2);
- if(header100.unk3 != 0x201)
- printf("** new header100 unk3: 0x%x\n", header100.unk3);
- header100 = header100;
- header100Read = true;
- break;
- case 0x103:
- fread(&header103, sizeof(AVB_STRING_HEADER), 1, fp);
- fread(&author, header103.size, 1, fp);
- header103Read = true;
- break;
- case 0x104:
- fread(&header104, sizeof(AVB_STRING_HEADER), 1, fp);
- fread(&download, header104.size, 1, fp);
- header104Read = true;
- break;
- case 0x105:
- fread(&header105, sizeof(AVB_STRING_HEADER), 1, fp);
- fread(&download2, header105.size, 1, fp);
- header105Read = true;
- break;
- case 0x106:
- fread(&header106, sizeof(AVB_PROTECT_HEADER), 1, fp);
- if(header106.size != 1)
- printf("** new header106 size: 0x%x\n", header106.size);
- if(header106.download_protected != 1)
- printf("** new header106 download_protected: 0x%x\n", header106.download_protected);
- header106 = header106;
- header106Read = true;
- break;
- case 0x107:
- fread(&header104, sizeof(AVB_STRING_HEADER), 1, fp);
- fread(&zlibOffset, 4, 1, fp);
- header107Read = true;
- break;
- case 0x81:
- if(!headerRead)
- {
- printf("** older header detected, use avbcvt / bmpbgb to convert to 2.5 first\n");
- return 0;
- }
- default:
- printf("** new header # 0x%x\n", type);
- if(type >= 0x100)
- {
- unsigned short size = 0;
- fread(&size, 2, 1, fp);
- printf("** header has size field, skipping 0x%x bytes...\n", size);
- fseek(fp, size, SEEK_CUR);
- }
- break;
- }
- current++;
- }
- if(nameRead)
- printf("name: %s\n", name);
- if(header103Read)
- printf("author: %s\n", author);
- if(header104Read)
- printf("download: %s\n", download);
- if(header105Read)
- printf("download2: %s\n", download2);
- if(headerRead)
- printf("header type: 0x%x unk: 0x%x\n", header.type, header.unk);
- if(header2Read)
- printf("header2 unk: 0x%x\n", header2.unk);
- if(header8Read)
- printf("header8 unk: 0x%x\n", header8.unk);
- if(header100Read)
- printf("header100 size: 0x%x unk1: 0x%x unk2: 0x%x unk3: 0x%x\n", header100.size, header100.unk1, header100.unk2, header100.unk3);
- if(header106Read)
- printf("header106 size: 0x%x download_protected: 0x%x\n", header106.size, header106.download_protected);
- if(header107Read)
- printf("header107 zlib offset: 0x%x\n", zlibOffset);
- if(hasGestures)
- {
- printf("gesture count: 0x%x\n", headerC.count);
- for(int i = 0; i < headerC.count; i++)
- {
- printf("== Gesture %d\n", i);
- printf(" gestureOffset: 0x%x unknownOffset: 0x%x poseOffset: 0x%x\n unk1: 0x%x facePosition: 0x%x unk2: 0x%x\n unk3: 0x%x unk4: 0x%x unk5: 0x%x\n", headerPoses[i].gestureOffset, headerPoses[i].unknownOffset, headerPoses[i].poseOffset, headerPoses[i].unk1, headerPoses[i].facePosition, headerPoses[i].unk2, headerPoses[i].unk3, headerPoses[i].unk4, headerPoses[i].unk5);
- }
- }
- unsigned char check = 0;
- unsigned char chk2 = 0;
- if(!hasGestures)
- {
- AVB_ZLIB_GESTURE_HEADER hdr;
- AVB_ZLIB_BMP_HEADER bmpHdr;
- fread(&hdr, sizeof(AVB_ZLIB_GESTURE_HEADER), 1, fp);
- void* colors = 0;
- if(hdr.num_colors > 0)
- {
- colors = malloc(hdr.num_colors * 4);
- memset(colors, 0, hdr.num_colors * 4);
- for(int y = 0; y < hdr.num_colors; y++)
- fread((BYTE*)colors + (y * 4), 3, 1, fp);
- }
- fread(&bmpHdr, sizeof(AVB_ZLIB_BMP_HEADER), 1, fp);
- void* compressed = malloc(bmpHdr.len_comp);
- fread(compressed, bmpHdr.len_comp, 1, fp);
- // create bmp and decompress
- BITMAPFILEHEADER bmp;
- memset(&bmp, 0, sizeof(BITMAPFILEHEADER));
- bmp.bfType = 0x4D42;
- bmp.bfOffBits = 0x36 + (hdr.num_colors * 4);
- bmp.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (hdr.num_colors * 4) + bmpHdr.len_decomp;
- void* dest = malloc(bmpHdr.len_decomp);
- int size = bmpHdr.len_decomp;
- int ret = uncompress((Bytef*)dest, (uLongf*)&size, (Bytef*)compressed, bmpHdr.len_comp);
- if(ret != 0) return 0;
- TCHAR fname[256];
- swprintf(fname, L"%ws_data\\", argv[1]);
- _tmkdir(fname);
- swprintf(fname, L"%ws_data\\bg.bmp", argv[1]);
- FILE* file = _wfopen(fname, L"wb");
- fwrite(&bmp, sizeof(BITMAPFILEHEADER), 1, file);
- fwrite(&bmpHdr.header, sizeof(BITMAPINFOHEADER), 1, file);
- if(colors)
- fwrite(colors, hdr.num_colors * 4, 1, file);
- fwrite(dest, size, 1, file);
- fclose(file);
- if(colors) free(colors);
- dest = dest;
- }
- else
- for(int i = 0; i < headerC.count; i++)
- {
- void* colors = 0;
- //fseek(fp, headerAEntries[i].ent.gestureOffset + zlibOffset, SEEK_SET);
- fseek(fp, headerPoses[i].gestureOffset + zlibOffset, SEEK_SET);
- if(!headerCisB)
- {
- fread(&gestureHdr[i], sizeof(AVB_ZLIB_GESTURE_HEADER), 1, fp);
- if(gestureHdr[i].num_colors > 0)
- {
- colors = malloc(gestureHdr[i].num_colors * 4);
- memset(colors, 0, gestureHdr[i].num_colors * 4);
- for(int y = 0; y < gestureHdr[i].num_colors; y++)
- fread(((BYTE*)colors + (y * 4)), 3, 1, fp);
- }
- }
- fread(&gestureBmpHdr[i], sizeof(AVB_ZLIB_BMP_HEADER), 1, fp);
- fread(&check, 1, 1, fp);
- fread(&chk2, 1, 1, fp);
- fseek(fp, -2, SEEK_CUR);
- if(check != 0x78 || chk2 != 0xDA)
- {
- /*printf("** scanning for zlib data...\n");
- int offset = 0;
- while(true)
- {
- offset++;
- fread(&check, 1, 1, fp);
- if(check != 0x78) continue;
- fread(&chk2, 1, 1, fp);
- if(chk2 != 0xDA)
- {
- fseek(fp, -1, SEEK_CUR);
- continue;
- }
- break;
- }
- offset -= 1;
- printf("found at %x\n", offset);
- fseek(fp, headerPoses[i].gestureOffset + zlibOffset + offset, SEEK_SET);
- fread(&gestureHdr[i], sizeof(AVB_ZLIB_GESTURE_HEADER), 1, fp);
- if(gestureHdr[i].num_colors > 0)
- {
- if(colors) free(colors);
- colors = malloc(gestureHdr[i].num_colors * 4);
- for(int y = 0; y < gestureHdr[i].num_colors; y++)
- fread(&colors + (y * 4), 3, 1, fp);
- }
- fread(&gestureBmpHdr[i], sizeof(AVB_ZLIB_BMP_HEADER), 1, fp);
- //return 0;*/
- printf("** zlib data not found and searching is deprecated, exiting\n");
- return 0;
- }
- void* compressed = malloc(gestureBmpHdr[i].len_comp);
- fread(compressed, gestureBmpHdr[i].len_comp, 1, fp);
- // create bmp and decompress
- BITMAPFILEHEADER bmp;
- memset(&bmp, 0, sizeof(BITMAPFILEHEADER));
- bmp.bfType = 0x4D42;
- bmp.bfOffBits = 36 + (gestureHdr[i].num_colors * 4);
- bmp.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (gestureHdr[i].num_colors * 4) + gestureBmpHdr[i].len_decomp;
- void* dest = malloc(gestureBmpHdr[i].len_decomp);
- int size = gestureBmpHdr[i].len_decomp;
- int ret = uncompress((Bytef*)dest, (uLongf*)&size, (Bytef*)compressed, gestureBmpHdr[i].len_comp);
- if(ret != 0) continue;
- TCHAR fname[256];
- swprintf(fname, L"%ws_data\\", argv[1]);
- _tmkdir(fname);
- swprintf(fname, L"%ws_data\\%d.bmp", argv[1], i);
- FILE* file = _wfopen(fname, L"wb");
- fwrite(&bmp, sizeof(BITMAPFILEHEADER), 1, file);
- fwrite(&gestureBmpHdr[i].header, sizeof(BITMAPINFOHEADER), 1, file);
- if(colors)
- fwrite(colors, gestureHdr[i].num_colors * 4, 1, file);
- fwrite(dest, size, 1, file);
- fclose(file);
- if(colors) free(colors);
- dest = dest;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement