Click here to Skip to main content
13,149,756 members (81,496 online)
Click here to Skip to main content

Stats

133.7K views
6.8K downloads
182 bookmarked
Posted 27 May 2007

Tamper Aware and Self Healing Code

, 15 Nov 2007
Dynamically Detect Code Alterations and Repair In-Memory Executable Files Using Hashing and Crypto++
// Self Healing 1.cpp
//

#include "stdafx.h"

VOID ImageInformation( HMODULE& hModule, PVOID& pVirtualAddress,
                       PVOID& pCodeStart, SIZE_T& dwCodeSize,
                       PVOID& pCodeEnd );
                       
VOID DumpImageInformation( HMODULE hModule, PVOID pVirtualAddress,
                           PVOID pCodeStart, SIZE_T dwCodeSize,
                           PVOID pCodeEnd );

VOID HexDump( LPCVOID pcbStartAddress,
              LPCVOID pDisplayBaseAddress = (PVOID)-1,
              DWORD dwSize = DEFAULT_DUMP_SIZE );

int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE hModule = NULL;
    PVOID   pVirtualAddress = NULL;
    PVOID   pCodeStart = NULL;
    PVOID   pCodeEnd = NULL;    
    SIZE_T  dwCodeSize = 0;
       
    ImageInformation( hModule, pVirtualAddress, pCodeStart,
                      dwCodeSize, pCodeEnd );                   
    
    DumpImageInformation( hModule, pVirtualAddress, pCodeStart,
                          dwCodeSize, pCodeEnd );
    
    HexDump( pCodeStart, pCodeStart, DUMP_SIZE );    

    return 0;
}

VOID DumpImageInformation( HMODULE hModule, PVOID pVirtualAddress,
                           PVOID pCodeStart, SIZE_T dwCodeSize,
                           PVOID pCodeEnd )
{
    std::tcout << _T("****************************************************");
    std::tcout << std::endl;
    std::tcout << _T("************* Memory Image Information *************");
    std::tcout << std::endl;
    std::tcout << _T("****************************************************");
    std::tcout << std::endl << std::endl;
    
    std::tcout << _T("         hModule: ");
    std::tcout << HEXADECIMAL_OUTPUT(8);
    std::tcout << hModule << std::endl;
            
    std::tcout << _T(" Virtual Address: ");
    std::tcout << HEXADECIMAL_OUTPUT(8);
    std::tcout << pVirtualAddress << std::endl;  
                    
    std::tcout << _T("     .text Start: ");
    std::tcout << HEXADECIMAL_OUTPUT(8);
    std::tcout << pCodeStart << std::endl;

    std::tcout << _T("      .text Size: ");
    std::tcout << HEXADECIMAL_OUTPUT(8);
    std::tcout << dwCodeSize << std::endl;    

    std::tcout << _T("       .text End: ");
    std::tcout << HEXADECIMAL_OUTPUT(8);
    std::tcout << pCodeEnd << std::endl;
               
    std::tcout << std::endl;
}                           

VOID ImageInformation( HMODULE& hModule, PVOID& pVirtualAddress,
                       PVOID& pCodeStart, SIZE_T& dwCodeSize,
                       PVOID& pCodeEnd )
{
    const UINT PATH_SIZE = 2 * MAX_PATH;
    TCHAR szFilename[ PATH_SIZE ] = { 0 };    

    __try {

        /////////////////////////////////////////////////
        /////////////////////////////////////////////////
        if( 0 == GetModuleFileName( NULL, szFilename, PATH_SIZE ) )
        {
            std::tcerr << _T("Error Retrieving Process Filename");
            std::tcerr << std::endl;
            __leave;
        }

        hModule = GetModuleHandle( szFilename );
        if( NULL == hModule )
        {
            std::tcerr << _T("Error Retrieving Process Module Handle");
            std::tcerr << std::endl;
            __leave;
        }

        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////
        PIMAGE_DOS_HEADER pDOSHeader = NULL;
        pDOSHeader = static_cast<PIMAGE_DOS_HEADER>( (PVOID)hModule );
        if( pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE )
        {
            std::tcerr << _T("Error - File is not EXE Format");
            std::tcerr << std::endl;
            __leave;
        }

        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        pNTHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(
            (PBYTE)hModule + pDOSHeader->e_lfanew );
        if( pNTHeader->Signature != IMAGE_NT_SIGNATURE )
        {
            std::tcerr << _T("Error - File is not PE Format") << std::endl;
            __leave;
        }

        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////
        PIMAGE_FILE_HEADER pFileHeader = NULL;
        pFileHeader = reinterpret_cast<PIMAGE_FILE_HEADER>(
            (PBYTE)&pNTHeader->FileHeader );

        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////
        PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
        pOptionalHeader = reinterpret_cast<PIMAGE_OPTIONAL_HEADER>(
            (PBYTE)&pNTHeader->OptionalHeader );

        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////
        if( IMAGE_NT_OPTIONAL_HDR32_MAGIC !=
            pNTHeader->OptionalHeader.Magic )
        {
            std::tcerr << _T("Error - File is not 32 bit") << std::endl;
            __leave;
        }

        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;
        pSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(
            (PBYTE)&pNTHeader->OptionalHeader +
            pNTHeader->FileHeader.SizeOfOptionalHeader );

        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////
        const CHAR TEXT[] = ".text";
        const CHAR BSSTEXT[] = ".textbss";
        UINT nSectionCount = pNTHeader->FileHeader.NumberOfSections;
        CHAR szSectionName[ IMAGE_SIZEOF_SHORT_NAME + 1 ];
        szSectionName[ IMAGE_SIZEOF_SHORT_NAME ] = '\0';
        for( UINT i = 0; i < nSectionCount; i++ )
        {
            memcpy( szSectionName, pSectionHeader->Name,
                    IMAGE_SIZEOF_SHORT_NAME );

            if( 0 == strncmp( TEXT, szSectionName,
                              IMAGE_SIZEOF_SHORT_NAME ) )
            {
                std::tcout << std::endl;
                break;
            }

            pSectionHeader++;
        }

        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////
        if( 0 != strncmp( TEXT, szSectionName, IMAGE_SIZEOF_SHORT_NAME ) )
        {
            std::tcerr << _T("Error - Unable to locate ");
            std::cerr << TEXT;
            std::tcerr << _T(" TEXT") << std::endl;
            __leave;
        }

        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////
        pVirtualAddress = (PVOID)(pSectionHeader->VirtualAddress);
        
        dwCodeSize = pSectionHeader->Misc.VirtualSize;
        
        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////        
        pCodeStart = (PVOID)(((PBYTE)hModule) +
                     (SIZE_T)((PBYTE)pVirtualAddress) );
                     
        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////                      
        pCodeEnd = (PVOID)((PBYTE)pCodeStart + dwCodeSize );                      
    }

    __except( EXCEPTION_EXECUTE_HANDLER ) {
        std::tcerr << std::endl << _T("Caught Exception") << std::endl;
    }
}

VOID HexDump( LPCVOID pcbStartAddress, LPCVOID pDisplayBaseAddress,
              DWORD dwSize )
{
    /////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////
    std::tcout << HEXADECIMAL_OUTPUT(8);

    /////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////
    DWORD dwPosition = 0;
    const UINT BYTES_PER_LINE = 16;

    if( (PVOID)-1 == pDisplayBaseAddress )
    {
        pDisplayBaseAddress = pcbStartAddress;
    }

    do
    {
        if( 0 == dwPosition % BYTES_PER_LINE )
        {
            std::tcout << HEXADECIMAL_OUTPUT(8);
            std::tcout << (SIZE_T)((PBYTE)pDisplayBaseAddress + dwPosition);
            std::tcout << _T(": ");
        }

        std::tcout << HEXADECIMAL_OUTPUT(2);
        std::tcout << (SIZE_T)(((PBYTE)pcbStartAddress)[ dwPosition ]);
        std::tcout << _T(" ");

        if( 0 == (dwPosition+1) % BYTES_PER_LINE && 0 != dwPosition )
        {
            std::tcout << std::endl;
        }
        else
        if( 0 == (dwPosition+1) % (BYTES_PER_LINE/2) && 0 != dwPosition )
        {
            std::tcout << _T(" ");
        }

    } while( ++dwPosition < dwSize );
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Jeffrey Walton
Systems / Hardware Administrator
United States United States
No Biography provided

You may also be interested in...

Pro
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170924.2 | Last Updated 15 Nov 2007
Article Copyright 2007 by Jeffrey Walton
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid