GPC檔案格式分析

2021-04-12 22:30:32 字數 3846 閱讀 4363

作者按:罕徳岡曼先生重溫了《劍芒x曼史》這個遊戲,感慨萬千,老淚縱橫。想當年玩仙劍看到白布下的林月如也滅有哭過滴他,卻在本遊戲中香奈兒死的時候掉淚了……畢竟是前一天晚上才h過的亞……究竟本遊戲有滅有可以救香奈兒mm的方法呢?解出便知道了……

gpc的壓縮比並不高,因為它使用遊程碼的關係。每個包的第乙個位元組a控制大流程,它的每一位以8個位元組為單位指出非0的包。從高位開始,為0表示有8個全0位元組,為1表示要進一步觀察。為0時,簡單填充8個位元組即可;當為1時,下乙個位元組b指出本包中8個位元組是否為0。位元組b從高位開始,為0表示乙個0位元組,為1表示從流中讀乙個作為目標位元組。以此類推。

在解完一行後,要對解開的位元組進行異或的解密。具體解密過程請見**。

調色盤是2個位元組表示乙個顏色(相當粗略啊^^)

另外要注意的是gpc有隔行掃瞄方式,在第10h位元組指出共有幾次掃瞄。如只有1次,就直接從第0行到最後一行。如有2次,則是0,2,4,6...n,1,3,5,...n-1這樣的組織。以次類推。

下面給出gpc轉bmp的**,在vs2003上編譯通過。使用方法是gpc2bmp [檔名],檔名表示要轉化的gpc檔案,可包含萬用字元。預設為*.gpc。

// gpc2bmp.cpp : 定義控制台應用程式的入口點。

//#include "stdafx.h"

#include "windows.h"

#include "io.h"

#define gpc_eof  -1

struct gpc_buf ;

int gpc_next_byte(struct gpc_buf* data);

int gpc_next_word(struct gpc_buf* data);

void gpc_seek(struct gpc_buf* data, int offset);

bool gpc_load(struct gpc_buf* data, const char * filename);

void gpc_free(struct gpc_buf* data);

int gpc_next_byte(struct gpc_buf* data)

return *data->buf++;

}int gpc_next_word(struct gpc_buf* data)

bool gpc_load(struct gpc_buf* data, const char * filename)

void gpc_free(struct gpc_buf* data)

void gpc_seek(struct gpc_buf* data, int offset)

void gpc2bmp(struct gpc_buf* data, const char* target_file)

unsigned char *bits_buffer = (unsigned char *)malloc(bpl * height);

gpc_seek(data, image_offset + 0x10);

unsigned char decode_buf[1024];

int line_words = (bpl + 1) / 2;

unsigned char *next_line_pos = decode_buf + line_words * 2 + 1;

unsigned char *p_target = decode_buf;

unsigned char *disp_buf = decode_buf + 0x180;

memset( disp_buf, 0, line_words * 2 );

memset( bits_buffer, 0, bpl * height );

for ( int s = 0; s < scans; ++ s ) else

}} else }}

}p_target = p;

// post_decode_1

int ch = decode_buf[0];

if ( ch != 0 )

start++;

p = start;}}

// post decode 2

unsigned char *src = decode_buf + 1;

unsigned char *dest = disp_buf;

for ( int j = 0; j < line_words * 2; ++j ) ;

// post decode 3

int size = (int)(p_target - next_line_pos);

memcpy( decode_buf, next_line_pos, p_target - next_line_pos );

p_target = decode_buf + (p_target - next_line_pos);

src = disp_buf;

// 4 planes -> b4b4

// a0 a1 a2 a3 a4 a5 a6 a7

// b0 b1 b2 b3 b4 b5 b6 b7

// c0 c1 c2 c3 c4 c5 c6 c7

// d0 d1 d2 d3 d4 d5 d6 d7

// ==>

// a0b0c0d0 a1b1c1d1 ; a2b2c2d2 a3b3c3d3 ; a4b4c4d4 a5b5c5d5 ; a6b6c6d6 a7b7c7d7

unsigned char bits;

for ( int j = 0; j < 4; ++j )

}i += scans;}}

bitmapfileheader bfh;

bitmapinfoheader bmi;

memset(&bfh, 0, sizeof(bitmapfileheader));

bfh.bftype = 'mb';

bfh.bfsize = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader);

bfh.bfoffbits = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader) + 64;

memset(&bmi, 0, sizeof(bitmapinfoheader));

bmi.bisize = sizeof(bitmapinfoheader);

bmi.bisizeimage = bpl * height;

bmi.biwidth = width;

bmi.biheight = height;

bmi.biplanes = 1;

bmi.bibitcount = 4;

bmi.biclrused = 16;

bmi.biclrimportant = 16;

file *fp = fopen(target_file, "wb");

fwrite(&bfh, 1, sizeof bfh, fp);

fwrite(&bmi, 1, sizeof bmi, fp);

fwrite(palette, 4, 16, fp);

fwrite(bits_buffer, 1, bpl * height, fp);

fclose(fp);

free(bits_buffer);

}int _tmain(int argc, _tchar* argv)

if ( argc > 2 )

struct _finddata_t t;

long handle;

if ((handle = (long)_findfirst(input_files, &t)) != -1)

while(_findnext(handle, &t) != -1);

}return 0;

}

檔案格式分析

檔案格式實質上是資訊的一種的編碼方式,在windows中,採用副檔名來區分不同的檔案格式。文字格式 txt doc docx 音訊格式 txt arsii碼的方式存在 doc 以二進位制格式儲存 docx 作為乙個zip壓縮格式存在,是doc結合xml的一種格式,由於是分塊儲存,相比與doc檔案完整...

lucene檔案格式分析

segment 每個segment代表lucene乙個完整的索引段。通常乙個索引中包含了多個segment。每個segment都有統一的字首,字首名由document的數量轉成36進製後,在前面加 而構成的。通常乙個完整索引中,有且只有乙個沒有字尾名的segment檔案,它記錄了當前索引中所有的se...

FLV檔案格式分析

flv header 一般比較簡單,包括檔案型別之類的全域性資訊,如圖 檔案型別 3bytes 總是flv 0x46 0x4c 0x56 否則.版本1byte 一般是0x01,表示flv version 1 流資訊1byte header長度 4bytes 整個檔案頭的長度,一般是9 3 1 1 4...