www.pudn.com > PEMonitor_0.10_src.zip > BreakPointServ.c


/////////////////////////////////////////////////////////////////////////////// 
// 
//  FileName    :   BreakPointServ.c 
//  Version     :   0.10 
//  Author      :   Luo Cong 
//  Date        :   2004-09-02 (yyyy-mm-dd) 
//  Comment     : 
// 
/////////////////////////////////////////////////////////////////////////////// 
 
#include  
#include  
#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; 
}