剑芒罗曼史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 ; } 
|