1

我能够毫无问题地设置硬件断点(写入或读取地址)并且它也可以工作。如果我尝试从 Vectored Exception 处理程序执行相同操作,则会设置寄存器(使用 set/getThreadContext 确认),但相同的 SW 永远不会中断。地址和设置函数是相同的,我看到的唯一区别是,如果我从主代码设置断点,它可以工作;如果我从向量异常处理程序(在发生不相关异常的情况下)执行相同操作,则断点将不会产生任何影响。

应该在断点处中断的代码当然在异常处理程序之外。我在 IA32 软件手册中找不到任何相关信息。

也许你们中的一些人有这个问题。任何帮助表示赞赏。

编辑:这是一个非常粗略的例子,不要介意警告。如果使用#define DIRECT 编译,程序会因为未捕获的 SINGLE_STEP 而终止,如果编译时没有任何反应。需要明确的是,这只是一个丑陋、混乱、快速的例子。

// The following macros define the minimum required platform.  The minimum required platform
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
// your application.  The macros work by enabling all features available on platform versions up to and
// including the version specified.

// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER                          // Specifies that the minimum required platform is Windows Vista.
#define WINVER 0x0600           // Change this to the appropriate value to target other versions of Windows.
#endif

#ifndef _WIN32_WINNT            // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600     // Change this to the appropriate value to target other versions of Windows.
#endif

#ifndef _WIN32_WINDOWS          // Specifies that the minimum required platform is Windows 98.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif

#ifndef _WIN32_IE                       // Specifies that the minimum required platform is Internet Explorer 7.0.
#define _WIN32_IE 0x0700        // Change this to the appropriate value to target other versions of IE.
#endif

#include "windows.h"
#include "stdio.h"

#define DR7_CONFIG(num, lg, rw, size)   ((((rw & 3) << (16 + 4 * num)) | ((size & 3) << (18 + 4 * num))) | (lg << (2 * num)))
HANDLE mainThread;

//#define DIRECT

DWORD WINAPI LibAsilEmu_ArrayBoundsMonitor(LPVOID lpParameter)
{
    MSG msg;
    CONTEXT tcontext;
    HANDLE th;
    DWORD temp = 0;
    IMAGE_SECTION_HEADER *psec;


    th = OpenThread(THREAD_ALL_ACCESS, FALSE, mainThread);

                temp = SuspendThread(th);
                tcontext.ContextFlags = CONTEXT_DEBUG_REGISTERS;
                temp = GetThreadContext(th, &tcontext);
                tcontext.Dr6 = 0;
                tcontext.Dr0 = lpParameter;
                tcontext.Dr2 = lpParameter;
                tcontext.Dr3 = lpParameter;
                tcontext.Dr1 = lpParameter;
                tcontext.Dr7 = 0xffffffff;//DR7_CONFIG(0, 1, 2, 3) | DR7_CONFIG(1, 1, 2, 3) | 256;
                temp = SetThreadContext(th, &tcontext);
                temp = GetThreadContext(th, &tcontext);
                temp = ResumeThread(th);
    return 0;
}
HANDLE child;


unsigned int test_array[10];


LONG WINAPI LibAsilEmu_TopLevelVectoredFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
    child = CreateThread(NULL, 0x4000, LibAsilEmu_ArrayBoundsMonitor, &test_array[2], 0, NULL);
    while (WAIT_OBJECT_0 != WaitForSingleObject(child, 0));
    return EXCEPTION_CONTINUE_EXECUTION;
}

int main(void)
{
    int i;

    printf("%p\n", test_array); fflush(stdout);
    printf("sizeof %d\n", sizeof(test_array));

    mainThread = GetCurrentThreadId();

#ifdef DIRECT
    child = CreateThread(NULL, 0x4000, LibAsilEmu_ArrayBoundsMonitor, &test_array[2], 0, NULL);
    // Edit 2: the wait was missing
    while (WAIT_OBJECT_0 != WaitForSingleObject(child, 0));
#else
    AddVectoredExceptionHandler(1, &LibAsilEmu_TopLevelVectoredFilter);
    RaiseException(0,0,0,0);
#endif


    printf("thread ready\n");

    printf("ta %p\n", &(test_array[10]));
    for (i = 0; i < 15; ++i)
    {
        *((char*)test_array) += 0x25;
        test_array[i] += 0x15151515;
        printf("%2d %d %p\n", i, test_array[i], &(test_array[i])); fflush(stdout);
    }
    printf("ta %d\n", test_array[10]);
    printf("exit\n\nexit\n\n");

    return 0;
}
4

1 回答 1

1

我不知道您的问题的具体情况,因为您的描述中没有提供代码。即,它可能只是一个编码错误。因此,在没有其他信息的情况下,我只能将您指向一个链接,其中包含一些有关使用向量异常处理的示例代码 HERE 希望这会有所帮助,否则,请发布一些代码

[编辑 1]

首先,我猜你不是第一个看到这个问题的人,Vectored 异常处理自 XP 以来就已经存在。其他人肯定已经看到了。

可能不需要说它(但无论如何我会)调试器,当运行多个线程时,它们的行为与它们在单线程中的行为不同。您正在从一个单独的线程调用您的矢量异常处理程序。这似乎与从线程运行时看不到断点的事实有某种关系。你有能力将你的调试器指向一个特定的线程吗?看这里

我还有另一个建议 - 由于这个问题的真正意义是确定为什么在尝试使用 Vectored Exception Handler 时未设置您的硬件断点,请考虑将这篇文章的标题更改为:
无法使用 Vectored 设置硬件断点异常处理程序。
它可能会得到更多的关注。(我自己会这样做,但不想假设你会同意 :)

[编辑 2]

我在您的示例中看到,您正在从一个新线程main()中调用。AddVectoredExceptionHandler()但是功能

LONG WINAPI LibAsilEmu_TopLevelVectoredFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
    child = CreateThread(NULL, 0x4000, LibAsilEmu_ArrayBoundsMonitor, &test_array[2], 0, NULL);
    while (WAIT_OBJECT_0 != WaitForSingleObject(child, 0));
    return EXCEPTION_CONTINUE_EXECUTION;
}  

创建另一个新线程, LibAsilEmu_ArrayBoundsMonitor然后再次打开主线程。这对我来说似乎是一系列奇怪的事件。这段代码是您在其他地方使用过的,并与向量异常处理结合使用吗?

于 2013-10-22T14:26:10.923 回答