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

📄 pemonitor.c

📁 PE Monitor是一个小调试器和反汇编器
💻 C
字号:
///////////////////////////////////////////////////////////////////////////////
//
//  FileName    :   PEMonitor.c
//  Version     :   0.10
//  Author      :   Luo Cong
//  Date        :   2004-09-02 (yyyy-mm-dd)
//  Comment     :
//
///////////////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <stdio.h>

#include "Misc.h"
#include "PEMonitor.h"
#include "PEServ.h"
#include "FileServ.h"
#include "BreakPointServ.h"
#include "StackServ.h"
#include "MemServ.h"
#include "LogServ.h"
#include "disasm.h"

#ifdef _DEBUG
#include "tib.h"
PTIB pTib;
#endif

long                g_lFileSize     = 0;
char                *g_FileContents = NULL;
unsigned long       g_ulImageBase   = 0;

int ProcessFile(char *szCmdLine)
{
    int nRetResult = 0;
    int nRetCode;

    CONTEXT ct;
    STARTUPINFO si;
    DEBUG_EVENT de;
    PROCESS_INFORMATION pi;

    LPVOID lpAddr; 
    int nSetBPIndex = 1;
    int nCurBPIndex;

    FUNCTION_NAME fnPrevFuncName;
    unsigned long ulPrevEIP;
#ifdef _MY_DEBUG
    char szPrevFuncName[FUNCTIONNAMELEN];
#endif

    GetStartupInfo(&si);

    nRetCode = CreateProcess(
        NULL,           // name of executable module
        szCmdLine,      // command line string
        NULL,           // ProcessAttributes
        NULL,           // ThreadAttributes
        FALSE,          // handle inheritance option
        DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS,    // creation flags
        NULL,           // new environment block
        NULL,           // current directory name
        &si,            // startup information
        &pi             // process information
    );
    MY_PROCESS_ERROR(nRetCode);

    for (;;)
    {
        nRetCode = WaitForDebugEvent(&de, INFINITE);
        MY_PROCESS_ERROR(nRetCode);

        if (EXIT_PROCESS_DEBUG_EVENT == de.dwDebugEventCode)
        {
            printf("\n**** PE Monitor: Debug Process finished! ****\n");
#ifdef _DEBUG
            MessageBox(NULL, "Process finished!", "PE Monitor", MB_ICONINFORMATION);
#endif
            break;
        }
        else if (CREATE_PROCESS_DEBUG_EVENT == de.dwDebugEventCode)
        {
            nRetCode = SetFunctionsBreakPoint(pi.hProcess);
            MY_PROCESS_ERROR(nRetCode);
        }
        else if (EXCEPTION_DEBUG_EVENT == de.dwDebugEventCode)
        {
            if (
                EXCEPTION_BREAKPOINT ==\
                de.u.Exception.ExceptionRecord.ExceptionCode
            )
            {
                lpAddr = de.u.Exception.ExceptionRecord.ExceptionAddress;
                nCurBPIndex = GetBreakPointIndex(lpAddr);
                if (nCurBPIndex)
                {
#ifdef _MY_DEBUG
                    printf(
                        "Break '%s' at address: 0x%08X\n",
                        g_bpData[nCurBPIndex].szFuncName,
                        lpAddr
                    );
#endif
#ifdef _MY_DEBUG
                    strcpy(szPrevFuncName, g_bpData[nCurBPIndex].szFuncName);
#endif

                    fnPrevFuncName = g_bpData[nCurBPIndex].fnFuncName;

                    nRetCode = RemoveBreakPoint(pi.hProcess, nCurBPIndex);
                    MY_PROCESS_ERROR(nRetCode);

                    ct.ContextFlags = CONTEXT_FULL;
                    nRetCode = GetThreadContext(pi.hThread, &ct);
                    MY_PROCESS_ERROR(nRetCode);

                    nRetCode = AnalyzeBreakPointAndWriteToLog(
                        pi.hProcess,
                        ct.Esp,
                        fnPrevFuncName
                    );
                    MY_PROCESS_ERROR(nRetCode);

                    --ct.Eip;
                    // Set single step flag to Re-SetBreakPoint on this
                    // existing breakpoint.
                    ct.EFlags |= TRAPFLAG;  // set single step flag

                    nRetCode = SetThreadContext(pi.hThread, &ct);
                    MY_PROCESS_ERROR(nRetCode);

                    ulPrevEIP = ct.Eip;
                }
            }   // EXCEPTION_BREAKPOINT
            else if (
                EXCEPTION_SINGLE_STEP ==\
                de.u.Exception.ExceptionRecord.ExceptionCode
            )
            {
                // Re-SetBreakPoint on the last existing breakpoint.
                nRetCode = SetBreakPoint(
                    pi.hProcess,
                    (unsigned long *)ulPrevEIP,
#ifdef _MY_DEBUG
                    szPrevFuncName,
#endif
                    fnPrevFuncName,
                    nCurBPIndex
                );
                MY_PROCESS_ERROR(nRetCode);
            }   // EXCEPTION_SINGLE_STEP
        }
        nRetCode = ContinueDebugEvent(
            de.dwProcessId,
            de.dwThreadId,
            DBG_CONTINUE
        );
        MY_PROCESS_ERROR(nRetCode);
    }   // for (;;)

    nRetResult = 1;
Exit0:
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return nRetResult;
}

int Initialize(const char *szPEFileName)
{
    int nRetResult = 0;
    int nRetCode;

    IMAGE_NT_HEADERS nt_header;

    nRetCode = ReadFileContents(szPEFileName);
    MY_PROCESS_ERROR(nRetCode);

    nRetCode = InitLogFile(szPEFileName);
    MY_PROCESS_ERROR(nRetCode);

    nRetCode = GetNTHeader(&nt_header);
    MY_PROCESS_ERROR(nRetCode);

    g_ulImageBase = nt_header.OptionalHeader.ImageBase;

    nRetResult = 1;
Exit0:
    return nRetResult;
}

void Finalize()
{
    FreeFileContents();
    FinalizeLogFile();
}

void Usage(const char *szExecFileName)
{
    printf(
        "PE Monitor v%d.%02d, Compiled on " __DATE__ ", " __TIME__ "\n"
        "Copyleft (C) Luo Cong at Kingsoft, Duba\n"
        "Usage:\n\t"
        "%s FileName [Parameter 1] [Parameter 2] ... [Parameter N]\n",
        VERSIONHI,
        VERSIONLO,
        szExecFileName
    );
}

/**
 * Attention:
 *      szCmdLine's size must not greater than MAX_PATH,
 *      Here has an hidden trouble.
 */
void GetStartupCmdLine(int argc, char *argv[], char *szCmdLine)
{
    int i;

    szCmdLine[0] = '\0';
    strcat(szCmdLine, "\"");
    strcat(szCmdLine, argv[1]);
    strcat(szCmdLine, "\" ");
    for (i = 2; i < argc; ++i)
    {
        strcat(szCmdLine, argv[i]);
        strcat(szCmdLine, " ");
    }
    szCmdLine[strlen(szCmdLine) - 1] = '\0';
}

int main(int argc, char *argv[])
{
    int nRetResult = 0;
    int nRetCode;

    char szCmdLine[MAX_PATH];

    if (argc < 2)
    {
        Usage(argv[0]);
        goto Exit0;
    }

    nRetCode = IsPEFile(argv[1]);
    MY_PROCESS_ERROR(nRetCode);

    nRetCode = Initialize(argv[1]);
    MY_PROCESS_ERROR(nRetCode);

    GetStartupCmdLine(argc, argv, szCmdLine);

    nRetCode = ProcessFile(szCmdLine);
    MY_PROCESS_ERROR(nRetCode);

    nRetResult = 1;
Exit0:
    Finalize();
    return nRetResult;
}

⌨️ 快捷键说明

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