Thu Jan 21 15:49:36 2016: Request 80322 was acted upon.
Transaction: Correspondence added by BULKDD
Queue: Win32-API
Subject: 'make test' failure - 03_Jim_Shaw.t - invalid unpack type
Broken in: 0.72, 0.73
Severity: Important
Owner: Nobody
Requestors: [email protected]
Status: open
Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=80322 >
After having no clue how to fix this, and having some doubts if this ticket is
real, I reproduced it with Win 7+VC 2013. Perhaps something in EnumChildWindows
changed between Win XP and Win7 that stopped "resetting" the FPU, or the SSE
heavy instead of x87, machine code of VC 2013 wasn't clearing the FPU state the
way the older non-SSE code wouldve, or EnumChildWindows in WinXP used ebp as
base pointer and in Win7 when MS compiled user32.dll, ebp was reused as GPR
with only esp addressing.
Anyways, what was happening was each fld op in the shellcode callback was
pushing one var onto FPU stack. Eventually the FPU stack which has 8 elements
was filled. x87 Stack Fault (bit 6) exception bit came on at that point. After
that, no further FPU math was possible. NAN was the result of every op. That
resulted in this PP division op failing, after 8 calls of the W::A::C callback
https://metacpan.org/source/BULKDD/Win32-API-0.82/Callback.pm#L176 this line in
PP was returning NAN even though its "16/4" which cant possibly be NAN. The NAN
in a SVNV after going through SvUV became 0, so the callback unwound the C
stack by 0 bytes instead of 8 as stdcall requires (EnumChildWindows wants a
stdcall func, not cdecl). Eventually EnumChildWindows poped nonvol register esi
from the wrong location on C stack a couple hundred bytes away from the correct
location of the saved esi register, since every call into the callback screwed
up esp by 8 bytes. The corrupted esi register after E
numChildWindows returned control to W::A causing a crash in Win32::API's
Call_asm.