⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fortify.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (st_Disabled)
        return 0;

    FORTIFY_LOCK();

    /*
     * Check the allocated memory
     */ 
    while (curr)
    {
        if (!st_CheckBlock(curr, file, line))
        {
          count++;
          break;    // !! added, GV 13/7-98
        }
        curr = curr->Next;      
    }

    /*
     * Check the deallocated memory while you're at it
     */
#ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
    curr = st_DeallocatedHead;
    while (curr)
    {
        if (!st_CheckDeallocatedBlock(curr, file, line))
            count++;

        curr = curr->Next;      
    }
#endif    

    /*  
     * If we know where we are, and everything is cool,
     * remember that. It might be important.
     */
    if (file && count == 0)
    {
        st_LastVerifiedFile = file;
        st_LastVerifiedLine = line;
    }

    FORTIFY_UNLOCK();
    return (count);
}


/*
 * Fortify_EnterScope() - enters a new Fortify scope 
 * level. Returns the new scope level.
 */
BYTE FORTIFY_STORAGE
Fortify_EnterScope(const char *file, DWORD line)
{
    ARGSUSED (file);
    ARGSUSED (line);
    return (++st_Scope);
}

/* Fortify_LeaveScope - leaves a Fortify scope level,
 * also prints a memory dump of all non-freed memory 
 * that was allocated during the scope being exited.
 * Does nothing and returns 0 if Fortify is disabled.
 */
BYTE FORTIFY_STORAGE
Fortify_LeaveScope(const char *file, DWORD line)
{
    struct Header *curr = st_AllocatedHead;
    DWORD size = 0, count = 0;

    if (st_Disabled)
        return 0;

    FORTIFY_LOCK();

    st_Scope--;
    while (curr)
    {
        if (curr->Scope > st_Scope)
        {
            if (count == 0)
            {
                sprintf(st_Buffer, "\nFortify: Memory leak detected leaving scope at %s.%lu\n", file, line);
                st_Output(st_Buffer);
                sprintf(st_Buffer, "%10s %8s %s\n", "Address", "Size", "Allocator");
                st_Output(st_Buffer);
            }
            
            st_OutputHeader(curr);
            count++;
            size += curr->Size;
        }

        curr = curr->Next;      
    }

    if (count)
    {
        sprintf(st_Buffer,"%8s %8lu bytes in %lu blocks with %lu bytes overhead\n",
                "total", size, count, count * FORTIFY_OVERHEAD);
        st_Output(st_Buffer);
    }

#ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
    /* 
     * Quietly free all the deallocated memory 
     * that was allocated in this scope that 
     * we are still tracking
     */
    st_PurgeDeallocatedScope (st_Scope, file, line);
#endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */

    FORTIFY_UNLOCK();
    return (st_Scope);
}

/*
 * Fortify_ListAllMemory() - Outputs the entire 
 * list of currently allocated memory. For each block 
 * is output it's Address, Size, and the SourceFile and 
 * Line that allocated it.
 *
 * If there is no memory on the list, this function 
 * outputs nothing.
 *
 * It returns the number of blocks on the list, unless 
 * Fortify has been disabled, in which case it always 
 * returns 0.
 */
DWORD FORTIFY_STORAGE
Fortify_ListAllMemory(const char *file, DWORD line)
{
    struct Header *curr = st_AllocatedHead;
    DWORD size = 0, count = 0;

    if (st_Disabled)
        return 0;

    Fortify_CheckAllMemory(file, line);

    FORTIFY_LOCK();

    if (curr)
    {
        sprintf(st_Buffer, "\n\nFortify: Memory List at %s.%lu\n", file, line);
        st_Output(st_Buffer);
        sprintf(st_Buffer, "%10s %8s %s\n", "Address", "Size", "Allocator");
        st_Output(st_Buffer);
                                
        while (curr)
        {
            st_OutputHeader(curr);
            count++;
            size += curr->Size;
            curr = curr->Next;      
        }
                     
        sprintf(st_Buffer, "%8s %8lu bytes in %lu blocks and %lu bytes overhead\n",
                           "total", size, count, count * FORTIFY_OVERHEAD);
        st_Output(st_Buffer);
    }
  
    FORTIFY_UNLOCK();
    return (count);
}

/*
 * Fortify_DumpAllMemory() - Outputs the entire list of 
 * currently allocated memory. For each allocated block 
 * is output it's Address, Size, the SourceFile and Line
 * that allocated it, a hex dump of the contents of the 
 * memory and an ascii dump of printable characters.
 *
 * If there is no memory on the list, this function outputs nothing.
 */
DWORD FORTIFY_STORAGE
Fortify_DumpAllMemory(const char *file, DWORD line)
{
    struct Header *curr = st_AllocatedHead;
    DWORD count = 0;

    if (st_Disabled)
        return 0;

    Fortify_CheckAllMemory(file, line);

    FORTIFY_LOCK();

    while (curr)
    {
        sprintf(st_Buffer, "\nFortify: Hex Dump of %s at %s.%lu\n",
                st_MemoryBlockString(curr), file, line);
        st_Output(st_Buffer);
        st_OutputMemory(curr);
        st_Output("\n");
        count++;

        curr = curr->Next;
    }

    FORTIFY_UNLOCK();
    return (count);
}

/* Fortify_OutputStatistics() - displays statistics 
 * about the maximum amount of memory that was 
 * allocated at any one time.
 */
void FORTIFY_STORAGE
Fortify_OutputStatistics(const char *file, DWORD line)
{
    if (st_Disabled)
        return;

    sprintf(st_Buffer, "\nFortify: Statistics at %s.%lu\n", file, line);
    st_Output(st_Buffer);

    sprintf(st_Buffer, "         Memory currently allocated: %lu bytes in %lu blocks\n",
                                 st_CurAllocation, st_CurBlocks);
    st_Output(st_Buffer);
    sprintf(st_Buffer, "         Maximum memory allocated at one time: %lu bytes in %lu blocks\n", 
                                 st_MaxAllocation, st_MaxBlocks);
    st_Output(st_Buffer);
    sprintf(st_Buffer, "         There have been %lu allocations and %lu deallocations\n",
                                 st_Allocations, st_Frees);
    st_Output(st_Buffer);
    sprintf(st_Buffer, "         There was a total of %lu bytes allocated\n",
                                 st_TotalAllocation);
    st_Output(st_Buffer);
    
    if (st_Allocations > 0)
    {
        sprintf(st_Buffer, "         The average allocation was %lu bytes\n",
                                     st_TotalAllocation / st_Allocations);
        st_Output(st_Buffer);                   
    }    
}

/* Fortify_GetCurrentAllocation() - returns the number of
 * bytes currently allocated.
 */
DWORD FORTIFY_STORAGE
Fortify_GetCurrentAllocation(const char *file, DWORD line)
{
    ARGSUSED (file);
    ARGSUSED (line);

    if (st_Disabled)
        return 0;

    return st_CurAllocation;
}

/* Fortify_SetAllocationLimit() - set a limit on the total
 * amount of memory allowed for this application.
 */
void FORTIFY_STORAGE
Fortify_SetAllocationLimit(DWORD NewLimit, const char *file, DWORD line)
{
    ARGSUSED (file);
    ARGSUSED (line);

    st_AllocationLimit = NewLimit;
}

/*
 * Fortify_Disable() - Run time method of disabling Fortify.
 * Useful if you need to turn off Fortify without recompiling
 * everything. Not as effective as compiling out, of course.
 * The less memory allocated by Fortify when it is disabled
 * the better.
 * (Previous versions of Fortify did not allow it to be 
 * disabled if there was any memory allocated at the time,
 * but since in C++ memory is often allocated before main
 * is even entered, this was useless so Fortify is now
 * able to cope).
 */
void FORTIFY_STORAGE
Fortify_Disable(const char *file, DWORD line)
{
#ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
    /* free all deallocated memory we might be tracking */
    st_PurgeDeallocatedScope (0, file, line);
#endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */

    st_Disabled = 1;
}



/*
 * st_CheckBlock - Check a block's header and fortifications.
 * Returns true if the block is happy.
 */
STATIC int
st_CheckBlock(struct Header *h, const char *file, DWORD line)
{
    BYTE *ptr = (BYTE *)h;
    int result = 1;

    if (!st_IsHeaderValid(h))
    {
      sprintf (st_Buffer,
               "\nFortify: Invalid pointer (%08lX) or corrupted header detected at %s.%lu\n",
               (DWORD)(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE), file, line);
                
      st_Output (st_Buffer);
      st_OutputLastVerifiedPoint();
      return (0);
    }

    if (!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE,
                           FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE))
    {
        sprintf(st_Buffer, "\nFortify: Underwrite detected before block %s at %s.%lu\n",
                           st_MemoryBlockString(h), file, line);
        st_Output(st_Buffer);

        st_OutputLastVerifiedPoint();
        st_OutputFortification(ptr + FORTIFY_HEADER_SIZE,
                            FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);
        result = 0;                        

#ifdef FORTIFY_FILL_ON_CORRUPTION
        st_SetFortification(ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);
#endif
    }
                           
    if (!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,
                           FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE))
    {
        sprintf(st_Buffer, "\nFortify: Overwrite detected after block %s at %s.%lu\n",
                           st_MemoryBlockString(h), file, line);
        st_Output(st_Buffer);

        st_OutputLastVerifiedPoint();
        st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,
                            FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);
        result = 0;

#ifdef FORTIFY_FILL_ON_CORRUPTION
        st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,
                         FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);
#endif
    }
 
    return (result);
}

#ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY

/* 
 * st_CheckDeallocatedBlock - Check a deallocated block's header and fortifications.
 * Returns true if the block is happy.
 */
STATIC int
st_CheckDeallocatedBlock(struct Header *h, const char *file, DWORD line)
{
    BYTE *ptr = (BYTE *)h;
    int result = 1;

    if (!st_IsHeaderValid(h))
    {
      sprintf (st_Buffer,
               "\nFortify: Invalid deallocated pointer (%08lX) or corrupted header detected at %s.%lu\n",
               (DWORD)(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE), file, line);
                
      st_Output(st_Buffer);
      st_OutputLastVerifiedPoint();
      return (0);
    }

    if (!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE,
            FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE))
    {
        sprintf(st_Buffer, "\nFortify: Underwrite detected before deallocated block %s at %s.%lu\n",
                           st_MemoryBlockString(h), file, line);
        st_Output(st_Buffer);
        sprintf(st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
                           st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
        st_Output(st_Buffer);

        st_OutputLastVerifiedPoint();
        st_OutputFortification(ptr + FORTIFY_HEADER_SIZE,
                            FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);

#ifdef FORTIFY_FILL_ON_CORRUPTION
        st_SetFortification(ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);
#endif
        result = 0;
    }
                           
    if (!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,
                           FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE))
    {
        sprintf(st_Buffer, "\nFortify: Overwrite detected after deallocated block %s at %s.%lu\n",
                           st_MemoryBlockString(h), file, line);
        st_Output(st_Buffer);
        sprintf(st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
                           st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
        st_Output(st_Buffer);

        st_OutputLastVerifiedPoint();
        st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,
                            FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);

#ifdef FORTIFY_FILL_ON_CORRUPTION
        st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,
                         FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);
#endif
        result = 0;
    }

#ifdef FORTIFY_FILL_ON_DEALLOCATE
    if (!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
                           FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size))
    {
        sprintf(st_Buffer, "\nFortify: Write to deallocated block %s detected at %s.%lu\n",
                           st_MemoryBlockString(h), file, line);
        st_Output(st_Buffer);

        sprintf(st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
                           st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
        st_Output(st_Buffer);
        st_OutputLastVerifiedPoint();
    
        st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
                            FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size);

#ifdef FORTIFY_FILL_ON_CORRUPTION
        st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
                            FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size);
#endif /* FORTIFY_FILL_ON_CORRUPTION */
        result = 0;
    }
#endif /* FORTIFY_FILL_ON_DEALLOCATE */
    return result;
 }

#endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */


/*
 * st_CheckFortification - Checks if the _size_ 
 * bytes from _ptr_ are all set to _value_
 * Returns true if all is happy.
 */
STATIC int
st_CheckFortification(BYTE *ptr, BYTE value, size_t size)
{
    while (size--)
        if (*ptr++ != value)
            return (0);
      
    return (1);
}

/*
 * st_SetFortification - Set the _size_ bytes from _ptr_ to _value_.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -