剑芒罗曼史2解图片程序
mcg文件
file head 40h
---------------------------
10h palette offset
1ch width
20h height
---------------------------
palette 400h
---------------------------
BMP's palette
---------------------------
pixel data
使用一种比较特殊的压缩法,至少是我不知道的,呵呵,具体的解码函数看0x422990吧
使用工具
IDA 4.0
TRW 2000
注:
dat\plane\n0.mcg,实际上不是mcg文件,好像是bmp吧,先把它换名再运行才不会出问题!
#include <stdio.h>
#include <windows.h>
#include <malloc.h>
#include <io.h>
#include <conio.h>
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 bithead;
BITMAPINFOHEADER 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)&0xfffffffc;
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 ret;
}
encode(pixel_data,linesize*h1,data+0x440,w-0x440);
for(i=0;i<h1;i++)
fwrite(pixel_data+linesize*(h1-i-1),linesize,1,f);
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 eax,0x0fff;
and esi,0x0fff;
mov cl,byte ptr [tmp+eax];
mov [edx],cl;
mov [tmp+esi],cl;
inc eax;
inc esi;
inc edx;
dec bl;
jnz _422aab;
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;
LoadXmp(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 ;
}