OK I finally found 811EZFRD64.dll (and matching version) here:
http://www.driverguide.com/driver/detail.php?driverid=1865150&action=filfo
How do people even find shady websites like this and decide to install software from it?!?! "Other Companies Universal Wired Controller Free Driver Download" just sounds soooo legit. Is this even a mayflash device?
In any case, this file is for VID/PID 0x0810/0x0001. (Try a quick search for that and see how many people have problems...)
For reference, it seems the code is basically doing the same as
https://github.com/arielscarpinelli/ntpad/blob/master/forcefeedback-support-dll/CForceFeedbackImpl.cpp
Now, back to the crash:
Looking at the exception context, we can see the problem is rcx:
Code:
0:005> .ecxr
rax=0000000000000000 rbx=00007ff8f6ef4bc0 rcx=0000000049d40080
rdx=0000000000000000 rsi=0000000000000010 rdi=0000000010001af0
rip=0000000010003654 rsp=000000c449f3fbc0 rbp=0000000049d40080
r8=000000c449f3fad8 r9=0000000049d40080 r10=0000000000000000
r11=0000000000000287 r12=000000007ffe000c r13=000000007ffe0008
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
811EZFRD64+0x3654:
00000000`10003654 837c011000 cmp dword ptr [rcx+rax+10h],0 ds:00000000`49d40090=????????
Looking at the crashing code:
Code:
__int64 __fastcall sub_10003600(void *a1)
{
...
for ( i = 0; i < 0x10; ++i )
{
if ( *((_DWORD *)a1 + 1226 * i + 4) ) <--- CRASH IS HERE
{
Looking at how this is reached:
Code:
// sub_10002110 is in some vtable+0x18. |this| is a 0x13388-byte object.
signed __int64 __fastcall sub_10002110(DWORD_PTR a1, unsigned int a2, unsigned int a3)
{
...
*(_DWORD *)(a1 + 0x13380) = timeSetEvent(25u, 100u, (LPTIMECALLBACK)fptc, (unsigned int)a1, 1u);
void __fastcall fptc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1)
{
sub_10003600((void *)(unsigned int)dwUser);
}
I began to suspect the issue was just that rcx is truncated from 64 to 32bits.
In fact this seems to be the case:
Code:
...
+ c4`49c4f8f8 c4`49c50000 0`00000708 Stack [~4; 1f80.1634]
+ c4`49c50000 c4`49e40000 0`001f0000 <unknown> <-- object allocated into here
+ c4`49e40000 c4`49f3e398 0`000fe398 Stack [~5; 1f80.1d00]
...
(It's <unknown> just because the dump doesn't have full info; it's the heap).
Soooo this is technically not ASLR related at all. In fact this code was just never really 64bit compatible. The ASLR change just happened to expose it. This is purely the EZFRD64's fault. timeSetEvent is documented to take dwUser param as DWORD_PTR type, which is 8bytes on 64bit. So they are doing some improper casting here which causes this.