微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MSVC++ 内联汇编未处理异常 0x80000004:单步

如何解决MSVC++ 内联汇编未处理异常 0x80000004:单步

我正在使用带有 VC++ 2019 32 位的内联 asm 编写代码。我写了一个函数来切换协程。这是源代码

我对其进行了测试,效果很好。参数是一个包含寄存器值的 uintptr_t 数组。该函数将交换除ebx之外的寄存器值。

问题是“tool.exe 中 0x5514704E (pevm.dll) 处的未处理异常:0x80000004:单步。”。

寄存器值:EAX = 00000246 EBX = 0019F5A0 ECX = E2F13240 EDX = 0019F5A0 ESI = 0019F3A8 EDI = 0019F3C8 EIP = 5514704E ESP = 0019F2BC EBP = 0019F2C0 EFL = 00000202

我不明白为什么“pop eax”会抛出异常? 也许我的代码破坏了一些“内部数据结构”,程序恰好停在这里,就像双重释放一样。对如何调试有什么建议吗?

inline __declspec(naked) void switchCoroutine(uintptr_t* vreg)
{
    //discard ebx
    __asm
    {
        push ebp
        mov ebp,esp
        //save 
        push eax
        //argument
        mov ebx,[ebp + 8]

        //exchange eflags 
        pushfd
        pop eax
        push[ebx]
        popfd
        mov[ebx],eax

        pop eax
        //exchange eax,ecx,edx,esi,edi
        XCHG eax,[ebx + type int]
        xchg ecx,[ebx + 3 * type int]
        xchg edx,[ebx + 4 * type int]
        xchg esi,[ebx + 5 * type int]
        xchg edi,[ebx + 6 * type int]

        //exchange ebp,esp
        mov esp,ebp
        pop ebp
        xchg ebp,[ebx + 7 * type int]
        xchg esp,[ebx + 8 * type int]

        //go eip
        ret
    }
}

55147031 C2 04 00             ret         4  
--- No source file -------------------------------------------------------------
55147034 CC                   int         3  
55147035 CC                   int         3  
55147036 CC                   int         3  
55147037 CC                   int         3  
55147038 CC                   int         3  
55147039 CC                   int         3  
5514703A CC                   int         3  
5514703B CC                   int         3  
5514703C CC                   int         3  
5514703D CC                   int         3  
5514703E CC                   int         3  
5514703F CC                   int         3  
--- D:\code\c++\PEVM\core\vm\vdata.h -------------------------------------------
   643:     //discard ebx
   644:     __asm
   645:     {
   646:         push ebp
55147040 55                   push        ebp  
   647:         mov ebp,esp
55147041 8B EC                mov         ebp,esp  
   648:         //save 
   649:         push eax
55147043 50                   push        eax  
   650:         //argument
   651:         mov ebx,[ebp + 8]
55147044 8B 5D 08             mov         ebx,dword ptr [vreg]  
   652: 
   653:         //exchange eflags 
   654:         pushfd
55147047 9C                   pushfd  
   655:         pop eax
55147048 58                   pop         eax  
   656:         push[ebx]
55147049 FF 33                push        dword ptr [ebx]  
   657:         popfd
5514704B 9D                   popfd  
   658:         mov[ebx],eax
5514704C 89 03                mov         dword ptr [ebx],eax  
   659: 
   660:         pop eax
5514704E 58                   pop         eax    //HERE   **Unhandled exception at 0x5514704E (pevm.dll) in tool.exe: 0x80000004: Single step.**

   661:         //exchange eax,edi
   662:         XCHG eax,[ebx + type int]
5514704F 87 43 04             xchg        eax,dword ptr [ebx+4]  
   663:         xchg ecx,[ebx + 3 * type int]
55147052 87 4B 0C             xchg        ecx,dword ptr [ebx+0Ch]  
   664:         xchg edx,[ebx + 4 * type int]
55147055 87 53 10             xchg        edx,dword ptr [ebx+10h]  
   665:         xchg esi,[ebx + 5 * type int]
55147058 87 73 14             xchg        esi,dword ptr [ebx+14h]  
   666:         xchg edi,[ebx + 6 * type int]
5514705B 87 7B 18             xchg        edi,dword ptr [ebx+18h]  
   667: 
   668:         //exchange ebp,esp
   669:         mov esp,ebp
5514705E 8B E5                mov         esp,ebp  
   670:         pop ebp
55147060 5D                   pop         ebp  
   671:         xchg ebp,[ebx + 7 * type int]
55147061 87 6B 1C             xchg        ebp,dword ptr [ebx+1Ch]  
   672:         xchg esp,[ebx + 8 * type int]
55147064 87 63 20             xchg        esp,dword ptr [ebx+20h]  
   673: 
   674:         //go eip
   675:         ret
55147067 C3                   ret  
--- No source file -------------------------------------------------------------
55147068 CC                   int         3  
55147069 CC                   int         3  
5514706A CC                   int         3  
5514706B CC                   int         3  
5514706C CC                   int         3  
5514706D CC                   int         3  
5514706E CC                   int         3  
5514706F CC                   int         3  

解决方法

0x5514704B,您设置了 EFLAGS。当它设置了 TF 标志时,CPU 将在下一条执行指令后生成调试异常 (#DB)。 popfd 之后的下一个是 mov[ebx],eax,因此执行后会产生异常。由于#DB 是一个陷阱,eip 指向执行指令之后的地址,在您的情况下为 pop eax

检查 push[ebx] 处的 0x55147048 是否设置了 TF 位。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。