内存中MFC的文本部分每次都在变化

时间:2013-12-03 16:48:02

标签: visual-c++ mfc operating-system reverse-engineering malware

我正在尝试在MFC exe中实现自我完整性检查。

参考: - Tamper Aware and Self Healing Code:Codeproject

我转储了文字部分

ofstream myfile;
myfile.open ("textsec.bin");
myfile.write((const char*)pCodeStart,dwCodeSize);
myfile.close();

每次它的不同如此哈希也是不同的。请帮忙

我想检查文本,即内存中的代码部分应与磁盘上存在的文件中的代码部分相同。 所以我们可以确定我们在内存中的exe文件没有修补。 我们可以在分发产品时使用。

我们将通过

开始在内存中启动代码段
 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;
    }
}      

现在我们可以计算代码段的哈希值

CalculateImageHash( pCodeStart, dwCodeSize, cbCalculatedImageHash );

然后我们与cbExpectedImageHash进行比较。 cbExpectedImageHash是预定义的全局

  if( 0 == memcmp( cbExpectedImageHash, cbCalculatedImageHash,
        CryptoPP::SHA224::DIGESTSIZE ) )
    {
        std::tcout << _T("Image is verified.") << std::endl;
    }

在MFC中,cbCalculatedImageHash每次都不同。 :(但不是在控制台应用程序。

cbExpectedImageHash和cbCalculatedImageHash是globel。

这是我的对话框的完整代码

// UserAppDlg.cpp : implementation file
//

#include "stdafx.h"
#include "UserApp.h"
#include "UserAppDlg.h"
#include "sha.h"        // SHA
#include "hex.h"        // HexEncoder
#include "files.h"      // FileSink
#include "filters.h"    // StringSink
#include "gzip.h"
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CAboutDlg dialog used for App About
// we can add cbExpectedImageHash new values if we get calcualted hash same every
BYTE cbExpectedImageHash[ CryptoPP::SHA224::DIGESTSIZE ] =
{ 
    0xBA, 0x71, 0x29, 0xD8, 0x79, 0x4E, 0xA3, 0x5A, 0x2C, 0xE0
    , 0xC5, 0x3A, 0x68, 0x9E, 0xE8, 0x29, 0x09, 0x44, 0xFA, 0x71
    , 0xAF, 0xDB,0x3E,0x88,0xAD,0x65,0x67,0x78
}; 

BYTE cbCalculatedImageHash[ CryptoPP::SHA224::DIGESTSIZE ] ; 

class CAboutDlg : public CDialog
{
public:
    CAboutDlg();

// Dialog Data
    enum { IDD = IDD_ABOUTBOX };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CUserAppDlg dialog




CUserAppDlg::CUserAppDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CUserAppDlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CUserAppDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CUserAppDlg, CDialog)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()


// CUserAppDlg message handlers
int CUserAppDlg::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;
    }
    return 0;
}     

    void CUserAppDlg::CalculateImageHash( PVOID pCodeStart, SIZE_T dwCodeSize,
        PBYTE pcbDigest )
    {
        CryptoPP::SHA224 hash;

        hash.Update( (PBYTE)pCodeStart, dwCodeSize );
        hash.Final( pcbDigest );    
    }  
BOOL CUserAppDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Add "About..." menu item to system menu.

    HMODULE hModule = NULL;
    PVOID   pVirtualAddress = NULL;
    PVOID   pCodeStart = NULL;
    PVOID   pCodeEnd = NULL;    
    SIZE_T  dwCodeSize = 0;

     ImageInformation( hModule, pVirtualAddress, pCodeStart,
                      dwCodeSize, pCodeEnd ); 
    ofstream myfile;
    myfile.open ("textsec.bin"); //textsec.bin changes everytime
    myfile.write((const char*)pCodeStart,dwCodeSize);
    myfile.close(); 

    CalculateImageHash( pCodeStart, dwCodeSize, cbCalculatedImageHash );     //cbCalculatedImageHash changes everytime
    myfile.open ("CalculateImageHash.bin");
    myfile.write((const char*)cbCalculatedImageHash,CryptoPP::SHA224::DIGESTSIZE);
    myfile.close();


    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon

    // TODO: Add extra initialization here

    return TRUE;  // return TRUE  unless you set the focus to a control
}

void CUserAppDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialog::OnSysCommand(nID, lParam);
    }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CUserAppDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CUserAppDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}

0 个答案:

没有答案