March 24, 2012

One byte heap overflow

The following code snippet copies the content of source buffer to the destination buffer. Since the source buffer is one-byte-larger than the destination buffer it overflows the heap by one byte.
void main(void)
{
    char* pDest = new char[4];
    char pSrc[] = {"Bytes"};
    memcpy(pDest, pSrc, 5);
    delete pDest;
}
Let's see the source code again matching the blocks to their native counterparts.
void main(void)
{
 push        ebp
 mov         ebp,esp
 sub         esp,8
    char* pDest = new char[4];
 push        4
 call        dword ptr [__imp_operator new (10E209Ch)]
    char pSrc[] = {"Bytes"};
 mov         ecx,dword ptr [string "Bytes" (10E20F4h)]
 mov         dx,word ptr ds:[10E20F8h]
    memcpy(pDest, pSrc, 5);
 mov         dword ptr [eax],ecx ;Copy 4 bytes to destination buffer
 mov         cl,dl
    delete pDest;
 push        eax
 mov         word ptr [ebp-4],dx
 mov         byte ptr [eax+4],cl ;Copy the 5th byte out of destination buffer
 call        dword ptr [__imp_operator delete (10E20A4h)]
 add         esp,8
}
 xor         eax,eax
 mov         esp,ebp
 pop         ebp
 ret
In this example one byte overflow didn't lead to crash on my machine, and in reality, the error would have remained undetected. These errors can be detected by enabling full page heap verification by setting up global flags like below.
gflags /p /enable TestSilentCorrupt.exe /full
When you execute the program it now crashes when delete() is called.
It remains a question for me that the copy of 5th byte why it is associated in the block with delete() rather with memcpy().
  This blog is written and maintained by Attila Suszter. Read in Feed Reader.