Jianmun Roman History 2 unique picture program
MCG file
File Head 40h --------------------------- 10h Palette Offset1ch Width20h Height --------------- ----------------
Palette 400h ------------------------------------------- ------------
Pixel Data uses a relatively special compression method, at least I don't know, huh, huh, the specific decoding function looks 0x422990
use tools
IDA 4.0TRW 2000
Note: DAT / Plane / N0.mcg, actually not a MCG file, it seems to be BMP, first change it to run again without problems!
#include
typedef struct BITMAPHEADER {unsigned short type; unsigned long size; unsigned long reserved; unsigned long offbits; unsigned long headsize; unsigned long width; unsigned long height; unsigned short planes; unsigned short bit;} BITMAPHEADER;
Void Encode (Byte * DST, DWORD LENGTH1, BYTE * SRC, DWORD LENGTH2);
Void LoadXMP (DWORD & W, DWORD & H, BYTE * & DATA, CHAR * NAME) {BitmapHeader BMPH; File * fp; char * TMP, * line; int i, pitch; unsigned J;
FP = FOPEN (Name, "RB"); // fp = CreateFile (Name, 0x80000000, 1, NULL, 3, 0X10000080, 0); // getFileSize (FP, & W);
Data = (Byte *) Malloc (W); if (data == null) {Printf ("Out of Memory!"); Return;}
Fread (DATA, W, 1, FP);
Fclose (fp);
// readfile (FP, DATA, W, & H, NULL);
// closehandle (fp);
Void SaveBMP (DWORD W, DWORD H, BYTE * DATA, CHAR * NAME) {file * f; BitmapFileHeader Bitinfo; DWord Headsize, LineSize, i, J, S, W1, H1; Unsigned Long Color
IF (DATA == NULL) RETURN;
IF ((f = fopen (Name, "WB")) == null) {Printf ("Write File Error");}
Memcpy (& W1, Data 0x1c, 4); Memcpy (& H1, Data 0x20, 4); // w1 = (DWORD) (* (Data 0x1c)); // h1 = (dword) (* (Data 0x20)); linesize = (w1 3) & 0xffffffc; s = linesize-3;
headsize = sizeof (bithead) sizeof (bitinfo); bithead.bfType = 'MB'; bithead.bfSize = headsize linesize * h1 1024; bithead.bfReserved1 = bithead.bfReserved2 = 0; bithead.bfOffBits = headsize 1024; FWRITE (& BitHead, 1, Sizeof (BitHead), F);
bitinfo.biSize = sizeof (bitinfo); bitinfo.biWidth = w1; bitinfo.biHeight = h1; bitinfo.biPlanes = 1; bitinfo.biBitCount = 8; bitinfo.biCompression = BI_RGB; bitinfo.biSizeImage = 0; bitinfo.biXPelsPerMeter = 72 Bitinfo.biypelspermeter = 72; Bitinfo.Biclrused = 0; Bitinfo.Biclrimportant = 0; FWRITE (& BitInfo, 1, Sizeof (BitInfo), F);
FWRITE (DATA 0X40, 0X400, 1, F);
Byte * pixel_data; pixel_data = (byte *) malloc (linesize * h1); if (pixel_data == null) {Printf ("out of memory"); goto return;}
ENCODE (Pixel_Data, Linesize * H1, Data 0x440, W-0x440);
For (i = 0; i
IF (pixel_data! = null) free (pixel_data);
RET: fclose (f);
Void Encode (Byte * DST, DWORD LENGTH1, BYTE * SRC, DWORD LENGTH2) {BYTE TMP [0x1000]; DWORD I, J, K, NUM;
MEMSET (TMP, 0, 0x1000);
// i = (dword) src length2; __ ASM {MOV EAX, SRC; MOV EBX, Length2; Add Eax, EBX; MOV I, EAX;
MOV EAX, DST; MOV EBX, Length1; Add Eax, EBX; MOV K, EAX;
__ASM {Push Ebx; Push EDX;
PUSH ESI;
MOV EBX, SRC; MOV EDX, DST; MOV ESI, 0x0Fee;
JMP _422A50; _422A42: SHR NUM, 1; MOV EAX, NUM; TEST AH, 1; JNZ _422A5D; _422A50: MOV CL, BYTE PTR [EBX]; MOV CH, 0xFF; AND ECX, 0xFFFF; MOV NUM, ECX;
INC EBX; _422A5D: Test Byte Ptr Num, 1; JZ _422A80; _422A64: MOV Al, [EBX]; and ESI, 0x0FFF;
MOV ECX, ESI; Inc ESI; Inc EBX; MOV BYTE PTR [EDX], AL; Inc EDX;
MOV [ECX TMP], AL;
JMP _422AD8; _422A80: MOV AX, [EBX]; MOV CL, AH;
And Eax, 0x0FFF; SHR CL, 4; Add Cl, 3; Inc EBX; Inc EBX;
CMP CL, 0; JZ _422AD7;
MOV J, EBX; MOV BL, Cl; _422AAB: AND ESI, 0x0FFF; And ESI, 0x0FFF;
MOV CL, BYTE PTR [TMP EAX]; MOV [EDX], CL;
MOV [TMP ESI], CL;
INC EX; Inc ESI; Inc EDX;
Dec BL; JNZ _422AB; MOV EBX, J; _422AD7: _422AD8: CMP EBX, I; JNB _RET; CMP EDX, K; JB _422A42; _RET: POP ESI; POP EDX; POP EBX;}}
Void main () {DWORD W, H; BYTE * DATA; BOOL RET; INT i; long done; _finddata_t f;
DONE = _FindFirst ("*. mcg", & f); if (done == - 1) Return; RET = FALSE;
While (! RET) {w = f.size; loadingXMP (W, H, Data, F.Name);
i = 0; Next: while (f.name [i]! = '.') i ; if (! ((f.name [i 1] == 'm' || f.name [i 1] == 'm') && (f.name [i 2] == 'c' || f.name [i 2] == 'c') && (f.name [i 3] == ' g '|| f.name [i 3] ==' g ')))) {i ; goto next;}
F.Name [i 1] = 'b'; f.Name [i 2] = 'm'; f.Name [i 3] = 'p';
SaveBMP (W, H, DATA, F.NAME);
IF (Data! = NULL) Free (DATA);
Ret = _findNext (DONE, & F);
Return;}