COM接口应用和引起的User breakpoint called from code at 0x7c92120e

本文探讨了在使用COM接口时遇到的Userbreakpoint错误,分析了错误原因并提供了解决方案。通过实例展示了如何正确地管理和释放COM接口资源,避免崩溃问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

COM接口应用和引起的User breakpoint called from code at 0x7c92120e
第一:在一个基类中,我定义了一个接口ISelf,使用过程中通过其它接口的某个函数返回了ISelf接口;
释放时,我调用.Release();
第二:最近系统引起崩溃,我就怀疑到这个接口上,于是我在基类的构造函数中为ISelf接口分配了内存,
m_ISelf = (ISelf*)CoTaskMemAlloc(sizeof(ISelf));
在析构函数中做了一个释放动作:
m_ISelf.Release();
CoTaskMemFree(m_ISelf); //执行到它,就会弹出一个 "Mircrosof Visual C++" “User breakpoint called from code at 0x7c92120e”
第三:后来我又把申请和释放去掉了,导致崩溃不是这方面的错
#include <stdio.h> // 添加printf支持 #include <windows.h> BOOL SetBreakPoint(PVOID pFuncAddr); BOOL ClearBreakPoint(PVOID pFuncAddr); BOOL InstallVEHHook(PVECTORED_EXCEPTION_HANDLER Handler); VOID UnInstallVEHHook(); typedef int (WINAPI* PFN_MessageBox)( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ); int WINAPI My_MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ); LONG WINAPI VectoredHandler1(struct _EXCEPTION_POINTERS* ExceptionInfo); LONG WINAPI VectoredHandler2(struct _EXCEPTION_POINTERS* ExceptionInfo); LONG WINAPI VectoredHandler3(struct _EXCEPTION_POINTERS* ExceptionInfo); VOID ShowMsgBox(LPCTSTR lpMsg); ULONG_PTR InitTrampolineFun(); PFN_MessageBox g_OriginalMessageBoxA; PVOID g_AddrofMessageBoxA = 0; PVOID g_hVector; BYTE g_OldCode[16] = { 0 }; int main(int argc, char* argv[]) { HMODULE hUser32 = LoadLibrary("user32.dll"); g_AddrofMessageBoxA = (PVOID)GetProcAddress(hUser32, "MessageBoxA"); printf("Address of MessageBoxA = 0x%p\n", g_AddrofMessageBoxA); g_OriginalMessageBoxA = (PFN_MessageBox)InitTrampolineFun(); //跳过开头的Hook printf("Addr of VectoredHandler1 = 0x%p\n", VectoredHandler1); printf("Addr of VectoredHandler2 = 0x%p\n", VectoredHandler2); printf("Addr of VectoredHandler3 = 0x%p\n", VectoredHandler3); //选择安装一个进行测试 InstallVEHHook(VectoredHandler1); //设置断点 SetBreakPoint(g_AddrofMessageBoxA); //call ShowMsgBox("VEH Hook Test."); printf("All Finished!\n"); ClearBreakPoint(g_AddrofMessageBoxA); UnInstallVEHHook(); ShowMsgBox("Hook Cleared"); return 0; } VOID ShowMsgBox(LPCTSTR lpMsg) { MessageBoxA(NULL, lpMsg, "Test", MB_OK); } ULONG_PTR InitTrampolineFun() { ULONG_PTR uResult = 0; PBYTE pFun = NULL; #ifdef _WIN64 //x64需要申请shellcode /* USER32!MessageBoxA: 00000000`779412b8 4883ec38 sub rsp,38h 00000000`779412bc 4533db xor r11d,r11d 00000000`779412bf 44391d760e0200 cmp dword ptr [USER32!gapfnScSendMessage+0x927c (00000000`7796213c)],r11d */ pFun = (PBYTE)VirtualAlloc(NULL, 128, MEM_COMMIT, PAGE_EXECUTE_READWRITE); uResult = (ULONG_PTR)pFun; memset(pFun, 0, 128); memcpy(pFun, (PVOID)g_AddrofMessageBoxA, 4); //拷贝第一条指令,4字节,推荐使用反汇编引擎来实际计算 pFun += 4; //下一条指令构造为jmp [xxxxxx] pFun[0] = 0xFF; pFun[1] = 0x25; *(ULONG_PTR*)(pFun + 6) = (ULONG_PTR)g_AddrofMessageBoxA + 4; //跳回到原函数加4的地方 #else //x86,第一条指令是mov edi,edi,直接跳过即可 uResult = (ULONG_PTR)g_AddrofMessageBoxA + 2; #endif return uResult; } //处理方式,修改参数并返回原函数继续执行 LONG WINAPI VectoredHandler1( struct _EXCEPTION_POINTERS* ExceptionInfo ) { const char* szNewMsg = "[VectoredHandler1] Hacked by pediy.com"; LONG lResult = EXCEPTION_CONTINUE_SEARCH; PEXCEPTION_RECORD pExceptionRecord; PCONTEXT pContextRecord; int ret = 0; pExceptionRecord = ExceptionInfo->ExceptionRecord; pContextRecord = ExceptionInfo->ContextRecord; ULONG_PTR* uESP = 0; printf("Exception Address = %p\n", pExceptionRecord->ExceptionAddress); if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { #ifdef _WIN64 //x64上前四个参数依次为RCX,RDX,R8,R9 //修改第二个参数,即LpMsg printf("lpText = 0x%p %s\n", pContextRecord->Rdx, (char*)pContextRecord->Rdx); pContextRecord->Rdx = (ULONG_PTR)szNewMsg; pContextRecord->Rip = (ULONG_PTR)g_OriginalMessageBoxA; //跳到Trampoline继续执行 #else /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ printf("ESP = 0x%p\n", pContextRecord->Esp); uESP = (ULONG_PTR*)pContextRecord->Esp; //取中断时的ESP uESP[2] = (ULONG_PTR)szNewMsg; //修改栈中的参数 pContextRecord->Eip = (ULONG_PTR)g_OriginalMessageBoxA; //跳过函数开头 #endif lResult = EXCEPTION_CONTINUE_EXECUTION; } return lResult; } //处理方式:直接调用原函数并替原函数返回 LONG WINAPI VectoredHandler2( struct _EXCEPTION_POINTERS* ExceptionInfo ) { const char* szNewMsg = "[VectoredHandler2] Hacked by pediy.com"; LONG lResult = EXCEPTION_CONTINUE_SEARCH; PEXCEPTION_RECORD pExceptionRecord; PCONTEXT pContextRecord; int ret = 0; pExceptionRecord = ExceptionInfo->ExceptionRecord; pContextRecord = ExceptionInfo->ContextRecord; ULONG_PTR* uESP = 0; if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { #ifdef _WIN64 //x64上前四个参数依次为RCX,RDX,R8,R9 printf("RSP = 0x%p\n", pContextRecord->Rsp); uESP = (ULONG_PTR*)pContextRecord->Rsp; printf("Return Address = 0x%p\n", uESP[0]); ret = g_OriginalMessageBoxA((HWND)pContextRecord->Rcx, szNewMsg, (LPCTSTR)pContextRecord->R8, (int)pContextRecord->R9); printf("ret = %d\n", ret); //修正RSP pContextRecord->Rsp += sizeof(ULONG_PTR);//参数在寄存器中,栈中无参数,仅需跳过返回地址 //直接返回到调用者处 pContextRecord->Rip = uESP[0];//设置EIP为返回地址 #else /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ printf("ESP = 0x%p\n", pContextRecord->Esp); uESP = (ULONG_PTR*)pContextRecord->Esp; ret = g_OriginalMessageBoxA((HWND)uESP[1], szNewMsg, (LPCTSTR)uESP[3], (int)uESP[4]); printf("ret = %d\n", ret); //直接返回到调用者处 pContextRecord->Eip = uESP[0];//设置EIP为返回地址 pContextRecord->Esp += (4 + 1) * sizeof(ULONG_PTR); //4为参数个数,1为返回地址 #endif lResult = EXCEPTION_CONTINUE_EXECUTION; } return lResult; } //处理方式:直接返回,相当于过滤掉 LONG WINAPI VectoredHandler3( struct _EXCEPTION_POINTERS* ExceptionInfo ) { LONG lResult = EXCEPTION_CONTINUE_SEARCH; PEXCEPTION_RECORD pExceptionRecord = ExceptionInfo->ExceptionRecord; PCONTEXT pContextRecord = ExceptionInfo->ContextRecord; ULONG_PTR* uESP = 0; if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ //直接返回到调用者处 #ifdef _WIN64 printf("RSP = 0x%p\n", pContextRecord->Rsp); uESP = (ULONG_PTR*)pContextRecord->Rsp; pContextRecord->Rip = uESP[0];//设置EIP为返回地址 pContextRecord->Rsp += sizeof(ULONG_PTR); //将压入栈内的参数返回地址清理掉,4为参数个数,1为返回地址 #else printf("ESP = 0x%X\n", pContextRecord->Esp); uESP = (ULONG_PTR*)pContextRecord->Esp; pContextRecord->Eip = uESP[0];//设置EIP为返回地址 pContextRecord->Esp += (4 + 1) * sizeof(ULONG_PTR); //将压入栈内的参数返回地址清理掉,4为参数个数,1为返回地址 #endif lResult = EXCEPTION_CONTINUE_EXECUTION; } return lResult; } BOOL InstallVEHHook(PVECTORED_EXCEPTION_HANDLER Handler) { printf("Current Handler Address = 0x%p\n", Handler); g_hVector = AddVectoredExceptionHandler(1, Handler); return g_hVector != NULL; } VOID UnInstallVEHHook() { RemoveVectoredExceptionHandler(g_hVector); } /* 0:000> u user32!messageboxA USER32!MessageBoxA: 77d507ea 8bff mov edi,edi 77d507ec 55 push ebp 77d507ed 8bec mov ebp,esp */ BOOL SetBreakPoint(PVOID pFuncAddr) { DWORD dwCnt = 0; BYTE* pTarget = (BYTE*)pFuncAddr; g_OldCode[0] = *pTarget; printf("Original Fun Head Code = 0x%02X\n", g_OldCode[0]); //修改内存页的属性 DWORD dwOLD; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pTarget, &mbi, sizeof(mbi)); VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &dwOLD); //写入int3 *pTarget = 0xCC; //恢复内存页的属性 VirtualProtect(mbi.BaseAddress, mbi.RegionSize, dwOLD, 0); return TRUE; } BOOL ClearBreakPoint(PVOID pFuncAddr) { BYTE* pTarget = (BYTE*)pFuncAddr; //修改内存页的属性 DWORD dwOLD; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pTarget, &mbi, sizeof(mbi)); VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &dwOLD); *pTarget = g_OldCode[0]; //恢复内存页的属性 VirtualProtect(mbi.BaseAddress, mbi.RegionSize, dwOLD, 0); return TRUE; } int WINAPI My_MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ) { char newMsg[400]; char newCation[] = "标题被我改了!"; int result; if (lpText) { ZeroMemory(newMsg, 400); lstrcpy(newMsg, lpText); lstrcat(newMsg, "\n\tMessage Box hacked by pediy.com"); } printf("有人调用MessageBox...\n"); result = g_OriginalMessageBoxA(hWnd, newMsg, newCation, uType); return result; }系统版本是win10 10240
最新发布
07-25
#include "stdafx.h" #include <windows.h> BOOL SetBreakPoint(PVOID pFuncAddr); BOOL ClearBreakPoint(PVOID pFuncAddr); BOOL InstallVEHHook(PVECTORED_EXCEPTION_HANDLER Handler); VOID UnInstallVEHHook(); typedef int (WINAPI* PFN_MessageBox)( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ); int WINAPI My_MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ); LONG WINAPI VectoredHandler1(struct _EXCEPTION_POINTERS* ExceptionInfo); LONG WINAPI VectoredHandler2(struct _EXCEPTION_POINTERS* ExceptionInfo); LONG WINAPI VectoredHandler3(struct _EXCEPTION_POINTERS* ExceptionInfo); VOID ShowMsgBox(LPCTSTR lpMsg); ULONG_PTR InitTrampolineFun(); PFN_MessageBox g_OriginalMessageBoxA; PVOID g_AddrofMessageBoxA = 0; PVOID g_hVector; BYTE g_OldCode[16] = { 0 }; int main(int argc, char* argv[]) { HMODULE hUser32 = LoadLibrary("user32.dll"); g_AddrofMessageBoxA = (PVOID)GetProcAddress(hUser32, "MessageBoxA"); printf("Address of MessageBoxA = 0x%p\n", g_AddrofMessageBoxA); g_OriginalMessageBoxA = (PFN_MessageBox)InitTrampolineFun(); //跳过开头的Hook printf("Addr of VectoredHandler1 = 0x%p\n", VectoredHandler1); printf("Addr of VectoredHandler2 = 0x%p\n", VectoredHandler2); printf("Addr of VectoredHandler3 = 0x%p\n", VectoredHandler3); //选择安装一个进行测试 InstallVEHHook(VectoredHandler1); //设置断点 SetBreakPoint(g_AddrofMessageBoxA); //call ShowMsgBox("VEH Hook Test."); printf("All Finished!\n"); ClearBreakPoint(g_AddrofMessageBoxA); UnInstallVEHHook(); ShowMsgBox("Hook Cleared"); return 0; } VOID ShowMsgBox(LPCTSTR lpMsg) { MessageBoxA(NULL, lpMsg, "Test", MB_OK); } ULONG_PTR InitTrampolineFun() { ULONG_PTR uResult = 0; PBYTE pFun = NULL; #ifdef _WIN64 //x64需要申请shellcode /* USER32!MessageBoxA: 00000000`779412b8 4883ec38 sub rsp,38h 00000000`779412bc 4533db xor r11d,r11d 00000000`779412bf 44391d760e0200 cmp dword ptr [USER32!gapfnScSendMessage+0x927c (00000000`7796213c)],r11d */ pFun = (PBYTE)VirtualAlloc(NULL, 128, MEM_COMMIT, PAGE_EXECUTE_READWRITE); uResult = (ULONG_PTR)pFun; memset(pFun, 0, 128); memcpy(pFun, (PVOID)g_AddrofMessageBoxA, 4); //拷贝第一条指令,4字节,推荐使用反汇编引擎来实际计算 pFun += 4; //下一条指令构造为jmp [xxxxxx] pFun[0] = 0xFF; pFun[1] = 0x25; *(ULONG_PTR*)(pFun + 6) = (ULONG_PTR)g_AddrofMessageBoxA + 4; //跳回到原函数加4的地方 #else //x86,第一条指令是mov edi,edi,直接跳过即可 uResult = (ULONG_PTR)g_AddrofMessageBoxA + 2; #endif return uResult; } //处理方式,修改参数并返回原函数继续执行 LONG WINAPI VectoredHandler1( struct _EXCEPTION_POINTERS* ExceptionInfo ) { char* szNewMsg = "[VectoredHandler1] Hacked by pediy.com"; LONG lResult = EXCEPTION_CONTINUE_SEARCH; PEXCEPTION_RECORD pExceptionRecord; PCONTEXT pContextRecord; int ret = 0; pExceptionRecord = ExceptionInfo->ExceptionRecord; pContextRecord = ExceptionInfo->ContextRecord; ULONG_PTR* uESP = 0; printf("Exception Address = %p\n", pExceptionRecord->ExceptionAddress); if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { #ifdef _WIN64 //x64上前四个参数依次为RCX,RDX,R8,R9 //修改第二个参数,即LpMsg printf("lpText = 0x%p %s\n", pContextRecord->Rdx, (char*)pContextRecord->Rdx); pContextRecord->Rdx = (ULONG_PTR)szNewMsg; pContextRecord->Rip = (ULONG_PTR)g_OriginalMessageBoxA; //跳到Trampoline继续执行 #else /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ printf("ESP = 0x%p\n", pContextRecord->Esp); uESP = (ULONG_PTR*)pContextRecord->Esp; //取中断时的ESP uESP[2] = (ULONG_PTR)szNewMsg; //修改栈中的参数 pContextRecord->Eip = (ULONG_PTR)g_OriginalMessageBoxA; //跳过函数开头 #endif lResult = EXCEPTION_CONTINUE_EXECUTION; } return lResult; } //处理方式:直接调用原函数并替原函数返回 LONG WINAPI VectoredHandler2( struct _EXCEPTION_POINTERS* ExceptionInfo ) { char* szNewMsg = "[VectoredHandler2] Hacked by pediy.com"; LONG lResult = EXCEPTION_CONTINUE_SEARCH; PEXCEPTION_RECORD pExceptionRecord; PCONTEXT pContextRecord; int ret = 0; pExceptionRecord = ExceptionInfo->ExceptionRecord; pContextRecord = ExceptionInfo->ContextRecord; ULONG_PTR* uESP = 0; if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { #ifdef _WIN64 //x64上前四个参数依次为RCX,RDX,R8,R9 printf("RSP = 0x%p\n", pContextRecord->Rsp); uESP = (ULONG_PTR*)pContextRecord->Rsp; printf("Return Address = 0x%p\n", uESP[0]); ret = g_OriginalMessageBoxA((HWND)pContextRecord->Rcx, szNewMsg, (LPCTSTR)pContextRecord->R8, (int)pContextRecord->R9); printf("ret = %d\n", ret); //修正RSP pContextRecord->Rsp += sizeof(ULONG_PTR);//参数在寄存器中,栈中无参数,仅需跳过返回地址 //直接返回到调用者处 pContextRecord->Rip = uESP[0];//设置EIP为返回地址 #else /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ printf("ESP = 0x%p\n", pContextRecord->Esp); uESP = (ULONG_PTR*)pContextRecord->Esp; ret = g_OriginalMessageBoxA((HWND)uESP[1], szNewMsg, (LPCTSTR)uESP[3], (int)uESP[4]); printf("ret = %d\n", ret); //直接返回到调用者处 pContextRecord->Eip = uESP[0];//设置EIP为返回地址 pContextRecord->Esp += (4 + 1) * sizeof(ULONG_PTR); //4为参数个数,1为返回地址 #endif lResult = EXCEPTION_CONTINUE_EXECUTION; } return lResult; } //处理方式:直接返回,相当于过滤掉 LONG WINAPI VectoredHandler3( struct _EXCEPTION_POINTERS* ExceptionInfo ) { LONG lResult = EXCEPTION_CONTINUE_SEARCH; PEXCEPTION_RECORD pExceptionRecord = ExceptionInfo->ExceptionRecord; PCONTEXT pContextRecord = ExceptionInfo->ContextRecord; ULONG_PTR* uESP = 0; if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ //直接返回到调用者处 #ifdef _WIN64 printf("RSP = 0x%p\n", pContextRecord->Rsp); uESP = (ULONG_PTR*)pContextRecord->Rsp; pContextRecord->Rip = uESP[0];//设置EIP为返回地址 pContextRecord->Rsp += sizeof(ULONG_PTR); //将压入栈内的参数返回地址清理掉,4为参数个数,1为返回地址 #else printf("ESP = 0x%X\n", pContextRecord->Esp); uESP = (ULONG_PTR*)pContextRecord->Esp; pContextRecord->Eip = uESP[0];//设置EIP为返回地址 pContextRecord->Esp += (4 + 1) * sizeof(ULONG_PTR); //将压入栈内的参数返回地址清理掉,4为参数个数,1为返回地址 #endif lResult = EXCEPTION_CONTINUE_EXECUTION; } return lResult; } BOOL InstallVEHHook(PVECTORED_EXCEPTION_HANDLER Handler) { printf("Current Handler Address = 0x%p\n", Handler); g_hVector = AddVectoredExceptionHandler(1, Handler); return g_hVector != NULL; } VOID UnInstallVEHHook() { RemoveVectoredExceptionHandler(g_hVector); } /* 0:000> u user32!messageboxA USER32!MessageBoxA: 77d507ea 8bff mov edi,edi 77d507ec 55 push ebp 77d507ed 8bec mov ebp,esp */ BOOL SetBreakPoint(PVOID pFuncAddr) { DWORD dwCnt = 0; BYTE* pTarget = (BYTE*)pFuncAddr; g_OldCode[0] = *pTarget; printf("Original Fun Head Code = 0x%02X\n", g_OldCode[0]); //修改内存页的属性 DWORD dwOLD; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pTarget, &mbi, sizeof(mbi)); VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &dwOLD); //写入int3 *pTarget = 0xCC; //恢复内存页的属性 VirtualProtect(mbi.BaseAddress, mbi.RegionSize, dwOLD, 0); return TRUE; } BOOL ClearBreakPoint(PVOID pFuncAddr) { BYTE* pTarget = (BYTE*)pFuncAddr; //修改内存页的属性 DWORD dwOLD; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pTarget, &mbi, sizeof(mbi)); VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &dwOLD); *pTarget = g_OldCode[0]; //恢复内存页的属性 VirtualProtect(mbi.BaseAddress, mbi.RegionSize, dwOLD, 0); return TRUE; } int WINAPI My_MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ) { char newMsg[400]; char newCation[] = "标题被我改了!"; int result; if (lpText) { ZeroMemory(newMsg, 400); lstrcpy(newMsg, lpText); lstrcat(newMsg, "\n\tMessage Box hacked by pediy.com"); } printf("有人调用MessageBox...\n"); result = g_OriginalMessageBoxA(hWnd, newMsg, newCation, uType); return result; }严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误(活动) E0020 未定义标识符 "printf" veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 41 错误(活动) E0020 未定义标识符 "printf" veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 116 错误(活动) E0020 未定义标识符 "printf" veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 166 错误(活动) E0020 未定义标识符 "printf" veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 225 错误(活动) E0020 未定义标识符 "printf" veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 243 错误(活动) E0020 未定义标识符 "printf" veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 267 错误(活动) E0020 未定义标识符 "printf" veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 314 错误 C1083 无法打开包括文件: “stdafx.h”: No such file or directory veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 3 错误(活动) E1696 无法打开 源 文件 "stdafx.h" veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 3 错误(活动) E0167 "LPCTSTR" (aka "const WCHAR *") 类型的实参与 "LPCSTR" (aka "const CHAR *") 类型的形参不兼容 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 68 错误(活动) E0167 "const char *" 类型的实参与 "LPCWSTR" (aka "const WCHAR *") 类型的形参不兼容 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 39 错误(活动) E0167 "const char *" 类型的实参与 "LPCWSTR" (aka "const WCHAR *") 类型的形参不兼容 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 312 错误(活动) E0167 "const char *" 类型的实参与 "LPCTSTR" (aka "const WCHAR *") 类型的形参不兼容 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 55 错误(活动) E0167 "const char *" 类型的实参与 "LPCTSTR" (aka "const WCHAR *") 类型的形参不兼容 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 62 错误(活动) E0144 "const char *" 类型的值不能用于初始化 "char *" 类型的实体 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 108 错误(活动) E0144 "const char *" 类型的值不能用于初始化 "char *" 类型的实体 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 152 错误(活动) E0167 "char *" 类型的实参与 "LPWSTR" (aka "wchar_t *") 类型的形参不兼容 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 311 错误(活动) E0167 "char *" 类型的实参与 "LPWSTR" (aka "wchar_t *") 类型的形参不兼容 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 312 错误(活动) E0167 "char *" 类型的实参与 "LPCTSTR" (aka "const WCHAR *") 类型的形参不兼容 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 169 错误(活动) E0167 "char *" 类型的实参与 "LPCTSTR" (aka "const WCHAR *") 类型的形参不兼容 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 315 错误(活动) E0167 "char *" 类型的实参与 "LPCTSTR" (aka "const WCHAR *") 类型的形参不兼容 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 315
07-25
<think>好的,我现在要解决的问题是用户遇到的调试问题:“Skipped breakpoint at com.mindskip.wdd.controller.EmailController:164 because of stepping in another thread”。首先,我需要理解这个错误信息的具体含义。 这个信息看起来是在调试过程中出现的,可能是在使用IntelliJ IDEA或者类似的IDE。当调试多线程应用时,如果在一个线程中设置了断点,但调试器在另一个线程中单步执行,就可能导致断点被跳过。因为调试器通常只能跟踪当前线程的执行,而其他线程中的断点可能不会被触发,尤其是在单步执行时。 接下来,我需要分析可能的原因。首先,用户可能是在调试多线程应用程序,比如使用Java的Spring框架,EmailController可能处理邮件发送,而邮件发送通常会是异步的,可能使用了新线程或者线程池。当在EmailController的第164行设置断点时,如果该行代码是在另一个线程中执行的,而调试器当前在主线程或其他线程中进行单步调试,那么这个断点可能不会被命中,导致提示信息出现。 可能的解决方案有几个方向:首先,确认代码是否真的执行到了那个断点所在的线程。可能需要检查代码逻辑,确保该行代码会被执行。其次,调整调试器的设置,比如在IDE中设置所有线程都暂停,而不仅仅是当前线程。此外,还可以尝试使用条件断点或者日志输出,来确认代码的执行情况。 另外,用户可能需要了解多线程调试的注意事项,比如线程的启动执行时机,以及如何在不同线程之间切换查看状态。如果断点所在的代码是在异步任务中,可能需要等待异步任务执行到该点时才会触发断点,而如果在单步执行其他线程时,调试器可能不会自动切换到那个线程,导致断点被跳过。 还要考虑IDE的特定设置,例如在IntelliJ IDEA中,有一个“Suspend”策略,可以设置为“All”而不是“Thread”,这样当任何线程遇到断点时,整个程序都会暂停,这样可能更容易捕获多线程中的断点。此外,检查是否有断点被禁用或条件设置不当的情况。 可能的误解是用户可能认为断点没有被触发是因为代码没有执行到,但实际原因可能是由于调试器在另一个线程中单步执行,导致断点所在的线程没有被监控到。因此,需要教育用户关于多线程调试的基本概念调试器的行为。 总结一下,回答用户时需要分步骤解释错误的原因,可能的解决方案,以及如何调整调试策略来处理多线程环境中的断点问题。同时,提供具体的操作步骤,比如修改IDE的挂起策略,使用日志辅助调试,或者确保断点所在的线程会被正确执行。</think>你在调试多线程程序时遇到了 **"Skipped breakpoint at com.mindskip.wdd.controller.EmailController:164 because of stepping in another thread"** 的提示,这意味着调试器无法在指定断点处暂停程序,原因与多线程执行有关。以下是详细解释解决方法: --- ### **原因分析** 1. **多线程环境** 你的代码(例如 `EmailController` 第164行)可能运行在一个子线程中(如异步任务、线程池任务、定时任务等),而调试时你正在主线程或其他线程中进行单步调试(Step Over/Into)。调试器默认只会跟踪当前线程的执行流,其他线程的断点可能被跳过。 2. **线程切换导致断点失效** 当调试器在某个线程中暂停时(例如主线程),其他线程可能仍在后台运行。如果断点设置在子线程的代码路径上,而调试器未在该线程中暂停,则会提示断点被跳过。 --- ### **解决方法** #### 1. **调整断点挂起策略(推荐)** - **在 IntelliJ IDEA 中**: 1. 右键点击断点。 2. 将 **Suspend** 从默认的 `Thread` 改为 `All`。 3. 勾选 **Make default**(可选,设为未来断点的默认行为)。 - **效果**:任何线程触发该断点时,所有线程都会暂停,方便你观察跨线程的代码逻辑。 ![IntelliJ 断点设置](https://resources.jetbrains.com/help/img/idea/2023.1/breakpoint_suspend_policy.png) #### 2. **强制切换到目标线程** - 当程序因其他断点暂停时: 1. 打开调试器的 **Threads** 面板(通常在调试窗口的底部)。 2. 找到执行到 `EmailController:164` 的线程(如 `pool-1-thread-1`)。 3. 右键该线程并选择 **Suspend**,手动暂停它以触发断点。 #### 3. **添加线程日志辅助调试** 如果断点难以触发,可以在代码中添加日志输出,确认子线程是否执行到目标位置: ```java // 在 EmailController 第164行附近添加日志 log.debug("Reached line
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值