提问人:Leo Galante 提问时间:7/28/2023 最后编辑:Leo Galante 更新时间:7/28/2023 访问量:97
如何逐步跟踪程序?
How can I trace a program by step in?
问:
主要问题:
我正在尝试编写自己的跟踪器,但我找不到任何关于如何跟踪程序本身的材料, MSDN 中没有关于EXCEPTION_SINGLE_STEP以及如何调用它的信息。同样,据我了解,我 需要以某种方式打电话给EXCEPTION_SINGLE_STEP,但如何?在第一个EXCEPTION_BREAKPOINT异常之后,我的应用程序 只是开始并继续,直到执行其任何操作。如果我只是在每条指令之前放置一个断点,然后删除它, 那么我会不断产生EXCEPTION_BREAKPOINT,而不是EXCEPTION_SINGLE_STEP,
1)调试循环环节
我的代码:
BOOL TraceProcess(PEInformation& PEInformation)
{
DEBUG_EVENT debugEvent; Regs Regs;
bool IsRunning = true;
CONTEXT Context{}; Context.ContextFlags = CONTEXT_ALL;
HANDLE hThread;
while (IsRunning)
{
if (!WaitForDebugEvent(&debugEvent, INFINITE))
{
// Error handling
DebugActiveProcessStop(PEInformation.processInfo.dwProcessId);
return FALSE;
}
// Process the debug event based on its type
switch (debugEvent.dwDebugEventCode)
{
case EXCEPTION_DEBUG_EVENT:
switch (debugEvent.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_BREAKPOINT:
hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, debugEvent.dwThreadId);
if (!GetThreadContext(hThread, &Context))
{
std::cerr << "GetThreadContext failed: " << GetLastError() << std::endl;
break;
}
std::cout << "rip: " << std::hex << Context.Rip << std::endl;
break;
case EXCEPTION_SINGLE_STEP:
hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, debugEvent.dwThreadId);
if (!GetThreadContext(hThread, &Context))
{
std::cerr << "GetThreadContext failed: " << GetLastError() << std::endl;
break;
}
std::cout << "rip: " << std::hex << Context.Rip << std::endl;
break;
}
break;
case CREATE_THREAD_DEBUG_EVENT:
// Handle newly created threads
// Process debugEvent.u.CreateThread for detailed information
break;
case CREATE_PROCESS_DEBUG_EVENT:
// Handle newly created processes (main thread)
// Process debugEvent.u.CreateProcessInfo for detailed information
break;
case EXIT_THREAD_DEBUG_EVENT:
// Handle thread exit
// Process debugEvent.u.ExitThread for detailed information
break;
case EXIT_PROCESS_DEBUG_EVENT:
// Handle process exit
// Process debugEvent.u.ExitProcess for detailed information
DebugActiveProcessStop(PEInformation.processInfo.dwProcessId);
return TRUE;
case LOAD_DLL_DEBUG_EVENT:
// Handle DLL loading
// Process debugEvent.u.LoadDll for detailed information
break;
case UNLOAD_DLL_DEBUG_EVENT:
// Handle DLL unloading
// Process debugEvent.u.UnloadDll for detailed information
break;
case OUTPUT_DEBUG_STRING_EVENT:
// Handle output of debug strings
// Process debugEvent.u.DebugString for detailed information
break;
// Handle other debug events as needed
}
// Continue execution of the traced process
ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE);
}
return true;
}
答:
1赞
Leo Galante
7/28/2023
#1
评论中的人是很棒的人)谢谢@Wyck和@RbMm
溶液
BOOL TraceProcess()
{
DEBUG_EVENT debugEvent;
bool IsRunning = true;
CONTEXT Context{}; Context.ContextFlags = CONTEXT_ALL;
while (IsRunning)
{
if (!WaitForDebugEvent(&debugEvent, INFINITE))
{
// Error handling
DebugActiveProcessStop(debugEvent.dwProcessId);
return FALSE;
}
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, debugEvent.dwThreadId);
if (!hThread) { std::cerr << "hThread is NULL" << std::endl; return false; }
// Process the debug event based on its type
switch (debugEvent.dwDebugEventCode)
{
case EXCEPTION_DEBUG_EVENT:
switch (debugEvent.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_BREAKPOINT:
if (!GetThreadContext(hThread, &Context))
{
std::cerr << "GetThreadContext failed: " << GetLastError() << std::endl;
break;
}
Context.EFlags |= 0x100;
if (!SetThreadContext(hThread, &Context))
{
std::cerr << "SetThreadContext failed: " << GetLastError() << std::endl;
break;
}
std::cout << "rip: " << std::hex << Context.Rip << std::endl;
CloseHandle(hThread);
break;
case EXCEPTION_SINGLE_STEP:
if (!GetThreadContext(hThread, &Context))
{
std::cerr << "GetThreadContext failed: " << GetLastError() << std::endl;
break;
}
std::bitset<32> flags(Context.EFlags);
if (!flags[8])
{
Context.EFlags |= 0x100;
if (!SetThreadContext(hThread, &Context))
{
std::cerr << "SetThreadContext failed: " << GetLastError() << std::endl;
break;
}
}
CloseHandle(hThread);
break;
}
break;
case CREATE_THREAD_DEBUG_EVENT:
// Handle newly created threads
// Process debugEvent.u.CreateThread for detailed information
break;
case CREATE_PROCESS_DEBUG_EVENT:
// Handle newly created processes (main thread)
// Process debugEvent.u.CreateProcessInfo for detailed information
break;
case EXIT_THREAD_DEBUG_EVENT:
// Handle thread exit
// Process debugEvent.u.ExitThread for detailed information
break;
case EXIT_PROCESS_DEBUG_EVENT:
// Handle process exit
// Process debugEvent.u.ExitProcess for detailed information
DebugActiveProcessStop(debugEvent.dwProcessId);
return TRUE;
case LOAD_DLL_DEBUG_EVENT:
// Handle DLL loading
// Process debugEvent.u.LoadDll for detailed information
break;
case UNLOAD_DLL_DEBUG_EVENT:
// Handle DLL unloading
// Process debugEvent.u.UnloadDll for detailed information
break;
case OUTPUT_DEBUG_STRING_EVENT:
// Handle output of debug strings
// Process debugEvent.u.DebugString for detailed information
break;
// Handle other debug events as needed
}
// Continue execution of the traced process
ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE);
}
return true;
}
评论
0赞
Ben Voigt
7/28/2023
不要用于位操作,你不想要进位。使用按位 OR ( 和复合赋值版本+
|
|=
)
0赞
Ben Voigt
7/28/2023
此外,您到处都在泄漏螺纹手柄。打开线程一次,根据需要多次使用句柄,然后调用 。CloseHandle
0赞
Leo Galante
7/28/2023
@BenVoigt 谢谢!据我了解,debugEvent.dwThreadId 具有发生某些事件的 id,因此,它不能只获得一次,因为在应用程序运行期间,在多线程应用程序的情况下,它的“工作”线程可能会发生变化
0赞
500 - Internal Server Error
7/28/2023
狮子座,你是在回复@BenVoigt删除的评论吗?因为他是对的,你需要关闭那些你打开的线程句柄,否则你很快就会用完。--- 好消息是,您首先不需要打开这些句柄:Thread Create 事件为您提供了线程的句柄。您只需要将其存储在某个查找结构中,以便可以从其他调试事件中给出的线程 ID 中找到它。
上一个:仅在调试模式下发生异常
评论
EXCEPTION_SINGLE_STEP
在 2 种情况下:1.) 如果 EFlags (0x100) 2.) ,则设置 TF你 ser DRx bp