Having problems with your account or logging in?
A lot of changes are happening in the community right now. Some may affect you. READ MORE HERE

Bug of the Month - June 2011

Matt Schuetze1 Absent Member.
Absent Member.
0 0 875

 This month's bug takes us down to some bare metal. Sometimes PDBs and Microsoft’s Debug interface just pass on the wrong information to us.  When we have the wrong information this can lead to perceived errors on BoundsChecker's part, especially when using guard bytes, poison on free, or fill on allocation. The incorrect program behavior reported to us in a recent customer case was that BC was overwriting variables past the structure we should have been. 


//Demonstrate RPI
     size_t memsize;
     LV_ITEM lvi;           
     memsize= sizeof(lvi); // this will return 40
     int j = _WIN32_WINNT;
     char *p = (char*)(&lvi);
    *(p+memsize+2) = 0;
//End demo code


LV_ITEM is defined as

typedef struct {
  UINT   mask;
  int    iItem;
  int    iSubItem;
  UINT   state;
  UINT   stateMask;
  LPTSTR pszText;
  int    cchTextMax;
  int    iImage;
  LPARAM lParam;
#if (_WIN32_IE >= 0x0300)
  int    iIndent;
#if (_WIN32_WINNT >= 0x0501)
  int    iGroupId;
  UINT   cColumns;
  UINT   puColumns;
#if (_WIN32_WINNT >= 0x0600)
  int    piColFmt;
  int    iGroup;

As we can see there are many conditional members of the structure and looking at the debug windows we can see the defines were set to and what the debugger tells us the fields are for the LVI_ITEM structure.
Debug window

       memsize              40           unsigned int                                                //Sizeof lvi

        j               0x00000400         int                        // _WIN32_WINNT

      lvi            {mask=0xcccccccc iItem=0xcccccccc iSubItem=0xcccccccc ...}     tagLVITEMW
                                mask     0xcccccccc           unsigned int
                                iItem     0xcccccccc           int
                                iSubItem              0xcccccccc           int
                                state      0xcccccccc           unsigned int
                                stateMask           0xcccccccc           unsigned int
+                             pszText                0xcccccccc <Bad Ptr>      wchar_t *
                                cchTextMax       0xcccccccc           int
                                iImage  0xcccccccc           int
                                lParam  0xcccccccc           long
                                iIndent 0xcccccccc           int
                                iGroupId              0xcccccccc           int
                                cColumns            0xcccccccc           unsigned int
+                             puColumns         0x00000000         unsigned int *

From the definition above we see the last 3 items listed in the debug window should not be there based on the value of _WIN32_WINNT
#if (_WIN32_WINNT >= 0x0501)
  int    iGroupId;
  UINT   cColumns;
  UINT   puColumns;
Note the above debug output is from a run of the application that is not instrumented nor being run under BoundsChecker. When we query the PDB information for the structure and its elements and use those items to put our poison or allocation fillers in we, are using the base address of the variable and the offsets given to us. The same type of operation / overwrite would occur if the user was to manipulate the values in the debug windows.
Sometimes a “bug” in your application is the result of erroneous information being passed from the compiler. Thanks to Mark L. for contributing this article!
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.