Sunday 23 April 2017

ECUFix has been updated to v6.2.6.7

Probably should have gone up a slightly higher version number this time because of the work I had to put into this.


I've added two extra binaries for US/Canada VW Rabbits (Golfs), both Normally Aspirated (NA) which took some doing! 360930 and 372644

If you would like to give it a try, the new version can be downloaded direct from ECUFix's product page or from the download directory HERE.

However, over the past month or so, I updated my development environment to Visual Studio 2017 and all seemed well except I noticed some unusual behaviour only after the project was compiled into Release mode.

The bug? Well to make things try and autocomplete as much as possible, I have a small routine to try and search for a string of bytes in a binary. A snippet follows (Thanks to http://hilite.me/)

unsigned __int32 chksumBase::FindStringWithDontCareInBinary(unsigned char *szString, unsigned __int32 nSLength, unsigned __int32 nStartAddress) 
{
 unsigned __int32 nAddr = 0xffffffff, nIndexA, nIndexB;
 CString  csBuf;

 //Guard against overflows
 if(nSLength > m_nBSize)
 {
  nSLength = m_nBSize;
  csBuf.Format(_T("Warning! Function FindStringInBinary given nSLength of 0x%lx but the binary is only 0x%lx long"), (unsigned __int32)nSLength, (unsigned __int32)m_nBSize);
  DisplayErrorText(csBuf);
  return 0xffffffff;//Error
 }

 //Guard against overflows
 if((nStartAddress + nSLength) > m_nBSize)
 {
  csBuf.Format(_T("Warning! Function FindStringInBinary given a StartAddress of 0x%lx but length of 0x%lx when the binary is only 0x%lx long"), (unsigned __int32)nStartAddress, (unsigned __int32)nSLength, (unsigned __int32)m_nBSize);
  DisplayErrorText(csBuf);
  return 0xffffffff;//Error
 }

 for(nIndexA=nStartAddress; nIndexA < m_nBSize; nIndexA++)
 {
  if(*(m_pBinary+nIndexA) == *szString)
  {// We're matched for the 1st char, now check the rest
   for(nIndexB=0; nIndexB < nSLength; nIndexB++)
   {
    if(*(szString+nIndexB) != 0xff) //check for don't care flag
    {
     if(*(m_pBinary+nIndexA+nIndexB) != *(szString+nIndexB))
     {
      break;// No longer matched
     }
     
     if ((nIndexB + 1) == nSLength)
     {
      return nIndexA; // String completely matched
     }
    }
   }
  }
 }

 return nAddr;
}

That code has worked for the past few years but since the change to VS2017, it's stopped 😐 Therefore I've wrote the following instead and am just testing it for inclusion with the next version:

/*
* The memmem() function finds the start of the first occurrence of the
* substring 'needle' of length 'nSLength' in the memory area 'm_pBinary' of
* length 'binaryLength'.
*
* The return value is a pointer to the beginning of the sub-string, or
* NULL if the substring is not found.
* 
* From: http://stackoverflow.com/questions/2188914/c-searching-for-a-string-in-a-file
*/
unsigned __int32* chksumBase::memmem(unsigned char *needle, unsigned __int32 nSLength)
{
 int needle_first;
 unsigned char *p = m_pBinary;
 unsigned __int32 binaryLength = sizeof(m_pBinary);
 unsigned __int32 plen = nSLength;

 if (!nSLength)
  return nullptr;

 needle_first = *(unsigned char *)needle;

 while (plen >= nSLength && (p = (unsigned char *)memchr(p, needle_first, plen - nSLength + 1)))
 {
  if (!memcmp(p, needle, nSLength))
   return (unsigned __int32 *)p;

  p++;
  plen = binaryLength - (p - m_pBinary);
 }

 return nullptr;
}