You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.6 KiB
129 lines
3.6 KiB
/*
|
|
* Copyright 2002-2019 Intel Corporation.
|
|
*
|
|
* This software is provided to you as Sample Source Code as defined in the accompanying
|
|
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
|
|
* section 1.L.
|
|
*
|
|
* This software and the related documents are provided as is, with no express or implied
|
|
* warranties, other than those that are expressly stated in the License.
|
|
*/
|
|
|
|
//
|
|
// This tool prints a trace of image load and unload events
|
|
//
|
|
|
|
#include "pin.H"
|
|
#include <stdio.h>
|
|
|
|
namespace WINDOWS
|
|
{
|
|
#include <windows.h>
|
|
}
|
|
|
|
WINDOWS::PIMAGE_DATA_DIRECTORY GetExportDirectory(ADDRINT base)
|
|
{
|
|
if (base == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
WINDOWS::PIMAGE_DOS_HEADER pDos = reinterpret_cast<WINDOWS::PIMAGE_DOS_HEADER>(base);
|
|
|
|
// Returns FALSE when not DOS MZ header
|
|
if (pDos->e_magic != IMAGE_DOS_SIGNATURE)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
const WINDOWS::PIMAGE_NT_HEADERS pHeaders = reinterpret_cast<WINDOWS::PIMAGE_NT_HEADERS>
|
|
(reinterpret_cast<WINDOWS::ULONG_PTR>(pDos) + pDos->e_lfanew);
|
|
|
|
// check that this is PE/COFF image
|
|
if (pHeaders->Signature != IMAGE_NT_SIGNATURE)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
WINDOWS::PIMAGE_DATA_DIRECTORY pExpDirEntry =
|
|
&pHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
|
|
if ((pExpDirEntry->VirtualAddress == 0) || (pExpDirEntry->Size == 0))
|
|
{
|
|
return NULL; // No export directory
|
|
}
|
|
|
|
return pExpDirEntry;
|
|
}
|
|
|
|
|
|
// Pin calls this function every time a new img is loaded
|
|
VOID ImageLoad(IMG img, VOID *v)
|
|
{
|
|
if (!IMG_IsMainExecutable(img))
|
|
return;
|
|
|
|
printf("%s loaded\n", IMG_Name(img).c_str());
|
|
fflush(stdout);
|
|
|
|
ADDRINT imageBase = IMG_LowAddress(img);
|
|
WINDOWS::PIMAGE_DATA_DIRECTORY pExpDir = GetExportDirectory(imageBase);
|
|
if ((pExpDir == 0) || (pExpDir->Size == 0))
|
|
{
|
|
// Failure: Executable image lacks export directory.
|
|
printf("ERROR: No export directory in executable image\n");
|
|
fflush(stdout);
|
|
exit(3);
|
|
}
|
|
ADDRINT exportBase = imageBase + pExpDir->VirtualAddress;
|
|
|
|
// First check that bytes in export directory range do not belong to a RTN
|
|
for (ADDRINT addr = exportBase; addr < exportBase + pExpDir->Size; ++addr)
|
|
{
|
|
if (RTN_FindByAddress(addr) != RTN_Invalid())
|
|
{
|
|
// Test failure. Byte in export directory belongs to a RTN.
|
|
printf("ERROR: Data from export directory included in RTN\n");
|
|
fflush(stdout);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
// Second check RTN size. RTN range should not overlap with export directory range.
|
|
for (SEC sec = IMG_SecHead(img); sec != SEC_Invalid(); sec = SEC_Next(sec))
|
|
{
|
|
for (RTN rtn = SEC_RtnHead(sec); rtn != RTN_Invalid(); rtn = RTN_Next(rtn))
|
|
{
|
|
if (((RTN_Address(rtn) <= exportBase) && (RTN_Address(rtn) + RTN_Size(rtn) > exportBase)) ||
|
|
((RTN_Address(rtn) > exportBase) && (exportBase + pExpDir->Size > RTN_Address(rtn))))
|
|
{
|
|
// Test failure. RTN overlaps with export directory.
|
|
printf("ERROR: RTN overlaps with export directory\n");
|
|
fflush(stdout);
|
|
exit(2);
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// argc, argv are the entire command line, including pin -t <toolname> -- ...
|
|
int main(int argc, char * argv[])
|
|
{
|
|
// Initialize symbol processing
|
|
PIN_InitSymbols();
|
|
|
|
// Initialize pin
|
|
if (PIN_Init(argc, argv) != 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
// Register ImageLoad to be called when an image is loaded
|
|
IMG_AddInstrumentFunction(ImageLoad, 0);
|
|
|
|
// Start the program, never returns
|
|
PIN_StartProgram();
|
|
|
|
return 0;
|
|
}
|