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

📄 breakpointserv.c

📁 PE Monitor是一个小调试器和反汇编器
💻 C
字号:
///////////////////////////////////////////////////////////////////////////////
//
//  FileName    :   BreakPointServ.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 "BreakPointServ.h"
#include "PEServ.h"
#include "MemServ.h"
#include "StackServ.h"
#include "LogServ.h"
#include "disasm.h"

const FUNCTION_BREAKPOINT g_FuncBP[] =
{
    {"CreateFileA",     FN_CREATEFILEA},
    {"DeleteFileA",     FN_DELETEFILEA},
    {"CopyFileA",       FN_COPYFILEA},
    {"RegCreateKeyA",   FN_REGCREATEKEYA},
    {"RegCreateKeyExA", FN_REGCREATEKEYEXA},
    {"RegDeleteKeyA",   FN_REGDELETEKEYA},
    {"RegSetValueA",    FN_REGSETVALUEA},
    {"RegSetValueExA",  FN_REGSETVALUEEXA},
};
const int g_nFuncBPCount = sizeof(g_FuncBP) / sizeof(FUNCTION_BREAKPOINT);

BPDATA g_bpData[MAXBREAKPOINTCOUNT] = { 0 };
static const int g_nBPDATACount = sizeof(g_bpData) / sizeof(BPDATA);

/**
 * Attention: nNum must start from 1
 */
int SetBreakPoint(
    /* [in] */ const HANDLE hProcess,
    /* [in] */ const LPVOID lpAddr,
#ifdef _MY_DEBUG
    /* [in] */ const char szFuncName[],
#endif
    /* [in] */ const FUNCTION_NAME fnFuncName,
    /* [in] */ const int nNum
) 
{ 
    int nRetResult = 0;
    int nRetCode;

    unsigned char byTemp;
    unsigned long ulNewProt;
    unsigned long ulOldProt;

    if (nNum >= g_nBPDATACount)
        goto Exit0;

    nRetCode = VirtualProtectEx(
        hProcess,
        lpAddr,
        1,
        PAGE_EXECUTE_READWRITE,
        &ulOldProt
    );
    MY_PROCESS_ERROR(nRetCode);
    nRetCode = ReadProcessMemory(hProcess, lpAddr, &byTemp, 1, NULL);
    MY_PROCESS_ERROR(nRetCode);

    g_bpData[nNum].lpAddr = lpAddr;
    g_bpData[nNum].byData = byTemp;
    g_bpData[nNum].fnFuncName = fnFuncName;
#ifdef _MY_DEBUG
    strcpy(g_bpData[nNum].szFuncName, szFuncName);
#endif

    byTemp = 0xcc;
    nRetCode = WriteProcessMemory(hProcess, lpAddr, &byTemp, 1, NULL);
    MY_PROCESS_ERROR(nRetCode);

    nRetResult = 1;
Exit0:
    VirtualProtectEx(hProcess, lpAddr, 1, ulOldProt, &ulNewProt);
    return nRetResult;
} 

/**
 * Attention: nNum must start from 1
 */
int RemoveBreakPoint(
    /* [in] */ const HANDLE hProcess,
    /* [in] */ const int nNum
)
{ 
    int nRetResult = 0;
    int nRetCode;

    unsigned char byTemp;
    unsigned long ulNewProt;
    unsigned long ulOldProt;
    LPVOID lpAddr = g_bpData[nNum].lpAddr;

    if (nNum >= g_nBPDATACount)
        goto Exit0;

    nRetCode = VirtualProtectEx(
        hProcess,
        lpAddr,
        1,
        PAGE_EXECUTE_READWRITE,
        &ulOldProt
    );
    MY_PROCESS_ERROR(nRetCode);
    nRetCode = ReadProcessMemory(hProcess, lpAddr, &byTemp, 1, NULL);
    MY_PROCESS_ERROR(nRetCode);

    nRetCode = (byTemp == 0xcc);
    MY_PROCESS_ERROR(nRetCode);

    nRetCode = WriteProcessMemory(
        hProcess,
        lpAddr,
        &g_bpData[nNum].byData,
        1,
        NULL
    );
    if (nRetCode)
        ZeroMemory(&g_bpData[nNum], sizeof(BPDATA));
    else
        goto Exit0;

    nRetResult = 1;
Exit0:
    VirtualProtectEx(hProcess, lpAddr, 1, ulOldProt, &ulNewProt);
    return nRetResult;
}

int GetBreakPointIndex(
    /* [in] */ const LPVOID lpAddr
)
{
    int nBPIndex = 0;
    int i;

    for (i = 1; i < g_nBPDATACount; ++i)
    {
        if (lpAddr == g_bpData[i].lpAddr)
        {
            nBPIndex = i;
            break;
        }
    }

    return nBPIndex;
}

int SetFunctionsBreakPoint(
    /* [in] */ const HANDLE hProcess
)
{
    int nRetResult = 0;
    int nRetCode;

    int i;
    char cmd[MAXCMDSIZE];
    unsigned long ulCmdSize;
    t_disasm da;
    unsigned long ulBase;
    unsigned long ulSize;
    unsigned long ulIndex = 0;
    unsigned long ulCurEIP;
    char szFuncName[FUNCTIONNAMELEN];

    int nBPIndex = 1;

    nRetCode = GetDisassemblerRange(&ulBase, &ulSize);
    MY_PROCESS_ERROR(nRetCode);

    while (ulIndex < ulSize)
    {
        ulCurEIP = ulBase + ulIndex;

        nRetCode = ReadCommand(ulCurEIP, MAXCMDSIZE, cmd);
        MY_PROCESS_ERROR(nRetCode);

        ulCmdSize = Disasm(cmd, MAXCMDSIZE, ulCurEIP, &da, DISASM_CODE);
        ulIndex += ulCmdSize;

        nRetCode = GetImportFunctionName(ulCurEIP, szFuncName);
        MY_PROCESS_ERROR(nRetCode);

        if ('\0' != szFuncName[0])
        {
            for (i = 0; i < g_nFuncBPCount; ++i)
            {
                nRetCode = strcmp(g_FuncBP[i].szFuncName, szFuncName);
                if (0 == nRetCode)  // 0 == Found
                {
                    nRetCode = SetBreakPoint(
                        hProcess,
                        (LPLONG)ulCurEIP,
#ifdef _MY_DEBUG
                        szFuncName,
#endif
                        g_FuncBP[i].fnFuncName,
                        nBPIndex++
                    );
                    MY_PROCESS_ERROR(nRetCode);
#ifdef _MY_DEBUG
                    printf(
                        "SetBreakPoint '%s' at 0x%08X\n",
                        g_FuncBP[i].szFuncName,
                        ulCurEIP
                    );
#endif
                    break;
                }
            }
        }
    }

    nRetResult = 1;
Exit0:
    return nRetResult;
}

int GetTextFromStack(
    /* [in] */ const HANDLE hProcess,
    /* [in] */ const unsigned long Esp,
    /* [in] */ const int nNum,  // Item's Number of stack, start from 1
    /* [in] */ const unsigned int unBufSize,
    /* [out] */ char *buf
)
{
    int nRetResult = 0;
    int nRetCode;

    unsigned long ulTextAddress;

    nRetCode = GetStackContents(
        hProcess,
        Esp + 4 * (nNum - 1),
        &ulTextAddress
    );
    MY_PROCESS_ERROR(nRetCode);

    if (0 == ulTextAddress)
    {
        buf[0] = '\0';
        goto Exit1;
    }

    nRetCode = ReadProcessMemory(
        hProcess,
        (unsigned long *)ulTextAddress,
        buf,
        unBufSize,
        NULL
    );
    MY_PROCESS_ERROR(nRetCode);

Exit1:
    nRetResult = 1;
Exit0:
    return nRetResult;
}

int GetULValueFromStack(
    /* [in] */ const HANDLE hProcess,
    /* [in] */ const unsigned long Esp,
    /* [in] */ const int nNum,  // Item's Number of stack, start from 1
    /* [out] */ unsigned long *ulParamValue
)
{
    int nRetResult = 0;
    int nRetCode;

    nRetCode = GetStackContents(
        hProcess,
        Esp + 4 * (nNum - 1),
        ulParamValue
    );
    MY_PROCESS_ERROR(nRetCode);

    nRetResult = 1;
Exit0:
    return nRetResult;
}

int AnalyzeBreakPointAndWriteToLog(
    /* [in] */ const HANDLE hProcess,
    /* [in] */ const unsigned long Esp,
    /* [in] */ const FUNCTION_NAME fnFuncName
)
{
    int nRetResult = 0;
    int nRetCode;

    int nReady = 1;
    int nLogLen = 0;

    char buf1[MAX_PATH] = { 0 };
    char buf2[MAX_PATH] = { 0 };

    unsigned long ulParamValue;

    char log[1024] = { 0 };

    switch (fnFuncName)
    {
    case FN_CREATEFILEA:
        nRetCode = GetTextFromStack(
            hProcess,
            Esp,
            1,
            MAX_PATH,
            buf1
        );
        MY_PROCESS_ERROR(nRetCode);
        nRetCode = GetULValueFromStack(
            hProcess,
            Esp,
            5,  // DWORD dwCreationDisposition,  // how to create
            &ulParamValue
        );
        MY_PROCESS_ERROR(nRetCode);
        if (
            (ulParamValue == CREATE_NEW) ||
            (ulParamValue == CREATE_ALWAYS)
        )
        {
            sprintf(log, "创建文件 %s 。\n", buf1);
#ifdef _DEBUG
            printf("CreateFile(): %s\n", buf1);
#endif
        }
        break;

    case FN_DELETEFILEA:
        nRetCode = GetTextFromStack(
            hProcess,
            Esp,
            1,
            MAX_PATH,
            buf1
        );
        MY_PROCESS_ERROR(nRetCode);
        sprintf(log, "删除文件 %s 。\n", buf1);
#ifdef _DEBUG
        printf("DeleteFile(): %s\n", buf1);
#endif
        break;

    case FN_COPYFILEA:
        nRetCode = GetTextFromStack(
            hProcess,
            Esp,
            1,
            MAX_PATH,
            buf1
        );
        MY_PROCESS_ERROR(nRetCode);
        nRetCode = GetTextFromStack(
            hProcess,
            Esp,
            2,
            MAX_PATH,
            buf2
        );
        MY_PROCESS_ERROR(nRetCode);
        sprintf(log, "拷贝文件 %s 到 %s 。\n", buf1, buf2);
#ifdef _DEBUG
        printf("CopyFile(): %s to %s\n", buf1, buf2);
#endif
        break;

    case FN_REGCREATEKEYEXA:
    case FN_REGCREATEKEYA:
        nRetCode = GetTextFromStack(
            hProcess,
            Esp,
            2,
            MAX_PATH,
            buf1
        );
        MY_PROCESS_ERROR(nRetCode);
        nRetCode = GetULValueFromStack(
            hProcess,
            Esp,
            1,
            &ulParamValue
        );
        MY_PROCESS_ERROR(nRetCode);
        switch (ulParamValue)
        {
        case HKEY_CLASSES_ROOT:
            nLogLen = sprintf(log, "创建注册表主键 HKEY_CLASSES_ROOT");
            break;
        case HKEY_CURRENT_CONFIG:
            nLogLen = sprintf(log, "创建注册表主键 HKEY_CURRENT_CONFIG");
            break;
        case HKEY_CURRENT_USER:
            nLogLen = sprintf(log, "创建注册表主键 HKEY_CURRENT_USER");
            break;
        case HKEY_LOCAL_MACHINE:
            nLogLen = sprintf(log, "创建注册表主键 HKEY_LOCAL_MACHINE");
            break;
        case HKEY_USERS:
            nLogLen = sprintf(log, "创建注册表主键 HKEY_USERS");
            break;
        case HKEY_PERFORMANCE_DATA:
            nLogLen = sprintf(log, "创建注册表主键 HKEY_PERFORMANCE_DATA");
            break;
        case HKEY_DYN_DATA:
            nLogLen = sprintf(log, "创建注册表主键 HKEY_DYN_DATA");
            break;
        default:
            nReady = 0;
            nLogLen = 0;
            break;
        }
        sprintf(log + nLogLen, "\\%s 。\n", buf1);
#ifdef _DEBUG
        printf("RegCreateKey(Ex)(): %s\n", buf1);
#endif
        break;

    case FN_REGDELETEKEYA:
        nRetCode = GetTextFromStack(
            hProcess,
            Esp,
            2,
            MAX_PATH,
            buf1
        );
        MY_PROCESS_ERROR(nRetCode);
        nRetCode = GetULValueFromStack(
            hProcess,
            Esp,
            1,
            &ulParamValue
        );
        MY_PROCESS_ERROR(nRetCode);
        switch (ulParamValue)
        {
        case HKEY_CLASSES_ROOT:
            nLogLen = sprintf(log, "删除注册表主键 HKEY_CLASSES_ROOT");
            break;
        case HKEY_CURRENT_CONFIG:
            nLogLen = sprintf(log, "删除注册表主键 HKEY_CURRENT_CONFIG");
            break;
        case HKEY_CURRENT_USER:
            nLogLen = sprintf(log, "删除注册表主键 HKEY_CURRENT_USER");
            break;
        case HKEY_LOCAL_MACHINE:
            nLogLen = sprintf(log, "删除注册表主键 HKEY_LOCAL_MACHINE");
            break;
        case HKEY_USERS:
            nLogLen = sprintf(log, "删除注册表主键 HKEY_USERS");
            break;
        case HKEY_PERFORMANCE_DATA:
            nLogLen = sprintf(log, "删除注册表主键 HKEY_PERFORMANCE_DATA");
            break;
        case HKEY_DYN_DATA:
            nLogLen = sprintf(log, "删除注册表主键 HKEY_DYN_DATA");
            break;
        default:
            nReady = 0;
            nLogLen = 0;
            break;
        }
        sprintf(log + nLogLen, "\\%s 。\n", buf1);
#ifdef _DEBUG
        printf("RegDeleteKey(): %s\n", buf1);
#endif
        break;

    case FN_REGSETVALUEEXA:
    case FN_REGSETVALUEA:
        nRetCode = GetTextFromStack(
            hProcess,
            Esp,
            2,
            MAX_PATH,
            buf1
        );
        MY_PROCESS_ERROR(nRetCode);
        nRetCode = GetTextFromStack(
            hProcess,
            Esp,
            4,
            MAX_PATH,
            buf2
        );
        MY_PROCESS_ERROR(nRetCode);
        nRetCode = GetULValueFromStack(
            hProcess,
            Esp,
            1,
            &ulParamValue
        );
        MY_PROCESS_ERROR(nRetCode);
        switch (ulParamValue)
        {
        case HKEY_CLASSES_ROOT:
            nLogLen = sprintf(log, "修改注册表键值 HKEY_CLASSES_ROOT");
            break;
        case HKEY_CURRENT_CONFIG:
            nLogLen = sprintf(log, "修改注册表键值 HKEY_CURRENT_CONFIG");
            break;
        case HKEY_CURRENT_USER:
            nLogLen = sprintf(log, "修改注册表键值 HKEY_CURRENT_USER");
            break;
        case HKEY_LOCAL_MACHINE:
            nLogLen = sprintf(log, "修改注册表键值 HKEY_LOCAL_MACHINE");
            break;
        case HKEY_USERS:
            nLogLen = sprintf(log, "修改注册表键值 HKEY_USERS");
            break;
        case HKEY_PERFORMANCE_DATA:
            nLogLen = sprintf(log, "修改注册表键值 HKEY_PERFORMANCE_DATA");
            break;
        case HKEY_DYN_DATA:
            nLogLen = sprintf(log, "修改注册表键值 HKEY_DYN_DATA");
            break;
        default:
            nReady = 0;
            nLogLen = 0;
            break;
        }
        sprintf(log + nLogLen, "\\%s 为 %s 。\n", buf1, buf2);
#ifdef _DEBUG
        printf("RegSetValue(Ex)(): %s : %s\n", buf1, buf2);
#endif
        break;
    }

    if (nReady && ('\0' != log[0]))
        AddToLogTail(log);

    nRetResult = 1;
Exit0:
    return nRetResult;
}

⌨️ 快捷键说明

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