__int64 __fastcall GreResetDCInternal(HDC oldHDC, __int64 a2,
int
*
a3, __int64 a4, __int64 a5)
{
HDC v5;
/
/
r14
int
*
v6;
/
/
r13
int
v7;
/
/
r15d
HDC v8;
/
/
r12
unsigned
int
v9;
/
/
edi
DCOBJ
*
v10;
/
/
rbx
__int64 PDEVOBJ;
/
/
rbx
__int64 v12;
/
/
rax
DCOBJ
*
v13;
/
/
rcx
int
v14;
/
/
r13d
BOOL
v15;
/
/
r14d
int
v16;
/
/
esi
HDC newHDC;
/
/
rax
DCOBJ
*
v18;
/
/
rdx
void (__fastcall
*
vuln_ptr)(_QWORD, _QWORD);
/
/
rax
__int64 v21;
/
/
rax
__int64 v22;
/
/
rcx
bool
v23;
/
/
zf
int
v24;
/
/
[rsp
+
28h
] [rbp
-
51h
]
__int64 v25;
/
/
[rsp
+
58h
] [rbp
-
21h
] BYREF
DCOBJ
*
oldDCOBJ[
2
];
/
/
[rsp
+
60h
] [rbp
-
19h
] BYREF
DCOBJ
*
newDCOBJ[
11
];
/
/
[rsp
+
70h
] [rbp
-
9h
] BYREF
v5
=
oldHDC;
v6
=
a3;
v7
=
0
;
v8
=
0i64
;
v9
=
0
;
DCOBJ::DCOBJ((DCOBJ
*
)oldDCOBJ, oldHDC);
/
/
create a DCOBJ
from
HDC
v10
=
oldDCOBJ[
0
];
if
( !oldDCOBJ[
0
] )
{
EngSetLastError(
6u
);
v13
=
oldDCOBJ[
0
];
LABEL_38:
v16
=
v25;
goto LABEL_19;
}
v7
=
*
((_DWORD
*
)oldDCOBJ[
0
]
+
9
) &
0x800
;
/
/
offset
0x24
: flag
if
( v7 )
{
DC::bMakeInfoDC(oldDCOBJ[
0
],
0
);
v10
=
oldDCOBJ[
0
];
}
PDEVOBJ
=
*
((_QWORD
*
)v10
+
6
);
/
/
offset
0x30
: hdev
v12
=
*
(_QWORD
*
)(PDEVOBJ
+
0x6B0
);
*
(_QWORD
*
)(PDEVOBJ
+
0x6B0
)
=
0i64
;
v13
=
oldDCOBJ[
0
];
v25
=
v12;
if
( (
*
((_DWORD
*
)oldDCOBJ[
0
]
+
9
) &
0x100
) !
=
0
||
*
((_DWORD
*
)oldDCOBJ[
0
]
+
8
)
=
=
1
|| (
*
(_DWORD
*
)(PDEVOBJ
+
40
) &
0x80u
)
=
=
0
)
{
goto LABEL_38;
}
v14
=
*
((_DWORD
*
)oldDCOBJ[
0
]
+
0x1B
);
v15
=
*
((_QWORD
*
)oldDCOBJ[
0
]
+
0x3E
) !
=
0i64
;
v16
=
v15;
if
( XDCOBJ::bCleanDC((XDCOBJ
*
)oldDCOBJ,
0
) )
{
if
(
*
(_DWORD
*
)(PDEVOBJ
+
8
)
=
=
1
)
{
/
/
create a new HDC
and
back to user mode
newHDC
=
(HDC)hdcOpenDCW(&word_1C02CCD00, a2,
0i64
,
0i64
,
*
(_QWORD
*
)(PDEVOBJ
+
2560
), v25, a4, a5,
0
);
/
/
miss some validation of oldHDC, maybe the oldHDC has been released
v8
=
newHDC;
if
( newHDC )
{
*
(_QWORD
*
)(PDEVOBJ
+
0xA00
)
=
0i64
;
/
/
create a newDCOBJ
from
newHDC
DCOBJ::DCOBJ((DCOBJ
*
)newDCOBJ, newHDC);
v18
=
newDCOBJ[
0
];
if
( newDCOBJ[
0
] )
{
if
( v14 >
0
)
{
*
((_DWORD
*
)newDCOBJ[
0
]
+
27
)
=
*
((_DWORD
*
)newDCOBJ[
0
]
+
26
);
v18
=
newDCOBJ[
0
];
}
/
/
fetch data
from
oldDCOBJ, maybe the oldDCOBJ has been released
*
((_QWORD
*
)v18
+
0x101
)
=
*
((_QWORD
*
)oldDCOBJ[
0
]
+
0x101
);
*
((_QWORD
*
)oldDCOBJ[
0
]
+
0x101
)
=
0i64
;
*
((_QWORD
*
)newDCOBJ[
0
]
+
0x102
)
=
*
((_QWORD
*
)oldDCOBJ[
0
]
+
258
);
*
((_QWORD
*
)oldDCOBJ[
0
]
+
0x102
)
=
0i64
;
/
/
vuln_ptr can be a dangling function pointer
vuln_ptr
=
*
(void (__fastcall
*
*
)(_QWORD, _QWORD))(PDEVOBJ
+
0xAB8
);
if
( vuln_ptr )
vuln_ptr(
*
(_QWORD
*
)(PDEVOBJ
+
0x708
),
*
(_QWORD
*
)(
*
((_QWORD
*
)newDCOBJ[
0
]
+
6
)
+
0x708i64
));
/
/
...
}