Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ win 7上是否可设置单步陷阱?_C++_Windows_Winapi_Visual C++_Hook - Fatal编程技术网

C++ win 7上是否可设置单步陷阱?

C++ win 7上是否可设置单步陷阱?,c++,windows,winapi,visual-c++,hook,C++,Windows,Winapi,Visual C++,Hook,我在做一个所谓的“seh hooking”。实际上,它更改了内存区域的权限,并在访问异常时捕获异常,从而可以钩住函数 它使用单步陷阱,看起来像: info->ContextRecord->EFlags |= 0x100; 要将保护恢复到页面,\u NOACCESS 该应用程序在win xp上运行良好,但在win 7上不例外。在第七场比赛中它被冻结了。我高度怀疑这是因为“设置单步陷阱”的事情,但我不确定 到源程序包的直接下载链接简短回答: 是的,单步标志是x86架构的一部分,并且仍然

我在做一个所谓的“seh hooking”。实际上,它更改了内存区域的权限,并在访问异常时捕获异常,从而可以钩住函数

它使用单步陷阱,看起来像:

info->ContextRecord->EFlags |= 0x100;
要将保护恢复到
页面,\u NOACCESS

该应用程序在win xp上运行良好,但在win 7上不例外。在第七场比赛中它被冻结了。我高度怀疑这是因为“设置单步陷阱”的事情,但我不确定

到源程序包的直接下载链接

简短回答:

是的,单步标志是x86架构的一部分,并且仍然通过处理器上下文的eflags组件在windows 7中实现

我已经设法下载了你的项目,在关闭UAC的情况下,在Windows8上,一切都可以正常运行。因此,它也应该适用于Windows7。启动
VEH Hooking Test.exe
时,它会显示两个消息框,在每个消息框之后,我都会得到
MessageBoxA
控制台输出,因此钩子工作了。也许可以尝试在Windows 7上以管理员身份启动该程序


长答覆:

SEH
代表结构化异常处理,但您所描述的内容听起来更像是
VEH
-向量化异常处理

VEH钩子是一种非常慢的钩子方法,因此它不能真正用于性能关键型钩子,例如图形钩子,其中钩子每秒命中多次。它通常用于一次性挂钩。勾车的目的是为了真正的隐蔽。没有用别人的代码编写的内存,您不必使用调试寄存器


下面是我将如何使用C++实现.< /P> 首先,您必须注册一个向量异常处理程序。这是进程的全局异常处理程序。此处理程序将捕获每个未经处理并将进入操作系统的抛出异常

PVOID pExHandler = AddVectoredExceptionHandler(1, VectoredHandler);
在此之后,您应该设置
HOOK\u位置(HOOK地址)所在页面的内存保护。我使用的新保护是
PAGE\u EXECUTE\u READ | PAGE\u GUARD
。受保护的页面将导致访问异常,并在访问异常后自动删除保护。这个异常不会由任何人处理,因此它将由我们的向量化处理程序处理。抛出异常后,可以再次访问该页面。(见附件)

只能在页中保护内存(通常为0x1000字节长)。这就是为什么我们不能只保护钩子的位置,并有巨大的性能开销

DWORD orgProt;
VirtualProtect(HOOK_LOCATION, 1, PAGE_EXECUTE_READ|PAGE_GUARD, &orgProt);
现在来看我们的异常处理程序。这就是它的样子:

LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS exc)
{
    if (exc->ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION)
    {
        // guard page exeption occured. guard page protection is gone now

        if (HOOK_LOCATION == reinterpret_cast<long*>(exc->ContextRecord->Eip)) {
            // hook location was hit! call any hook callbacks here
        } else {
            // hook was not hit and has to be refreshed. set single-step flag
            exc->ContextRecord->EFlags |= 0x100;
        }

        return EXCEPTION_CONTINUE_EXECUTION;
    }

    if (exc->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP)
    {
        // single-step exeption occured. single-step flag is cleared now

        // set guard page protection
        DWORD oldProt;
        VirtualProtect(HOOK_LOCATION, 1, PAGE_EXECUTE_READ|PAGE_GUARD, &oldProt);

        return EXCEPTION_CONTINUE_EXECUTION;
    }

    return EXCEPTION_CONTINUE_SEARCH;
}
长回调向量句柄(PEXCEPTION\u指针exc)
{
如果(exc->ExceptionRecord->ExceptionCode==状态\保护\页面\违规)
{
//发生保护页验证。保护页保护现在已取消
if(HOOK\u LOCATION==reinterpret\u cast(exc->ContextRecord->Eip)){
//钩子位置被击中!在这里调用任何钩子回调
}否则{
//钩子未命中,必须刷新。请设置单步标志
exc->ContextRecord->EFlags |=0x100;
}
返回异常\继续\执行;
}
如果(exc->ExceptionRecord->ExceptionCode==STATUS\u SINGLE\u STEP)
{
//发生单步执行。单步标志现在已清除
//设置保护页保护
德沃德·奥尔德普洛特;
虚拟保护(钩子位置,1,执行页面,读取页面,保护页面和旧保护);
返回异常\继续\执行;
}
返回异常\u继续\u搜索;
}
如果代码运行到受保护的内存页,它将抛出保护页冲突。我们检查是否在钩子的位置。如果一切正常,我们可以调用钩子回调。如果我们不在正确的位置,我们不知何故需要重新保护代码,但如果我们现在就这样做,我们就无法前进,并且总是在同一位置上出现异常并使应用程序死锁。因此,我们设置了处理器单步标志

现在,当接收到单步异常时,我们可以再次设置保护,因为我们按一条指令前进。这就是我们如何始终保护目标页面,并且不会错过任何钩子命中

代价是在目标页中执行的每条指令有两个异常和一个页面保护。不要试图在附加了调试器的情况下执行此操作。它会发疯的

对于实际的实现,您可能需要同步对象来摆脱钩子,而不会使程序崩溃,并更好地管理钩子


我真的很喜欢这个聪明的机制,希望有人能对它有所了解。

只需以正常的方式连接函数即可。这些疯狂的技术很可能会将你的代码标记为恶意软件。你是以管理员身份启动该程序的吗?Windows 7添加了一个securi。。程序权限的烦恼级别。你可以通过设置Linker->Manifest File->UAC execution level->RequiredMini来请求权限。我不确定这是否回答了OP问题,但是谢谢你的解释,我很喜欢阅读它@谢谢你的反馈。事实上,我现在已经猜到了下载文件的位置。我在Windows6上一切正常。x@typ1232我已经修改了我的问题,添加了一个直接下载到源代码的链接,很抱歉给您带来不便