void CheckUnused(void * ptr, TraceItem *i)
{
	//DBERR("CheckUnused: checking whether the memory at 0x%08X was used at all\n", ptr);
	unsigned char * start = (unsigned char *) ADDPTR(ptr, prefix);
	unsigned char * end = (unsigned char *) ADDPTR(ptr, prefix+i->size);

	if (end <= start) {
		DBERR("trace-error: end before or equal to start?!\n");
		return;
	}

	bool bUnused = true;
	for (unsigned char * p = start; p < end; p++)
	{
		//DBERR("check: memory at 0x%08X (0x%02X)\n", p, *p);
		if (*p != 0xa5) 
		{
			bUnused = false;
		}
	}
	if (bUnused)
	{
		//DBERR("CheckUnused: memory at 0x%08X was NOT used at all\n", ptr);
		unusedList.push_back(new TraceItem(*i));
	}
}
/*
 * Allocated memory will be surrounded by 8 guard-bytes that will be
 * checked at deallocation. (a leading and trailing unsigned int)
 */
inline void * allocate(unsigned int size, const char *file, int line, const char *type)
{
	// before allocation new memory, check for corruption in existing markers
	CheckSanity();

	Uint32 extraNomansLand = 0;
	size = size + extraNomansLand;

	Uint32 neededSize = (size + 3) & 0xffffffc;  // actual allocated memory for data (assumption: 32 bit architecture)
    neededSize += markerSize;                    // add area of markers

    void * ptr = (void *) malloc(neededSize);
    memset(ptr, 0xa6, neededSize);		// no-mans land poison

	unsigned int *markBegin = (unsigned int *) ptr;
	*markBegin = 0xa1a2a3a4;

    unsigned int *markEnd = (unsigned int *) ADDPTR(ptr, neededSize-postfix);
 	*markEnd = 0xf1f2f3f4;

	// increse ptr behound the magic marker
	ptr = ADDPTR(ptr, prefix);

	memset(ptr, 0xa5, size);		// un-initialized poison
	
	traceMap[ptr] = new TraceItem(size, neededSize, file, line, type);
    DBERR("MEMORY allocation at 0x%08X (%s) of %u bytes from %s:%u\n", ptr, type, size, file, line);
    return ptr;
}
void TraceCheckInternal(void * ptr, TraceItem *i)
{
	bool errorDetected = false;
	//DBERR("TraceCheckInternal: checking magic markers of 0x%08X allocated at %s:%u\n", ptr, i->file.c_str(), i->line);

	// Check the begin-marker is in-tact
	unsigned int *markBegin = (unsigned int *) ptr;
	if ((*markBegin) != 0xa1a2a3a4)
	{
		DBERR("TraceCheckInternal: markBegin check FAILED for %s at 0x%08X allocated at %s:%u\n", i->type.c_str(), ptr, i->file.c_str(), i->line);
		errorDetected = true;
	}

	// Check for in-tact no-mans land poison 
	unsigned char * nomansLand = (unsigned char *) ADDPTR(ptr, prefix+i->size);
	unsigned char * nomansEnd = (unsigned char *) ADDPTR(nomansLand, i->neededSize-markerSize-i->size);
	
	if (nomansEnd < nomansLand) {
		DBERR("trace-error: negative amount of nomansland\n");
		return;
	}
	
	for (unsigned char * p = nomansLand; p < nomansEnd; p++)
	{
		if (*p != 0xa6)
		{
			DBERR("TraceCheckInternal: Nomans land area overwritten (0x%02X != 0x%02X) for %s at 0x%08X allocated at %s:%u\n", *p, 0xa6, i->type.c_str(), p, i->file.c_str(), i->line);
			errorDetected = true;
		}
	}

	// Check the end-marker is in-tact
    unsigned int *markEnd = (unsigned int *) ADDPTR(ptr, i->neededSize-postfix);
	if ((*markEnd) != 0xf1f2f3f4)
	{
		DBERR("TraceCheckInternal: markEnd check FAILED for %s at 0x%08X allocated at %s:%u\n", i->type.c_str(), ptr, i->file.c_str(), i->line);
		errorDetected = true;
	}
	
	// comment this line to just LOG errors, and not stop when they occur
	//assert(!errorDetected);
}
Esempio n. 4
0
void
_gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
                                             enum random_origins),
                                 enum random_origins origin)
{
  static int addedFixedItems = 0;

  if ( debug_me )
    log_debug ("rndw32#gather_random_fast: ori=%d\n", origin );

  /* Get various basic pieces of system information: Handle of active
     window, handle of window with mouse capture, handle of clipboard
     owner handle of start of clpboard viewer list, pseudohandle of
     current process, current process ID, pseudohandle of current
     thread, current thread ID, handle of desktop window, handle of
     window with keyboard focus, whether system queue has any events,
     cursor position for last message, 1 ms time for last message,
     handle of window with clipboard open, handle of process heap,
     handle of procs window station, types of events in input queue,
     and milliseconds since Windows was started. On 64-bit platform
     some of these return values are pointers and thus 64-bit wide.
     We discard the upper 32-bit of those values.  */

  {
    byte buffer[20*sizeof(intptr_t)], *bufptr;

    bufptr = buffer;
#define ADDINT(f)  do { intptr_t along = (intptr_t)(f);               \
                        memcpy (bufptr, &along, sizeof (intptr_t) );  \
                        bufptr += sizeof (along);                     \
                      } while (0)
#define ADDPTR(f)  do { void *aptr = (f);                          \
                        ADDINT((SIZE_T)aptr);                      \
                      } while (0)

    ADDPTR ( GetActiveWindow ());
    ADDPTR ( GetCapture ());
    ADDPTR ( GetClipboardOwner ());
    ADDPTR ( GetClipboardViewer ());
    ADDPTR ( GetCurrentProcess ());
    ADDINT ( GetCurrentProcessId ());
    ADDPTR ( GetCurrentThread ());
    ADDINT ( GetCurrentThreadId ());
    ADDPTR ( GetDesktopWindow ());
    ADDPTR ( GetFocus ());
    ADDINT ( GetInputState ());
    ADDINT ( GetMessagePos ());
    ADDINT ( GetMessageTime ());
    ADDPTR ( GetOpenClipboardWindow ());
    ADDPTR ( GetProcessHeap ());
    ADDPTR ( GetProcessWindowStation ());
    /* Following function in some cases stops returning events, and cannot
       be used as an entropy source.  */
    /*ADDINT ( GetQueueStatus (QS_ALLEVENTS));*/
    ADDINT ( GetTickCount ());

    gcry_assert ( bufptr-buffer < sizeof (buffer) );
    (*add) ( buffer, bufptr-buffer, origin );
#undef ADDINT
#undef ADDPTR
  }

  /* Get multiword system information: Current caret position, current
     mouse cursor position.  */
  {
    POINT point;

    GetCaretPos (&point);
    (*add) ( &point, sizeof (point), origin );
    GetCursorPos (&point);
    (*add) ( &point, sizeof (point), origin );
  }

  /* Get percent of memory in use, bytes of physical memory, bytes of
     free physical memory, bytes in paging file, free bytes in paging
     file, user bytes of address space, and free user bytes.  */
  {
    MEMORYSTATUS memoryStatus;

    memoryStatus.dwLength = sizeof (MEMORYSTATUS);
    GlobalMemoryStatus (&memoryStatus);
    (*add) ( &memoryStatus, sizeof (memoryStatus), origin );
  }

  /* Get thread and process creation time, exit time, time in kernel
     mode, and time in user mode in 100ns intervals.  */
  {
    HANDLE handle;
    FILETIME creationTime, exitTime, kernelTime, userTime;
    SIZE_T minimumWorkingSetSize, maximumWorkingSetSize;

    handle = GetCurrentThread ();
    GetThreadTimes (handle, &creationTime, &exitTime,
                    &kernelTime, &userTime);
    (*add) ( &creationTime, sizeof (creationTime), origin );
    (*add) ( &exitTime, sizeof (exitTime), origin );
    (*add) ( &kernelTime, sizeof (kernelTime), origin );
    (*add) ( &userTime, sizeof (userTime), origin );

    handle = GetCurrentProcess ();
    GetProcessTimes (handle, &creationTime, &exitTime,
                     &kernelTime, &userTime);
    (*add) ( &creationTime, sizeof (creationTime), origin );
    (*add) ( &exitTime, sizeof (exitTime), origin );
    (*add) ( &kernelTime, sizeof (kernelTime), origin );
    (*add) ( &userTime, sizeof (userTime), origin );

    /* Get the minimum and maximum working set size for the current
       process.  */
    GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
                              &maximumWorkingSetSize);
    /* On 64-bit system, discard the high 32-bits. */
    (*add) ( &minimumWorkingSetSize, sizeof (int), origin );
    (*add) ( &maximumWorkingSetSize, sizeof (int), origin );
  }


  /* The following are fixed for the lifetime of the process so we only
   * add them once */
  if (!addedFixedItems)
    {
      STARTUPINFO startupInfo;

      /* Get name of desktop, console window title, new window
         position and size, window flags, and handles for stdin,
         stdout, and stderr.  */
      startupInfo.cb = sizeof (STARTUPINFO);
      GetStartupInfo (&startupInfo);
      (*add) ( &startupInfo, sizeof (STARTUPINFO), origin );
      addedFixedItems = 1;
    }

  /* The performance of QPC varies depending on the architecture it's
     running on and on the OS, the MS documentation is vague about the
     details because it varies so much.  Under Win9x/ME it reads the
     1.193180 MHz PIC timer.  Under NT/Win2K/XP it may or may not read the
     64-bit TSC depending on the HAL and assorted other circumstances,
     generally on machines with a uniprocessor HAL
     KeQueryPerformanceCounter() uses a 3.579545MHz timer and on machines
     with a multiprocessor or APIC HAL it uses the TSC (the exact time
     source is controlled by the HalpUse8254 flag in the kernel).  That
     choice of time sources is somewhat peculiar because on a
     multiprocessor machine it's theoretically possible to get completely
     different TSC readings depending on which CPU you're currently
     running on, while for uniprocessor machines it's not a problem.
     However, the kernel appears to synchronise the TSCs across CPUs at
     boot time (it resets the TSC as part of its system init), so this
     shouldn't really be a problem.  Under WinCE it's completely platform-
     dependent, if there's no hardware performance counter available, it
     uses the 1ms system timer.

     Another feature of the TSC (although it doesn't really affect us here)
     is that mobile CPUs will turn off the TSC when they idle, Pentiums
     will change the rate of the counter when they clock-throttle (to
     match the current CPU speed), and hyperthreading Pentiums will turn
     it off when both threads are idle (this more or less makes sense,
     since the CPU will be in the halted state and not executing any
     instructions to count).

     To make things unambiguous, we detect a CPU new enough to call RDTSC
     directly by checking for CPUID capabilities, and fall back to QPC if
     this isn't present.

     On AMD64, TSC is always available and intrinsic is provided for accessing
     it.  */
#ifdef __WIN64__
    {
      unsigned __int64 aint64;

      /* Note: cryptlib does not discard upper 32 bits of TSC on WIN64, but does
       * on WIN32.  Is this correct?  */
      aint64 = __rdtsc();
      (*add) (&aint64, sizeof(aint64), origin);
    }
#else
#ifdef __GNUC__
/*   FIXME: We would need to implement the CPU feature tests first.  */
/*   if (cpu_has_feature_rdtsc) */
/*     { */
/*       uint32_t lo, hi; */
      /* We cannot use "=A", since this would use %rax on x86_64. */
/*       __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); */
      /* Ignore high 32 bits, hwich are >1s res.  */
/*       (*add) (&lo, 4, origin ); */
/*     } */
/*   else */
#endif /*!__GNUC__*/
    {
      LARGE_INTEGER performanceCount;

      if (QueryPerformanceCounter (&performanceCount))
        {
          if ( debug_me )
          log_debug ("rndw32#gather_random_fast: perf data\n");
          (*add) (&performanceCount, sizeof (performanceCount), origin);
        }
      else
        {
          /* Millisecond accuracy at best... */
          DWORD aword = GetTickCount ();
          (*add) (&aword, sizeof (aword), origin );
        }
    }
#endif /*__WIN64__*/


}