IRONCAD QueryInterface crash in CoCreateInstance.

c++ / delphi package - dll injection and api hooking
kimjw0820
Posts: 35
Joined: Fri Sep 11, 2015 1:54 am

IRONCAD QueryInterface crash in CoCreateInstance.

Post by kimjw0820 »

Version : madCodeHook 3.1.18
OS : windows 10, Windows 7 same crush.
Tool : IRONCAD ( 30day trial download : https://drive.google.com/open?id=1RGUa9 ... tdgI-hGX0n )

Hello :)
Crash on QueryInterface attempt in IRONCAD process.
Other processes will work fine.
I don't know what the problem is.
If you need a pdb symbol and a dump file, I'll email you. (dmp file : 600mb)

Thank you.

code:

Code: Select all

HookAPI("Ole32.dll", "CoCreateInstance", cocreateinstanceCallback, (PVOID*)&cocreateinstanceNext);

HRESULT WSAAPI cocreateinstanceCallback(_In_  REFCLSID  rclsid,
    _In_  LPUNKNOWN pUnkOuter,
    _In_  DWORD     dwClsContext,
    _In_  REFIID    riid,
    _Out_ LPVOID* ppv
    ) {

    HRESULT result = S_OK;

    result = cocreateinstanceNext(
                rclsid,
                pUnkOuter,
                dwClsContext,
                riid,
                ppv
                );

    if (SUCCEEDED(result) && ppv && *ppv) {
        CComPtr<IFileDialog> file_dialog = nullptr;
        if (SUCCEEDED(reinterpret_cast<IUnknown*>(*ppv)->QueryInterface(IID_IFileDialog, reinterpret_cast<void**>(&file_dialog)))) { // crash point.

        }
    }

    return result;
}
crash point:

Code: Select all

if (SUCCEEDED(reinterpret_cast<IUnknown*>(*ppv)->QueryInterface(IID_IFileDialog, reinterpret_cast<void**>(&file_dialog)))) { // crash point.
--------------------------------------------------------------------------------

dump:

Code: Select all

KEY_VALUES_STRING: 1

    Key  : Timeline.OS.Boot.DeltaSec
    Value: 78

    Key  : Timeline.Process.Start.DeltaSec
    Value: 38


PROCESSES_ANALYSIS: 1

SERVICE_ANALYSIS: 1

STACKHASH_ANALYSIS: 1

TIMELINE_ANALYSIS: 1

Timeline: !analyze.Start
    Name: <blank>
    Time: 2019-10-10T02:03:38.920Z
    Diff: 495920 mSec

Timeline: Dump.Current
    Name: <blank>
    Time: 2019-10-10T01:55:23.0Z
    Diff: 0 mSec

Timeline: Process.Start
    Name: <blank>
    Time: 2019-10-10T01:54:45.0Z
    Diff: 38000 mSec

Timeline: OS.Boot
    Name: <blank>
    Time: 2019-10-10T01:54:05.0Z
    Diff: 78000 mSec


DUMP_CLASS: 2

DUMP_QUALIFIER: 400

CONTEXT:  (.ecxr)
rax=00000000013f8db0 rbx=00007ffb882af490 rcx=000000005b643900
rdx=000000005b38042c rsi=00000000011eaf40 rdi=00000000011eb430
rip=000000005b37f6e2 rsp=00000000011eb6c0 rbp=00007ffb72117b98
 r8=00000000011eb780  r9=0000000000000000 r10=000000000fffffff
r11=000000000142a170 r12=ffffffffffff0002 r13=0000000000000002
r14=0000000009ada050 r15=00000000136e5580
iopl=0         nv up ei pl nz na pe nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010200
mfc100u!AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2+0x4e:
00000000`5b37f6e2 488b8f10010000  mov     rcx,qword ptr [rdi+110h] ds:00000000`011eb540=0000000000010eae
Resetting default scope

FAULTING_IP: 
mfc100u!AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2+4e
00000000`5b37f6e2 488b8f10010000  mov     rcx,qword ptr [rdi+110h]

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 000000005b37f6e2 (mfc100u!AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2+0x000000000000004e)
   ExceptionCode: c000041d
  ExceptionFlags: 00000001
NumberParameters: 0

PROCESS_NAME:  ICDraft.exe

ERROR_CODE: (NTSTATUS) 0xc000041d - <Unable to get error code text>

EXCEPTION_CODE: (NTSTATUS) 0xc000041d - <Unable to get error code text>

EXCEPTION_CODE_STR:  c000041d

WATSON_BKT_PROCSTAMP:  591bc582

WATSON_BKT_PROCVER:  19.0.20.14614

PROCESS_VER_PRODUCT:  IRONCAD

WATSON_BKT_MODULE:  mfc100u.dll

WATSON_BKT_MODSTAMP:  4df2cfdb

WATSON_BKT_MODOFFSET:  11f6e2

WATSON_BKT_MODVER:  10.0.40219.325

BUILD_VERSION_STRING:  18362.1.amd64fre.19h1_release.190318-1202

MODLIST_WITH_TSCHKSUM_HASH:  e162a2fec137bfe9e8c8c9e2b017925a0c98a3ad

MODLIST_SHA1_HASH:  efe39d7e8b9c004e3f6eb8471a724d33da623c9d

NTGLOBALFLAG:  0

APPLICATION_VERIFIER_FLAGS:  0

PRODUCT_TYPE:  1

SUITE_MASK:  272

DUMP_FLAGS:  8000c07

DUMP_TYPE:  3

ANALYSIS_SESSION_HOST:  JS-±èÁö¿ì

ANALYSIS_SESSION_TIME:  10-10-2019 11:03:38.0920

ANALYSIS_VERSION: 10.0.18362.1 amd64fre

THREAD_ATTRIBUTES: 
OS_LOCALE:  KOR

BUGCHECK_STR:  FATAL_USER_CALLBACK_EXCEPTION

DEFAULT_BUCKET_ID:  FATAL_USER_CALLBACK_EXCEPTION

PRIMARY_PROBLEM_CLASS:  FATAL_USER_CALLBACK_EXCEPTION

PROBLEM_CLASSES: 

    ID:     [0n321]
    Type:   [@APPLICATION_FAULT_STRING]
    Class:  Primary
    Scope:  DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
            BUCKET_ID
    Name:   Omit
    Data:   Add
            String: [FATAL_USER_CALLBACK_EXCEPTION]
    PID:    [Unspecified]
    TID:    [Unspecified]
    Frame:  [0]

LAST_CONTROL_TRANSFER:  from 00007ffb408adf98 to 000000005b37f6e2

STACK_TEXT:  
00000000`011eb6c0 00007ffb`408adf98 : 00000000`09d166a0 00000000`011eb7e0 00000000`0142a9d0 00007ffb`72117b98 : mfc100u!AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2+0x4e
00000000`011eb6f0 00000000`5b4ae147 : 00007ffb`406df118 00000000`09a33540 00000000`09ada050 00000000`013f8db0 : 3ish31!CConverter::ConvertToEdges+0x1c8
00000000`011eb750 00000000`5b4ae1d3 : 00000000`00000000 00000000`09a33540 00000000`09ada050 00007ffb`72117b98 : mfc100u!CCmdTarget::QueryAggregates+0x5b
00000000`011eb780 00007ffb`40675d64 : 00000000`09a33540 00007ffb`72117b98 00007ffb`722060b2 cccccccc`cccccccc : mfc100u!CCmdTarget::InternalQueryInterface+0x4b
00000000`011eb7b0 00007ffb`71f017ba : 00000000`09ad9b88 00007ffb`407f3fd0 00000000`09ada050 cccccccc`cccccccc : 3icm31!CViewTool::RestoreStatusString+0x90
00000000`011eb800 00007ffb`89751000 : 00007ffb`4072dec0 00000000`00000000 00000000`00000001 00007ffb`4072e280 : jsfnhk64!cocreateinstanceCallback+0x10a
00000000`011eb890 00007ffb`4072dec0 : 00000000`00000000 00000000`00000001 00007ffb`4072e280 00000000`011eb8d0 : 0x00007ffb`89751000
00000000`011eb898 00000000`00000000 : 00000000`00000001 00007ffb`4072e280 00000000`011eb8d0 00007ffb`55074ccd : 3icm31!CInsertWireFillet::`vftable'+0x27c8


THREAD_SHA1_HASH_MOD_FUNC:  260c95073262d6211a349cb000b3242a3dce58ea

THREAD_SHA1_HASH_MOD_FUNC_OFFSET:  7004ee3f0e6f0bfe52ef1efb72a019100f40836c

THREAD_SHA1_HASH_MOD:  0693860c4f337eaed421c36f48fdd10ca99c45e1

FOLLOWUP_IP: 
mfc100u!AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2+4e
00000000`5b37f6e2 488b8f10010000  mov     rcx,qword ptr [rdi+110h]

FAULT_INSTR_CODE:  108f8b48

SYMBOL_STACK_INDEX:  0

SYMBOL_NAME:  mfc100u!AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2+4e

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: mfc100u

IMAGE_NAME:  mfc100u.dll

DEBUG_FLR_IMAGE_TIMESTAMP:  4df2cfdb

STACK_COMMAND:  ~0s ; .ecxr ; kb

BUCKET_ID:  FATAL_USER_CALLBACK_EXCEPTION_mfc100u!AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2+4e

FAILURE_EXCEPTION_CODE:  c000041d

FAILURE_IMAGE_NAME:  mfc100u.dll

BUCKET_ID_IMAGE_STR:  mfc100u.dll

FAILURE_MODULE_NAME:  mfc100u

BUCKET_ID_MODULE_STR:  mfc100u

FAILURE_FUNCTION_NAME:  AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2

BUCKET_ID_FUNCTION_STR:  AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2

BUCKET_ID_OFFSET:  4e

BUCKET_ID_MODTIMEDATESTAMP:  4df2cfdb

BUCKET_ID_MODCHECKSUM:  566e8e

BUCKET_ID_MODVER_STR:  10.0.40219.325

BUCKET_ID_PREFIX_STR:  FATAL_USER_CALLBACK_EXCEPTION_

FAILURE_PROBLEM_CLASS:  FATAL_USER_CALLBACK_EXCEPTION

FAILURE_SYMBOL_NAME:  mfc100u.dll!AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2

FAILURE_BUCKET_ID:  FATAL_USER_CALLBACK_EXCEPTION_c000041d_mfc100u.dll!AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2

WATSON_STAGEONE_URL:  http://watson.microsoft.com/StageOne/ICDraft.exe/19.0.20.14614/591bc582/mfc100u.dll/10.0.40219.325/4df2cfdb/c000041d/0011f6e2.htm?Retriage=1

TARGET_TIME:  2019-10-10T01:55:23.000Z

OSBUILD:  18362

OSSERVICEPACK:  329

SERVICEPACK_NUMBER: 0

OS_REVISION: 0

OSPLATFORM_TYPE:  x64

OSNAME:  Windows 10

OSEDITION:  Windows 10 WinNt SingleUserTS

USER_LCID:  0

OSBUILD_TIMESTAMP:  unknown_date

BUILDDATESTAMP_STR:  190318-1202

BUILDLAB_STR:  19h1_release

BUILDOSVER_STR:  10.0.18362.1.amd64fre.19h1_release.190318-1202

ANALYSIS_SESSION_ELAPSED_TIME:  43f8

ANALYSIS_SOURCE:  UM

FAILURE_ID_HASH_STRING:  um:fatal_user_callback_exception_c000041d_mfc100u.dll!afx_maintain_state2::afx_maintain_state2

FAILURE_ID_HASH:  {a5efe655-3a45-f929-9cea-3f1fc482da7c}

Followup:     MachineOwner
---------
1.png
1.png (119.19 KiB) Viewed 15386 times
2.png
2.png (65.24 KiB) Viewed 15386 times
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by iconic »

Hello,

So this doesn’t happen with an empty callback?
Only when you query the i-face???

—Iconic
kimjw0820
Posts: 35
Joined: Fri Sep 11, 2015 1:54 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by kimjw0820 »

Yes it doesn't happen with an empty callback.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by madshi »

How does your definition of CoCreateInstanceNext look like? Not sure about what WSAAPI is, I hope it ends up as WINAPI?

This "CComPtr<IFileDialog>" stuff is some kind of dark compiler magic to help you deal with interfaces, I think? I personally don't like such things for low level things like API hooks. Instead use a simple "IFileDialog*", that way you have more control over what happens exactly.
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by iconic »

WSAAPI will result in WINAPI/__stdcall however using WSAAPI alias instead of WINAPI for a COM API completely unrelated to Windows Socket API (WSA) isn't right and either WINOLEAPI or WINAPI should be used directly (both are __stdcall) otherwise this can clearly be confusing to the programmer. Of course if your app is 64-bit this doesn't matter as there is only one calling convention so it only matters for 32-bit apps.

What's a bit puzzling is how other processes aren't crashing when the QueryInterface() method is called, just one specific process being this IRONCAD program. COM objects always have to support AddRef, Release and QueryInterface methods by default so it really shouldn't be an issue at all when calling this API. Anyhow, you shouldn't have to call this method anyhow, you can just check the CLSID and RIID directly, like this:

Code: Select all

if (SUCCEEDED(result) && IsEqualIID(riid, IID_IFileDialog) && IsEqualCLSID(rclsid, CLSID_FileOpenDialog)) // whatever specific CLSID you need for an open or save dialog
{
 ...
}
Also, be sure to only call HookCode() on methods that aren't *already* hooked because CoCreateInstance() can be called multiple times resulting in several calls to HookCode()

--Iconic
kimjw0820
Posts: 35
Joined: Fri Sep 11, 2015 1:54 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by kimjw0820 »

Thank you :)

Unfortunately I haven't found a solution yet...
WSAAPI is a mistake during test sample creation. I'm using __stdcall and the problem occurs likewise.
IsEqualIID not available due to COM interface inheritance structure.
can also create FileDialog using IID_IUnknwon...
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by iconic »

I’ll download the trial and test myself to see if I can reproduce the issue. Please allow me a day or two as I’ve just arrived back home now. I’m a MCH 4.x user so I’ll revert to 3.x to keep the setup similar.

—Iconic
kimjw0820
Posts: 35
Joined: Fri Sep 11, 2015 1:54 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by kimjw0820 »

wow!
I'm not sure it's a problem with MCH.
Thank you for your help.
Doesn't the problem occur in MCH 4.x?
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by iconic »

I don’t actually think it’s MCH related either personally but I’ll double check and try to reproduce just in the off chance that it is specific to MCH.

—Iconic
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by iconic »

@kimjw0820,

I’ve installed the entire CAD suite (~3.3 gb) and will run tests tomorrow to see if I can reproduce the issue. I’ve also registered the trial for icdraft which is the faulting executable in your crash dump, it appears. It will be the primary process I’ll analyze. Just wanted to keep you in the loop, I’ll post back tomorrow.

—Iconic
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by iconic »

Sorry for the delay, I have tested IronCAD (ICDraft.exe) with a CoCreateInstance() hook and have called the QueryInterface() method on the returned interface pointer. I was able to successfully do so with both MCH 3.x and MCH 4.x without any issues here. Tested on Windows 7 x64 Ultimate SP1. I wrote a simple Delphi DLL to test instead of c++, however. If you'd like to upload your exact c++ hook project I can test here as well with that, if you want.

Code: Select all

var
 CoCreateInstanceNext: function(const clsid: TCLSID;
                                  pUnkOuter: PVOID;
                               dwClsContext: DWORD;
                                  const iid: TIID;
                                        ppv: PPVOID): HRESULT; stdcall = nil;

function CoCreateInstanceCallback(const clsid: TCLSID;
                                    pUnkOuter: PVOID;
                                 dwClsContext: DWORD;
                                    const iid: TIID;
                                          ppv: PPVOID): HRESULT; stdcall;
var
    ifd: IFileDialog;
begin
    result := CoCreateInstanceNext(clsid,
                                   pUnkOuter,
                                   dwClsContext,
                                   iid,
                                   ppv);
    if Succeeded(result) and (ppv <> nil) and (ppv^ <> nil) then
    begin
    if Succeeded(IUnknown(ppv^).QueryInterface(IID_IFileDialog, ifd)) then
    OutputDebugString('IFileDialog Detected!')
else
    OutputDebugString('Not IFileDialog!');
    end;
end;
ICDraft.png
ICDraft.png (446.07 KiB) Viewed 15150 times
--Iconic
kimjw0820
Posts: 35
Joined: Fri Sep 11, 2015 1:54 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by kimjw0820 »

hello! Thank you for testing.
The problem is reproduced when creating a 3D scene immediately after starting the process without creating a dialog like the attached image.
(1.png -> 2.png)

Windows 7 pro 32bit, 64bit Windows 10 64bit are all reproduced.

Reproduction video : https://www.dropbox.com/s/ire4kh20qt193 ... d.mp4?dl=0
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by iconic »

I was able to reproduce the issue as per your instructions contained within your video. The issue seems to stem from the internal chained calls that take place after QueryInterface() method is called, an internal routine is called and then aggregates are each queried one by one, which is what is generating the exception.

Code: Select all

00000000`0059bb00 00000000`6f96e1d3 : 00000000`00000000 00000000`12ef7f60 00000000`0059bbb0 00000000`02f974d0 : mfc100u!CCmdTarget::QueryAggregates+0x59
00000000`0059bb30 000007fe`e1425d64 : 00000000`12ef7f60 00000000`02f974d0 00000000`12ae4bb0 00000000`00000002 : mfc100u!CCmdTarget::InternalQueryInterface+0x4b
00000000`0059bb60 00000000`02f80dee : 000007fe`e148f268 000007fe`e15a3fd0 00000000`00000000 00000000`6f859beb : 3icm31!CViewTool::RestoreStatusString+0x90
00000000`0059bbb0 000007fe`fe851000 : 000007fe`e15a3fd0 00000000`6f83f6f9 00000000`0059bca8 000007fe`e148f1b0 : Test_CoCreate+0x80de <--- my hook DLL module


mfc100u!CCmdTarget::QueryAggregates+0x59:
00000000`6f96e145 ff10            call    qword ptr [rax] ds:feeefeee`feeefeee=????????????????e
RAX is certainly invalid and causes an invalid pointer exception...

--Iconic
kimjw0820
Posts: 35
Joined: Fri Sep 11, 2015 1:54 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by kimjw0820 »

Thank you for analysis.
Can you solve the problem?

Does the problem happen with MCH 4.x as well?
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: IRONCAD QueryInterface crash in CoCreateInstance.

Post by iconic »

Same issue happens with any hooking library, it’s not specific to any one library. The issue at hand lies in the software’s incorrect implementation of the QueryInterface() method within one of their “custom” interface extensions. It’s simply not implemented properly by COM “contract” standards and as a result already freed heap memory is being accessed when it shouldn’t be. Google 0xFeeeFeee on x86, it’s an MSVC memory marker “identifier” usually set after new/delete pairs. Put simply, QueryInterface() can’t be called safely, which is very unfortunate. Exclude the specific process in MCH or check IID, CLSID etc. Not much else can be done outside of hacks

—Iconic
Post Reply