문제는 this.mailDoc() 처리 중 생성된 내부 XID 객체가 더 이상 필요하지 않은 시점보다 먼저 해제되고, 이후 후속 함수들에 동일한 포인터가 그대로 전달되는 데서 발생합니다.
취약한 흐름은 아래와 같이 단순화할 수 있습니다.
v11 = sub_2B6C0(a1, 0); // Allocate XID object
...
CMFCRibbonInfo::XID::XID(v11);
j_j_free_0(v11); // Free XID object
v20 = CStringT(..., L"document.mailDoc()");
v21 = sub_DE50(...);
// Use-After-Free
v22 = CDumpContext::operator<<(v11);
if (CRichEditView::XRichEditOleCallback::ContextSensitiveHelp(
(CRichEditView::XRichEditOleCallback *)v27,
v22))
{
...
}
즉, 내부 객체 v11은 j_j_free_0(v11)를 통해 해제된 뒤에도 CDumpContext::operator<< 및 이후 UI/문자열 처리 경로에서 계속 사용됩니다. 이 과정에서 해제된 힙 메모리에 남아 있던 값이나 재사용된 값이 문자열 비교 함수 등에 전달되면서 비정상 동작이 발생합니다.
일부 실행 환경에서는 해제된 포인터가 곧바로 잘못된 주소를 참조하여 Access Violation이 발생하며, 다른 경우에는 wcscmp와 같은 문자열 비교 루틴까지 전파된 뒤 크래시가 발생할 수 있습니다. 힙 상태에 따라 충돌 양상은 달라질 수 있으나, 근본 원인은 동일한 Use-After-Free입니다.
