I am writing a code using inline asm with VC++ 2019 32bit. I have written a function to switch coroutine.This is the source code :
I tested it and it works well. The argument is a uintptr_t array that contains the register value. This function will exchagne register value except ebx.
The problem is the "Unhandled exception at 0x5514704E (pevm.dll) in tool.exe: 0x80000004: Single step.".
Register value : EAX = 00000246 EBX = 0019F5A0 ECX = E2F13240 EDX = 0019F5A0 ESI = 0019F3A8 EDI = 0019F3C8 EIP = 5514704E ESP = 0019F2BC EBP = 0019F2C0 EFL = 00000202
I can not understand why "pop eax" throw exception ? Maybe my code destroy some "internal data structure" and the program happened to stop here, like double free. Any suggestions to how to debug ?
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 ,ecx,edx,esi,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
At 0x5514704B
you set EFLAGS
. When it has TF
flag set, a debug exception (#DB) will be generated by the CPU after next executed instruction. Next after popfd
is mov[ebx], eax
, thus the exception is generated after it's execution. Since #DB is a trap, eip points to address after the executed instruction, pop eax
in your case.
Check if push[ebx]
at 0x55147048
has TF
bit set.
User contributions licensed under CC BY-SA 3.0