バッファオーバーフローの脆弱性が Lhaca.exe の以下の似ているの function にあります。
function_40D974(FILE *fp, char *outbuffer)
{
char var_1408[4096];
char overflowedBuffer[255]; //var_408
char var_309[769];
DWORD var_8;
DWORD var_4;
var_4 = 0;
memset(outbuffer, 0, 0x12c); // clear 300-byte buffer
...
...
fseek(fp, 1, SEEK_SET);
...
...
if(fread(&var_1408[1], 1, 0x24, fp) < 0x24)
{
// exit with error "Invalid header (LHarc file ?)"
}
globalReadBufPtr = &var_1408[20]; // header-level byte position
outbuffer[0x15] = *globalReadBufPtr;
globalReadBufPtr++;
if(outbuffer[0x15] != 2) // check header level
{
if(fread(&var_1408[0x25], 1, 2, fp) < 2) // read length of extended header
{
// exit with error "Invalid header (LHarc file ?)"
}
}
if(outbuffer[0x15] >= 3)
{
// exit with error "Unknown level header"
}
globalReadBufPtr = &var_1408[2];
outbuffer[0] = 0x25;
memcpy(&outbuffer[1], &var_1408[2], 5);
...
...
...
// globalReadBufPtr points within the var_1408 buffer and currently points
// to the filename read from the LZH header.
40DAB9_copy_filename_in_lzh_header_to_outbuffer(&outbuffer[0x16],
globalReadBufPtr,
length_of_filename);
...
...
...
while(...) // loc_40DC67 (loop that reads all headers)
{
// globalReadBufPtr points within the var_1408 buffer and currently points to
// the next Extended Header Size field (two-bytes) that was read from the LZH file.
// The getNextExtendedHeaderSize() function will increment the "globalReadBufPtr"
// pointer by two bytes.
hdrSize = getNextExtendedHeaderSize(globalReadBufPtr);
// stop processing if the next header size is 0
if(hdrSize == 0)
break;
if(outbuffer[0x15] != 2) // header level
{
// This code checks that there is enough space to read header.
// The result of overflowedBuffer - globalReadBufPtr can be up
// to 0xFD9 (4057 bytes).
// So up the 4057 bytes can be read in this buffer. i.e. "hdrSize"
// can be up to 0xFD9.
// Note that globalReadBufPtr points within var_1408.
if(overflowedBuffer - globalReadBufPtr >= hdrSize)
{
if(fread(globalReadBufPtr, 1, hdrSize, fp) != hdrSize)
{
// exit with error "Invalid header (LHa file ?)"
}
switch(*globalReadBufPtr)
{
globalReadBufPtr++;
case 40: // MS-DOS attribute header : 0x40
{
...
}
case 2: // Directory name header : 0x02
{
// BUFFER OVERFLOW.
// (hdrSize - 3)-bytes of directory name in the
// extended header is copied from the buffer
// pointed to by globalReadBufPtr into
// overflowedBuffer.
// From above, it should be noted that up to
// 0xFD9 (4057) bytes can be read into the buffer
// pointed to by globalReadBufPtr. i.e. hdrSize
// can be up to 0xFD9.
// The size of overflowedBufer is only 0xFF (255).
// Note that there is another buffer below
// overflowedBuffer, so more than 0x408 (1032)
// bytes must be copied into overflowedBuffer to
// overwrite the saved EIP. This is possible since
// 4057 bytes can be read into globalReadBufPtr.
if(hdrSize-3 > 0)
{
copyloop(overflowedBuffer, globalReadBufPtr,
hdrSize-3);
}
...
}
...
}
}
else
{
// exit with error "Invalid header (LHa file ?)"
}
}
}
if(outbuffer[0x15] != 2) // header level
{
...
}
// &outbuffer[0x16] points to the filename read from the LZH header
// WRONG USE OF strncat() !!!!
// "overflowedBuffer" already contains the directory name copied from
// the extended header. So fixing strncat()'s length argument at
// 0xFF allows more bytes to be appended into the buffer that is already
// overflowed.
strncat(overflowedBuffer, &outbuffer[0x16], 0xFF);
strncpy(&outbuffer[0x16], overflowedBuffer, 0xFF);
...
...
...
...
}