Skip to content

Commit c7a8e51

Browse files
committed
fix endianism and structure packing issues in mmcmp.cpp
1 parent 0901b25 commit c7a8e51

File tree

1 file changed

+78
-26
lines changed

1 file changed

+78
-26
lines changed

src/mmcmp.cpp

Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010

1111
BOOL PP20_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength);
1212

13+
#pragma pack(1)
1314
typedef struct MMCMPFILEHEADER
1415
{
15-
DWORD id_ziRC;// "ziRC"
16-
DWORD id_ONia;// "ONia"
16+
char id[8];// "ziRCONia"
1717
WORD hdrsize;
1818
} MMCMPFILEHEADER, *LPMMCMPFILEHEADER;
1919

@@ -43,6 +43,13 @@ typedef struct MMCMPSUBBLOCK
4343
DWORD unpk_pos;
4444
DWORD unpk_size;
4545
} MMCMPSUBBLOCK, *LPMMCMPSUBBLOCK;
46+
#pragma pack()
47+
48+
// make sure of structure sizes
49+
typedef int chk_MMCMPFILEHEADER[(sizeof(struct MMCMPFILEHEADER) == 10) * 2 - 1];
50+
typedef int chk_MMCMPHEADER[(sizeof(struct MMCMPHEADER) == 14) * 2 - 1];
51+
typedef int chk_MMCMPBLOCK[(sizeof(struct MMCMPBLOCK) == 20) * 2 - 1];
52+
typedef int chk_MMCMPSUBBLOCK[(sizeof(struct MMCMPSUBBLOCK) == 8) * 2 - 1];
4653

4754
#define MMCMP_COMP0x0001
4855
#define MMCMP_DELTA0x0002
@@ -84,57 +91,106 @@ DWORD MMCMPBITBUFFER::GetBits(UINT nBits)
8491
extern void Log(LPCSTR s, ...);
8592
#endif
8693

87-
const DWORD MMCMP8BitCommands[8] =
94+
static const DWORD MMCMP8BitCommands[8] =
8895
{
8996
0x01, 0x03,0x07, 0x0F,0x1E, 0x3C,0x78, 0xF8
9097
};
9198

92-
const UINT MMCMP8BitFetch[8] =
99+
static const UINT MMCMP8BitFetch[8] =
93100
{
94101
3, 3, 3, 3, 2, 1, 0, 0
95102
};
96103

97-
const DWORD MMCMP16BitCommands[16] =
104+
static const DWORD MMCMP16BitCommands[16] =
98105
{
99106
0x01, 0x03,0x07, 0x0F,0x1E, 0x3C,0x78, 0xF0,
100107
0x1F0, 0x3F0, 0x7F0, 0xFF0, 0x1FF0, 0x3FF0, 0x7FF0, 0xFFF0
101108
};
102109

103-
const UINT MMCMP16BitFetch[16] =
110+
static const UINT MMCMP16BitFetch[16] =
104111
{
105112
4, 4, 4, 4, 3, 2, 1, 0,
106113
0, 0, 0, 0, 0, 0, 0, 0
107114
};
108115

109116

117+
static void swap_mfh(LPMMCMPFILEHEADER fh)
118+
{
119+
fh->hdrsize = bswapLE16(fh->hdrsize);
120+
}
121+
122+
static void swap_mmh(LPMMCMPHEADER mh)
123+
{
124+
mh->version = bswapLE16(mh->version);
125+
mh->nblocks = bswapLE16(mh->nblocks);
126+
mh->filesize = bswapLE32(mh->filesize);
127+
mh->blktable = bswapLE32(mh->blktable);
128+
}
129+
130+
static void swap_block (LPMMCMPBLOCK blk)
131+
{
132+
blk->unpk_size = bswapLE32(blk->unpk_size);
133+
blk->pk_size = bswapLE32(blk->pk_size);
134+
blk->xor_chk = bswapLE32(blk->xor_chk);
135+
blk->sub_blk = bswapLE16(blk->sub_blk);
136+
blk->flags = bswapLE16(blk->flags);
137+
blk->tt_entries = bswapLE16(blk->tt_entries);
138+
blk->num_bits = bswapLE16(blk->num_bits);
139+
}
140+
141+
static void swap_subblock (LPMMCMPSUBBLOCK sblk)
142+
{
143+
sblk->unpk_pos = bswapLE32(sblk->unpk_pos);
144+
sblk->unpk_size = bswapLE32(sblk->unpk_size);
145+
}
146+
147+
110148
BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength)
111149
//---------------------------------------------------------
112150
{
113-
DWORD dwMemLength = *pdwMemLength;
114-
LPCBYTE lpMemFile = *ppMemFile;
151+
DWORD dwMemLength;
152+
LPCBYTE lpMemFile;
115153
LPBYTE pBuffer;
116-
LPMMCMPFILEHEADER pmfh = (LPMMCMPFILEHEADER)(lpMemFile);
117-
LPMMCMPHEADER pmmh = (LPMMCMPHEADER)(lpMemFile+10);
118-
LPDWORD pblk_table;
154+
LPMMCMPFILEHEADER pmfh;
155+
LPMMCMPHEADER pmmh;
156+
const DWORD *pblk_table;
119157
DWORD dwFileSize;
158+
BYTE tmp0[32], tmp1[32];
120159

121160
if (PP20_Unpack(ppMemFile, pdwMemLength))
122161
{
123162
return TRUE;
124163
}
125-
if ((dwMemLength < 256) || (!pmfh) || (pmfh->id_ziRC != 0x4352697A) || (pmfh->id_ONia != 0x61694e4f) || (pmfh->hdrsize < 14)
164+
165+
dwMemLength = *pdwMemLength;
166+
lpMemFile = *ppMemFile;
167+
if ((dwMemLength < 256) || (!lpMemFile)) return FALSE;
168+
memcpy(tmp0, lpMemFile, 24);
169+
pmfh = (LPMMCMPFILEHEADER)(tmp0);
170+
pmmh = (LPMMCMPHEADER)(tmp0+10);
171+
swap_mfh(pmfh);
172+
swap_mmh(pmmh);
173+
174+
if ((memcmp(pmfh->id,"ziRCONia",8) != 0) || (pmfh->hdrsize < 14)
126175
|| (!pmmh->nblocks) || (pmmh->filesize < 16) || (pmmh->filesize > 0x8000000)
127176
|| (pmmh->blktable >= dwMemLength) || (pmmh->blktable + 4*pmmh->nblocks > dwMemLength)) return FALSE;
128177
dwFileSize = pmmh->filesize;
129178
if ((pBuffer = (LPBYTE)GlobalAllocPtr(GHND, (dwFileSize + 31) & ~15)) == NULL) return FALSE;
130-
pblk_table = (LPDWORD)(lpMemFile+pmmh->blktable);
179+
pblk_table = (const DWORD *)(lpMemFile+pmmh->blktable);
131180
for (UINT nBlock=0; nBlock<pmmh->nblocks; nBlock++)
132181
{
133-
DWORD dwMemPos = pblk_table[nBlock];
134-
LPMMCMPBLOCK pblk = (LPMMCMPBLOCK)(lpMemFile+dwMemPos);
135-
LPMMCMPSUBBLOCK psubblk = (LPMMCMPSUBBLOCK)(lpMemFile+dwMemPos+20);
136-
137-
if ((dwMemPos + 20 >= dwMemLength) || (dwMemPos + 20 + pblk->sub_blk*8 >= dwMemLength)) break;
182+
DWORD dwMemPos = bswapLE32(pblk_table[nBlock]);
183+
LPMMCMPBLOCK pblk;
184+
LPMMCMPSUBBLOCK psubblk;
185+
186+
if (dwMemPos + 20 >= dwMemLength) break;
187+
memcpy(tmp1,lpMemFile+dwMemPos,28);
188+
pblk = (LPMMCMPBLOCK)(tmp1);
189+
psubblk = (LPMMCMPSUBBLOCK)(tmp1+20);
190+
swap_block(pblk);
191+
swap_subblock(psubblk);
192+
193+
if (dwMemPos + 20 + pblk->sub_blk*8 >= dwMemLength) break;
138194
dwMemPos += 20 + pblk->sub_blk*8;
139195
#ifdef MMCMP_LOG
140196
Log("block %d: flags=%04X sub_blocks=%d", nBlock, (UINT)pblk->flags, (UINT)pblk->sub_blk);
@@ -328,12 +384,12 @@ ULONG PPBITBUFFER::GetBits(UINT n)
328384
result = (result<<1) | (bitbuffer&1);
329385
bitbuffer >>= 1;
330386
bitcount--;
331-
}
332-
return result;
387+
}
388+
return result;
333389
}
334390

335391

336-
VOID PP20_DoUnpack(const BYTE *pSrc, UINT nSrcLen, BYTE *pDst, UINT nDstLen)
392+
static VOID PP20_DoUnpack(const BYTE *pSrc, UINT nSrcLen, BYTE *pDst, UINT nDstLen)
337393
{
338394
PPBITBUFFER BitBuffer;
339395
ULONG nBytesLeft;
@@ -395,7 +451,7 @@ BOOL PP20_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength)
395451
DWORD dwDstLen;
396452
LPBYTE pBuffer;
397453

398-
if ((!lpMemFile) || (dwMemLength < 256) || (*(DWORD *)lpMemFile != 0x30325050)) return FALSE;
454+
if ((!lpMemFile) || (dwMemLength < 256) || (memcmp(lpMemFile,"PP20",8) != 0)) return FALSE;
399455
dwDstLen = (lpMemFile[dwMemLength-4]<<16) | (lpMemFile[dwMemLength-3]<<8) | (lpMemFile[dwMemLength-2]);
400456
//Log("PP20 detected: Packed length=%d, Unpacked length=%d\n", dwMemLength, dwDstLen);
401457
if ((dwDstLen < 512) || (dwDstLen > 0x400000) || (dwDstLen > 16*dwMemLength)) return FALSE;
@@ -406,7 +462,3 @@ BOOL PP20_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength)
406462
return TRUE;
407463
}
408464

409-
410-
411-
412-

0 commit comments

Comments
 (0)