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; }