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

📄 fortify.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 */
STATIC void
st_SetFortification(BYTE *ptr, BYTE value, size_t size)
{
    memset(ptr, value, size);
}

/*
 * st_OutputFortification - Output the corrupted section of the fortification 
 */
STATIC void
st_OutputFortification(BYTE *ptr, BYTE value, size_t size)
{
    size_t offset, skipped, advance;
    offset = 0;

    sprintf(st_Buffer, "   Address   Offset Data (%02x)", value);
    st_Output(st_Buffer);

    while (offset < size)
    {
        /* 
         * Skip 3 or more 'correct' lines
         */
        if ((size - offset) < 3 * 16)
            advance = size - offset;
        else
            advance = 3 * 16;
        if (advance > 0 && st_CheckFortification(ptr+offset, value, advance))
        {
            offset += advance;
            skipped = advance;
                 
            if (size - offset < 16)
                advance = size - offset;
            else
                advance = 16;
             
            while (advance > 0 && st_CheckFortification(ptr+offset, value, advance))
            {
                offset  += advance;
                skipped += advance;
                if (size - offset < 16)
                    advance = size - offset;
                else
                    advance = 16;
            }    
            sprintf(st_Buffer, "\n                        ...%lu bytes skipped...", (DWORD)skipped);
            st_Output(st_Buffer);
            continue;
        }
        else
        {
            if (size - offset < 16)
                st_HexDump(ptr, offset, size-offset, 0);
            else
                st_HexDump(ptr, offset, 16, 0);
                
            offset += 16;
        }
    }

    st_Output("\n");
}

/*
 * st_HexDump - output a nice hex dump of "size" bytes, starting at "ptr" + "offset"
 */
STATIC void
st_HexDump(BYTE *ptr, size_t offset, size_t size, int title)
{
    char ascii[17];
    int  column;
    int  output;

    if (title)
        st_Output("   Address   Offset Data");

    column = 0;
    ptr += offset;
    output = 0;

    while (output < size)
    {
        if (column == 0)
        {
          sprintf(st_Buffer, "\n%08lX %8lu ", (DWORD)ptr, (DWORD)offset);
          st_Output(st_Buffer);
        }

        sprintf (st_Buffer, "%02x%s", *ptr, ((column % 4) == 3) ? " " : "");
        st_Output (st_Buffer);

        ascii [column]   = isprint(*ptr) ? (char)*ptr : '.';
        ascii [column+1] = '\0';

        ptr++;
        offset++;
        output++;
        column++;

        if (column == 16)
        {
            st_Output ("   \"");
            st_Output (ascii);
            st_Output ("\"");
            column = 0;
        }
    }

    if  (column != 0)
    {
        while  (column < 16)
        {
            if  (column % 4 == 3)
                st_Output ("   ");
            else
                st_Output ("  ");

            column++;
        }
        st_Output ("   \"");
        st_Output (ascii);
        st_Output ("\"");
    }
}

/*
 * st_IsHeaderValid - Returns true if the 
 * supplied pointer does indeed point to a 
 * real Header
 */
STATIC int
st_IsHeaderValid(struct Header *h)                                
{
    return (st_ChecksumHeader(h) == FORTIFY_CHECKSUM_VALUE);
}

/*
 * st_MakeHeaderValid - Updates the checksum 
 * to make the header valid
 */
STATIC void
st_MakeHeaderValid(struct Header *h)
{
    h->Checksum = 0;
    h->Checksum = (WORD)(FORTIFY_CHECKSUM_VALUE - st_ChecksumHeader(h));
}

/*
 * st_ChecksumHeader - Calculate (and return) 
 * the checksum of the header. (Including the 
 * Checksum field itself. If all is well, the 
 * checksum returned by this function should
 * be FORTIFY_CHECKSUM_VALUE
 */
STATIC WORD
st_ChecksumHeader(struct Header *h)
{
#if (DOSX)
    return inchksum_fast (h, FORTIFY_HEADER_SIZE/sizeof(WORD));
#else
    WORD c, checksum, *p;
  
    for(c = 0, checksum = 0, p = (WORD *)h;
        c < FORTIFY_HEADER_SIZE/sizeof(WORD); c++)
    {    
        checksum += *p++;  
    }    
    
    return (checksum);
#endif
}                  

/* 
 * st_IsOnAllocatedList - Examines the allocated 
 * list to see if the given header is on it.
 */  
STATIC int
st_IsOnAllocatedList(struct Header *h)
{
    struct Header *curr;
  
    curr = st_AllocatedHead;
    while (curr)
    {
        if (curr == h)
            return (1);
      
        curr = curr->Next;
    }
  
    return (0);
}

#ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
/* 
 * st_IsOnDeallocatedList - Examines the deallocated 
 * list to see if the given header is on it.
 */  
STATIC int
st_IsOnDeallocatedList(struct Header *h)
{
    struct Header *curr;
  
    curr = st_DeallocatedHead;
    while (curr)
    {
        if (curr == h)
            return (1);
      
        curr = curr->Next;
    }
  
    return (0);
}

/*
 * st_PurgeDeallocatedBlocks - free at least "Bytes"
 * worth of deallocated memory, starting at the 
 * oldest deallocated block.
 * Returns true if any blocks were freed.
 */
STATIC int
st_PurgeDeallocatedBlocks(DWORD Bytes, const char *file, DWORD line)
{
    DWORD FreedBytes = 0;
    DWORD FreedBlocks = 0;

#ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY
    sprintf(st_Buffer, "\nFortify: Warning - Discarding deallocated memory at %s.%lu\n", 
                       file, line);
    st_Output(st_Buffer);
#endif /* FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */

    while (st_DeallocatedTail && FreedBytes < Bytes)
    {
        st_CheckDeallocatedBlock(st_DeallocatedTail, file, line);
        FreedBytes += st_DeallocatedTail->Size;
        FreedBlocks++;
#ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY
#ifdef FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY
        sprintf(st_Buffer, "                %s\n",
                           st_DeallocatedMemoryBlockString(st_DeallocatedTail));
        st_Output(st_Buffer);
#endif /* FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */
#endif /* FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */
        st_FreeDeallocatedBlock(st_DeallocatedTail, file, line);
    }

    return FreedBlocks != 0;
}

/*
 * st_PurgeDeallocatedScope - free all deallocated
 * memory blocks that were allocated within "Scope"
 */
STATIC int
st_PurgeDeallocatedScope(BYTE Scope, const char *file, DWORD line)
{
    struct Header *curr;
    DWORD FreedBlocks = 0;

    curr = st_DeallocatedHead;
    while (curr)
    {
        struct Header *next = curr->Next;
        if (curr->Scope >= Scope)
        {
            st_FreeDeallocatedBlock(curr, file, line);
            FreedBlocks++;
        }

        curr = next;
    }
    
    return FreedBlocks != 0;
}

/*
 * st_FreeDeallocatedBlock - actually remove
 * a deallocated block from the deallocated 
 * list, and actually free it's memory.
 */
STATIC void
st_FreeDeallocatedBlock(struct Header *h, const char *file, DWORD line)
{
    st_CheckDeallocatedBlock (h, file, line);

   /* 
    * Begin Critical region 
    */
    FORTIFY_LOCK();

    st_TotalDeallocated -= h->Size;
    
    if (st_DeallocatedHead == h)
    {
        st_DeallocatedHead = h->Next;
    }
    
    if (st_DeallocatedTail == h)
    {
        st_DeallocatedTail = h->Prev;
    }
    
    if (h->Prev)
    {
        st_CheckDeallocatedBlock(h->Prev, file, line);
        h->Prev->Next = h->Next;
        st_MakeHeaderValid(h->Prev);    
    }
    
    if (h->Next)
    {
        st_CheckDeallocatedBlock(h->Next, file, line);
        h->Next->Prev = h->Prev;
        st_MakeHeaderValid(h->Next);    
    }

    /*
     * Free the label
     */
    if (h->Label)
    {
        free(h->Label);
    }

    /*
     * Nuke out all memory that is about to be freed, including the header
     */
    st_SetFortification((BYTE*)h, FORTIFY_FILL_ON_DEALLOCATE_VALUE,
                        FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size + FORTIFY_AFTER_SIZE);

    /*
     * And do the actual free
     */
    free(h);
    
    /*
     * End critical region
     */
    FORTIFY_UNLOCK();    
}

#endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */

/*
 * st_OutputMemory - Hex and ascii dump the 
 * user memory of a block.
 */
STATIC void
st_OutputMemory(struct Header *h)
{
    st_HexDump((BYTE*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
               0, h->Size, 1);
}


/*
 * st_OutputHeader - Output the header
 */
STATIC void st_OutputHeader (struct Header *h)
{
  BYTE *adr = (BYTE*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE;

  if (h->Label == NULL)
       sprintf (st_Buffer, "%08lX %8lu %s.%lu\n",
                (DWORD) adr, (DWORD)h->Size, h->File, h->Line);

  else sprintf (st_Buffer, "%08lX %8lu %s.%lu %s\n",
                (DWORD) adr, (DWORD)h->Size, h->File, h->Line, h->Label);
  st_Output(st_Buffer);
}

/*
 * st_OutputLastVerifiedPoint - output the last
 * known point where everything was hoopy.
 */
STATIC void
st_OutputLastVerifiedPoint()
{
    sprintf(st_Buffer, "         Memory integrity was last verified at %s.%lu\n", 
                       st_LastVerifiedFile,
                       st_LastVerifiedLine);
    st_Output(st_Buffer);
}

/*
 * st_MemoryBlockString - constructs a string that 
 * desribes a memory block. (pointer,size,allocator,label)
 */
STATIC const char *
st_MemoryBlockString(struct Header *h)
{
    static char st_BlockString[512];
    
    if (h->Label == 0)
    {
        sprintf (st_BlockString,"(%08lX,%lu,%s.%lu)",
                (DWORD)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
                (DWORD)h->Size, h->File, h->Line);
    }            
    else
    {
        sprintf(st_BlockString,"(%08lX,%lu,%s.%lu,%s)",
                (DWORD)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
                (DWORD)h->Size, h->File, h->Line, h->Label);
    }

    return st_BlockString;
}

#ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
#ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY
#ifdef FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY
/*
 * st_DeallocatedMemoryBlockString - constructs
 * a string that desribes a deallocated memory
 * block. (pointer,size,allocator,deallocator)
 */

STATIC const char *
st_DeallocatedMemoryBlockString(struct Header *h)
{
    static char st_BlockString[256];

    if (h->Label == 0)
    {
        sprintf(st_BlockString,"(%08lX,%lu,%s.%lu,%s.%lu)",
                (DWORD)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
                (DWORD)h->Size, h->File, h->Line, h->FreedFile, h->FreedLine);
    }            
    else
    {
        sprintf(st_BlockString,"(%08lX,%lu,%s.%lu,%s.%lu,%s)",
                (DWORD)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
                (DWORD)h->Size, h->File, h->Line, h->FreedFile, h->FreedLine, h->Label);
    }

    return st_BlockString;
}
#endif /* FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */
#endif /* FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */
#endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */


/*
 * st_DefaultOutput - the default output function
 */
STATIC void
st_DefaultOutput(const char *String)
{
    fprintf(stdout, String);
    fflush(stdout);
}

/*
 * Fortify_malloc - Fortify's replacement malloc()

⌨️ 快捷键说明

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