📄 fortify.c
字号:
*/
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 + -