It is All about Traffic, and Programming
Search
Archives
0 visitors online now
0 guests, 0 members

Reverse Engineering

The Move Constructor: A Linking Pitfall of Qt Library with Different Compilers

Move constructor is a C++11 feature from ISO/IEC14882:2011.  It enhanced the old-school C++ copy constructor by moving the resource of an object, instead of member-wise copying.  It is faster than a copy constructor.  Thus a C++11 compiler will generate six special member functions for a C++ object, including  move constructor and move assignment operator:

  • Default Constructor
  • Copy Constructor
  • Copy Assignment Operator
  • Destructor
  • Move Constructor
  • Move Assignment Operator

We are not going to discuss C++11 Move Constructor in details here –  better details and better explanations are there, and there.

The motivation of  this article,  is not to discuss the semantics or usage of Move Constructor,  but an interesting debugging experience, and the lessons learned which involves C++11 move constructor.

Long story short – I have been working on developing an advanced Qt-based C++ plugin DLL for a host software developed in Qt 4.8.7.   I was using Visual C++ 2010 compiler, and the Qt for VS2010 official release for commercial applications.

The plugin DLL is supposed to be dynamically loaded by the host via Qt’s QLibrary API (see my previous article on this subject), which internally will call Microsoft’s Win32 API LoadLibrary.  Somehow, I got the following error, when trying to load the DLL into the host software:

34f8:3518 @ 01570140 – LdrpGetProcedureAddress – INFO: Locating procedure “AcdssPluginFactory” by name
34f8:3518 @ 01570140 – LdrpNameToOrdinal – WARNING: Procedure “AcdssPluginFactory” could not be located in DLL at base 0x0B630000
34f8:3518 @ 01570140 – LdrpReportError – WARNING: Locating export “AcdssPluginFactory” for DLL “Unknown” failed with status: 0xc0000139
34f8:1168 @ 01570265 – LdrpReportError – ERROR: Locating export “??4QString@@QAEAAV0@$$QAV0@@Z” for DLL “C:\Program Files (x86)\…\plugins\acdssplugin.DLL” failed with status: 0xc0000139

The above debug messages were generated by GFlags Utility, which comes with Debugging Tools for Windows. You can find the most advanced debugging techniques including how to use GFlags utility from the excellent book Inside Windows Debugging.  In our case, we just need to set “Show Loader Snaps” flag, as shown in the figure.  This is a typical way of debugging LoadLibrary failures.

2016-10-12_21-41-26

Looking at the debug messages, it is simply pointing out that LoadLibrary fails because an exported function is missing from the image space – its C++ mangled name as  “??4QString@@QAEAAV0@$$QAV0@@Z”,  which can be interpreted as:


    ? = C++ mangled symbol
    ?4 = "operator="
    QString@ = the enclosing class, hence method name: QString::operator=
    @ = end of the scope
    Q = public
    A = no const and volatile qualifier
    E = __thiscall
    AAV0 = const ref to the first named class (QString) - the return value (const QString &)
    @ = end return type
    $$ = move constructor &&
    QAV0 = const pointer to first named class - QString * const
    @ = end parameter type
    @ = end parameters
    Z = function

So clearly, the host software was complaining that the Move Constructor of QString can not be located in any of the image space.  Upon further inspection of the host software, it is discovered it was compiled using VS2005.  QtCore4.dll does not have the Move Constructor generated with VC++ 2005 compiler.  

The solution is simple – just rebuilt the Qt 4.8.7 using VC++ 2005, and rebuilt the plugin DLL.  Above all, the lessons learned are:

Do NOT mix Qt library compiled with different compilers, EVEN with the same Qt Version.  Period.

Dissecting Vissim COM Internal from Inside Out (3)

In order to study the life cycle of CCOMVissim,  we have to track the calling stack of comsvr.dll.  This DLL is the host of CCOMVissim and other helper classes of Vissim COM functionalities. Please note it is not possible and not an option to perform static code analysis using a typical debugger. This is because CodeMeter hardware chip employs sophisticated anti-debugging mechanism, black-listing all known static/dynamic analysis debuggers such as OllyDBG or IDAPro .  We’d have to return to comsrv.DLL  – and recall in this post – the 58 exported functions, something like below:

vissim-com-export-index-1-30

As an effective approach (for interoperability among Vissim’s own various licensed modules),  let’s start creating a DLL project, using the same name “comsrv.DLL”,  as the one in the Exe folder of Vissim installation.

As a good background reading on exporting  C++ classes in a DLL,  here is an detailed post CodeProject: Export C++ classes from a DLL

Following this new Visual Studio C++ DLL project,  create a new class called CCOMVissim  – pay attention to the class definition, and the empty methods, and the declaration “__declspec(dllexport)“.  By default, the calling convention is “thiscall“.  Because we know Vissim is compiled in Visual C++ compiler apriori, thus name mangling wouldn’t be an issue (because of the same C++ compiler).

2015-06-05_14-59-13

Now, compile this project, and a dll called comsrv.dll is generated.  After this new DLL is generated,  de-compile it to verify the exported functions (see the figure below):

2015-06-05_15-02-18

We just created a “proxy” DLL with the same name as Vissim’s original comsrv.dll.  We emulated some of the original exported functions and classes.  The point is,  as long as the same list of  functions  are exported by this new dll, it is “loadable” by Vissim.  Therefore, we are  enableed to append additional code to track, manage, and manipulate the calling stack of those class methods or functions relevant to the life-cycle of IVissimPtr. This will help accomplish the objective of enabling interoperability of Vissim COM functionalities within Vissim’s various DLL-based modules,  including Signal Control API DLL, External Driver DLL and such.

If you could understand up to this point,  there should be no problem for you to move on to a final working solution to the question asked in the beginning.  The efforts are yours, and the omissions are mine.  One last hint:

Rename the original “comsrv.dll” to a different name, e.g., “comsrv_org.dll”.  Redirect calls from inside the proxy comsrv.dll to the original dll.

Dissecting Vissim COM Internal from Inside Out (1)

There was an interesting discussion at PTV Vissim LinkedIn group – how to access Vissim COM interface inside a DLL, e.g., a Signal Control DLL,  an External Driver DLL etc.  To properly answer this question, some in-depth understanding of the COM technology,  C++ compiler internals, and Vissim binary level details are in order.

To begin with, Component Object Model (COM) is just a binary-level coding standard for out-of-process and in-process communication. It’s been out there for many years but somehow never become popular due to its daunting learning-curve for ordinary programmers,  and then Microsoft began promoting .NET, which is essentially similar idea revamped at the level of Common Language Run-time (CLR) and Intermediate Language (IL).

In the nostalgia good-old days,  COM/C++ programming required too steep learning curve to weed out sub-par programmers.  Nowadays programming is so much easier with various .NET languages or scripting languages that do not require low-level knowledge of hardware or compiler internals. The barrier to programing is quite low nowadays; anyone with common  sense can pick up programming,  develop some apps, and sell such on streets.

In the context of Vissim,  PTV wraps up the simulation elements and workflow into various interfaces. These interfaces are implemented (in C++) at binary level thus any language that supports COM (by their respective compilers) will be able to use Vissim’s COM interface to interact with Vissim functionality.

In the  earlier days of Vissim, its COM interfaces allow a client application to invoke Vissim as an automation server (as an out-of-process use case). Then PTV added In-Menu scripting, that supports invoking COM inside the active Vissim instance, using Python, VBS, or JS.

Starting Vissim 6, PTV completely refactored and redesigned Vissim, almost rebuild the software from scratch, inside out.  As part of this process, more gems are added,  one of such, is the so-called “event-based” COM scripting. “Event-based” COM scripting is a use case of in-process COM; it was added since Vissim v7.

Once again, with the In-Menu COM/Event-based Scripting,  and many other new designs/architectures, Vissim has set up a solid foundation significantly better than its v5 and any earlier generations, making itself readily primed for the future. A big congratulation is due to the PTV development team for this achievement, seriously.

Some of my earlier post discussed Vissim COM Internal as well.

As of today, Vissim 7-09 appears as the most impressive redemption of a legacy software (I mean, particularly, Vissim v4 and earlier versions) – and presents itself, with so many improvements and beef-ups, and as a powerful, sleek and increasingly popular tool for its users that have been yelling and crying for  years while its competitors eating up its market share.

Aside from COM interface, Vissim also provides various APIs e.g., Signal Control API, Emission API, External Driver API etc. These APIs have to be compiled in DLL to be loaded by Vissim host, which calls back the exported functions when certain events fire.

It is interesting that “event-based” COM scripting is capable of providing a unified interface for all the above APIs.  In future, it is possible that PTV might gradually phase out all these DLL-based APIs so everything is done through a unified event-based COM scripting. Granted, that is just my personal perspective.

Now, coming back to the million dollar question –  can we access COM interface from inside an API DLL? For example,  from inside External Driver DLL,  how can we access some, if not all of the COM functions?

The answer is: yes,  that is doable, but with some twist.

Now you start to have a faint of heart,  aren’t you?  Before we roll up our sleeves and jump to the 1-2-3 steps, I want you to take a look at the following snapshots – they are the key to the solution.

The following are the 58 exported functions from comsrv.dll, which is located in Vissim installation Exe folder. Most of these exported functions, are class methods of several classes, primarily:

  • CComVissim
  • CComNetObjHelper
  • CComVehicleContainer
  • CComSignalController
  • CComPedestrianContainer
  • CComException

💡 comsrv.dll is the “hub” of all Vissim COM functionality.

With the above in mind,   let me lead you to the interesting journey to figure out comsvr.dll  and Vissim COM invocation flow, till we reach the final solution to the original question.

vissim-com-export-index-1-30

vissim-com-export-index-31-58

 

(to be continued)

Hushing the nagging screen from Syncrho Education Version

Synchro Education Edition – has a nagging screen EACH time the software is launched – Until you click “Accept”,  you will be going nowhere.

After “Accept” is clicked,  you will see the main UI water-marked with the line saying “Educational Use Only”.  Also you will experience a noticeable freezing period up to 1 or 2 seconds – the software is surreptitiously checking with a Trafficware server in Texas for any new version available, and verifying the license information.

This Fall semester I am teaching a Traffic Control & Simulation course at NYU-Poly, and get to use the Synchro academic version with some sort of frequency.  This nagging screen is becoming quite annoying to me – not to mention personally I tend to attribute this nagging trick as being somewhat paranoid and pointless, especially when the actual protection with Syncrho is shockingly weak.

I simply don’t like that each time I have to manually click the “Accept” button, in order to proceed. Don’t get me wrong,  this is not that I disagree with the terms,  just I don’t like manually doing it.  I would like to make a tool, and authorize the tool,  representing myself, to Agree and Accept to the license terms by clicking the “Accept”  button for me.

Therefore – with my tool of choice – AutoIt,  I prepared a little nifty script so that each time the software is launched, the computer itself will automatically click the button for me to Accept the terms – I don’t need to bother to move any of my fingers.

Wowooo – La!

The following is download link to the compiled version of the script, just put it anywhere on your computer’s desktop to replace the default Synchro shortcut lnkYou are still going to see the nagging screen appear, so you know what you are going to Accept,  but immediately it will be closed since the script, as authorized by you, and truly you,  automatically click the “Accept” button for you.  Besides,  the version checking window will be immediately closed as well,  and you won’t see the initial 1 or 2 seconds freezing period.  You can always to go to “Help” -> “Check for Updates” to do the explicit version check, yourself.

http://www.wupingxin.net/wx-files/synchro-8.7z

VISSM COM Instance Model

VISSIM has a licensed feature “VISSIM COM” that a user can use to do automation-style programming. It provides convenient, easy-to-use  interfaces to access VISSIM functionality programmingly (e.g., though an Excel client).

VISSIM COM Server by design can only be invoked in “single instance” mode. That is, if you have a COM client that tries to establish a connection with a VISSIM COM server, the connection will be established only to the first VISSIM instance that has already been created.  In other words, a new VISSIM instance is created if and only if there is currently no active VISSIM instance running.  On the other hand, if there are multiple VISSIM instances, your COM client would only connect to the first instance.

Yesterday at  the 90th TRB annual meeting, a Minnesota friend asked me if it is possible to create multiple VISSIM COM server connections.   That was a pretty interesting question, and the answer lies in a clear understanding of what is under the hood of Microsoft’s COM technology.  Probably  let me do a little lecture first for those non-programmers or who not familiar with the inner workings of COM.  Since in 99.9% of its applications,  VISSIM is only used as a local out-of-process COM server,  let me just focus on explaining out-of-process COM only.  In-process COM has somewhat different mechanism – in order not to confuse I’ll rather leave it to some discussion later.

For out-of-process COM exe server like VISSIM,  a client program (a client program can be written in any COM compliant languages such as VB, VC++, .NET, or Delphi) starts a connection by calling Windows Operating System’s COM API in the following sequence:

1. CoCreateInstance

Nothing need to mention about this COM API.

 2. CoGetClassObject

For In-Process COM object, CoGetClassObject will get the pointer to the class factory; but for out-of-process COM exe like VISSIM, CoGetClassObject will get the VISSIM path from the ProgID in the system registry. Note, different versions of VISSIM has different ProgID. Also remember VISSIM is registered a LocalServer, so no DCOM is involved.

 3. CoRegisterClassObject

Once the system locates VISSIM.exe, CoRegisterClassObject (this is the ultimate ole32 API to be invoked, even VISSIM uses some .NET wrappers) – will be invoked in the start-up code before calling the WinMain entry function of VISSIM.exe.

 Here is the signature CoRegisterClassObject(CLSID, pUnk, dwClsContext, flags, &dwRegister). The key point is the fourth parameter “flags”. It determines during run-time whether VISSIM COM exe can be started as single instance or multiple instances. Check MSDN for more information about this COM API:

http://msdn.microsoft.com/en-us/library/ms693407%28VS.85%29.aspx

The fourth parameter is a REGCLS enumeration variable defined as:

typedef enum tagREGCLS { 
  REGCLS_SINGLEUSE       = 0,
  REGCLS_MULTIPLEUSE     = 1,
  REGCLS_MULTI_SEPARATE  = 2,
  REGCLS_SUSPENDED       = 4,
  REGCLS_SURROGATE       = 8
} REGCLS;

All we need to do is to  specify REGCLS_SINGLEUSE,  then VISSIM COM exe will be invoked in a “multi-instance” manner.  Why? Here is the description of the REGCLS flag:

  • REGCLS_SINGLEUSE

After an application is connected to a class object with CoGetClassObject, the class object is removed from public view so that no other applications can connect to it. This value is commonly used for single document interface (SDI) applications. Specifying this value does not affect the responsibility of the object application to call CoRevokeClassObject; it must always call CoRevokeClassObject when it is finished with an object class.

  • REGCLS_MULTIPLEUSE

Multiple applications can connect to the class object through calls to CoGetClassObject. If both the REGCLS_MULTIPLEUSE and CLSCTX_LOCAL_SERVER are set in a call to CoRegisterClassObject, the class object is also automatically registered as an in-process server, whether or not CLSCTX_INPROC_SERVER is explicitly set.

The above text is a little twisty – essentially it says, if REGCLS_SINGLEUSE is set, then any client connection request would result in creation of a new class object – in our case, the class object is VISSIM object represented by IVissim interface. Creating a new class object means starting a new VISSIM.exe process, because VISSIM.exe is the host of the class object. Period.

A little interesting additional information on what happens after CoRegisterClassObject – Internally, a I/O completion port (a.k.a IOCP) is created.  I/O completion port is a fairly low level Inter Process Communication (IPC) mechanism. By low level, I mean, File handle, Winsock2, name pipes etc all these higher level IPC mechanism would be built on top of I/O Completion port. So IOCP is pretty “ugly” if you ever bother to delve into that level to satisfy your peeking eyes and curiosity.

The created I/O completion port receives I/O completion packets then dispatches the package via Windows messaging then to the WndProc registered by ole32.dll. That WndProc then unmarshall the out-of-process COM method invocation and restores the original function’s stack frame, hence finishes the entire invocation COM function.

This creation of stack frame on the fly is similar to how web services are implemented. All are based on stack frames created during run time. Stack frame is just a memory footprint to prepare a function invocation, say, you need to allocate sufficient memories from the stack, then save all the current states registers and push the parameters. Of course, in COM, the convention is always stdcall.

Depending on the threading model the subject COM objects implements (single apartment, multiple apartment or whatever), there are some nuisances that I am not going to touch here.

OpenMP Runtime Version Conflicts

I was working on a software project that I have been working on in the past two years…

The strangest thing happened when I tried to launch the main GUI of the system – I double clicked it, it flashed in the screen then disappeared immediately.

This doesn’t make sense at all – it was working just a few days ago and I didn’t recall I did anything…

I launched the debugger from the IDE, but the same thing happened while none of the source code break points get hit!

My first reaction is, something must go wrong in the compiler generated start-up code….

So, Plan B.

This time I launched the OllyDBG debuggger from which I started my executable.

….. oh….. modules loaded one by one…. then…… boop!

I got this error message from a console window, and the main program just halted:

OMP abort: Initializing lidguide40.dll, but found libiomp5md.dll already initialized.

This may cause preformance KMP_DUPLICATE_LIB _OK=TRUE to ignore this problem and force the program to continue anyway. Please note that the use of KMP_DUPLICAT_LIB_OK is Unsupported and using it may cause undefined behavioer. For more infomation,please contact Intel(R) Premier Support. ”

So what is going on?

Here is an explanation from Intel website:

Both libiomp5md.dll and libguide40.dll are Intel OpenMP Runtime library. The libiomp5md.dll is new Intel OpenMP* Compatibility library while the libguide40.dll is legacy OpenMP library. The Intel® IPP 6.x and Intel® Compiler 11.x threading libraries are switching from the legacy OpenMP* run-time library (libguide*) to the compatibility library (libiomp*).

The dynamic library, libguide40.dll, is still included in the current releases for backwards compatibility and will be removed in a future release.

The error is caused by multiple OpenMP libraries were linked in same application. For example, if a application link the libiomp5md.dll from IPP 6.x, at the same time, it also link other software, e.g third-party library, which link libguide40.dll, then the error arises because of the duplicate initialization of OpenMP Runtime library

So it turns out that two third party libraries I was using are dependent on TWO different versions of OpenMP libraries.

In all, it wasn’t a challenging problem that requires RE technique to find the cause, however it is an elusive problem as the Console warning window never show up, or it did but in a very very short time to prevent naked human eyes to notice.

Solution? For the time being I just add the environmental variable as suggested but later I am thinking of removing one of the third party libraries.

Aimsun scripting: A different perspective

Aimsun is an Object-Oriented Framework and Unified Platform for Traffic Modeling.  It  provides quite a few programming interfaces for advanced applications and customization. To name a few,  those  include Aimsun Simulator API,  Aimsun SDK,  Aimsun Python-based Scripting,  MicroSDK,  Logistics SDK, Parking APIs.  These SDKs and APIs  together with Aimsun main software  provide powerful tools for its users.

Interestingly, by design all these APIs, albeit having different focuses, have ONE in common, i.e., they MUST either be invoked within Aimsun host ( e.g., Aimsun SDK and Aimsun Pyhton-based Scripting), or called-back during run time (i.e., simulator API and MicroSDK). This means Aimsun cannot be used as a COM automation sever, and therefore it may not be invoked by external applications.

Actually, it is only partially true.  First of all, this is not something to complain about.  Aimsun is a cross-platform software package;  it runs on Linux, MacOS, and Windows. COM is a very much Windows specific technology, so in spite of that it is doable it simply doesn’t seem to make much sense to dedicate Aimsun to a platform specific feature.  Second some the COM-like functionality can be achieved by using ANGApp class, which is fully accessible by Python scripting.

In this post,  I would like to discuss a way of porting ANGApp class by Python C API,  so that some of  its advanced functionality becomes available to a common compiler-based language.  To start with,  the following shows a Python wrapper class that encapsulate some COM-like interfaces, on top of the ANGApp class:

from PyANGBasic   import *
from PyANGApp     import *
from PyANGAimsun  import *
from PyANGKernel  import *
from PyANGConsole import *

__author__    = "Wuping Xin"
__company__   = "No Inc."
__copyright__ = "Copyright (c) No Rights Reserved"
__license__   = "python"
__version__   = "$1.0.0 $"
__date__      = "$Date: 2009/07/15 11:57 $"

class AimsunApp:
"Wrapper class of Aimsun ANGApp class for C++ application with Python C API"
def __init__(self, isCon = False):
  self.angInstance = None
  self.simulator   = None
  self.model       = None
  self.angGui      = None
  self.isConsole   = isCon
  def initInstance(self):
  pass

def freeInstance(self):
pass

def openNetwork(self,filename):
pass

def runInteractive(self):
  self.angInstance.run()

def __setModel(self):
  self.model = self.angInstance.getModel()

def initSimulator(self,repID,simMode = 0):

.......
def runSingleStep(self):
  self. angInstance.processEvents()
  self.simulator.simulationStep()

With this wrapper class ready, we can use the following C code to invoke:

Py_Initialize();
..........

pName    = PyString_FromString("aimsunpy_interface");
pModule  = PyImport_Import(pName);
pDict    = PyModule_GetDict(pModule);

// Build the name of a callable class
pClass = PyDict_GetItemString(pDict, "AimsunApp");

// Create an instance of the wrapper cls.
if (PyCallable_Check(pClass))
{
    pInstance = PyObject_CallObject(pClass, NULL);
}

PyObject_CallMethod(pInstance, "initInstance", NULL);
PyObject_CallMethod(pInstance, "openNetwork","s","C:\\Test\\test.ang");
PyObject_CallMethod(pInstance, "initSimulator","i",346);

This is a nuance to note – when trying to load a C-Extension module ( i.e., *.pyd file),  if the host program that embeds Python interpreter links with pythonxx_d.dll, then PyImport_Import will import the xxxx_d.pyd, even if the module’s name is specified without “_d”!  Also this approach is dependent on Aimsun’s embedded Python  interpreter hence there is some run-time performance hit. But if that is not an issue, this approach would make it possible to integrate Aimsun with external applications, for example, MATLAB platform.

Inside Aimsun ANGApp.close

Aimsun ANGApp is a class available to python scripting. It is a very interesting class that TSS provides to its general users, and can be very powerful if the user really appreciates how it works.

In the past a few days, I have been cleaning up my previous codes, while working on a project proposal that may require Aimsun micro + meso. And for some reason, one code snippet that has worked previously crashes on ANGApp.close … …

This time I am pretty hesitant to write to TSS for help – though I am sure they are going to help, as always TSS is very kind and prompt in supporting their users – sometimes a little delay if they are busy. And for these couple of days, I know they are being working their tails off on the new release of Aimsun 6.1.0 – couldn’t be more busier.

So I decided not to bother them and find out myself.

All rightee ……the question is, what is really going on inside ANGAPP.close()? And why there is a crash? Let’s take a partial look at the code segment:

OK, save the current state of ESI by pushing it to stack. This is a no brainer.
.text:00B620E0 push esi

Note, ECX always holds the “this” pointer for C++ class. So, after mov ESI, ECX, ESI stores the starting address of the current ANGApp instance
.text:00B620E1 mov esi, ecx

Now, since ESI+0 is the starting address of the subject ANGApp instance, ESI + 8 must be the address for some private member-variable, and by looking at the instruction at 00B620EA , we can immediately get the hint that it must be the address for a GGui* pointer . Now, what about ESI + 4? Note the fact that ANGApp inherits from QObject, thus ESI+4 actually is the address for a protected pointer of type QObjectData. What about ESI+0xC? Hey, are you as curious as I am? That is a good question! That is actually the address for a pointer of type GKModel *.

Doh~!
.text:00B620E3 mov ecx, [esi+8]

IS the GGui* NULL?
.text:00B620E6 test ecx, ecx

.text:00B620E8 jz short loc_B620FC

If the GGui* is not NULL then call GGui.getActiveModel
.text:00B620EA call ds:__imp_?getActiveModel@GGui@@QBEPAVGKModel@@XZ ;

.text:00B620F0 mov ecx, [esi+8]

Now after invoking GGui.getActiveModel, EAX holds the returned pointer for GKModel
.text:00B620F3 push eax

Then GGui.closeDocument is called with the returned GKModel pointer from above instruction
.text:00B620F4 call ds:__imp_?closeDocument@GGui@@QAE_NPAVGKModel@@@Z

Okaydokay. So far so good! Now restore ESI.
.text:00B620FA pop esi
.text:00B620FB retn
.text:00B620FC ; —————————————————————————
.text:00B620FC

.text:00B620FC loc_B620FC:
[ESI + 0xC] is the address that holds the pointer of type GKModel*
.text:00B620FC mov ecx, [esi+0Ch]

Now ECX holds the pointer to GKModel
.text:00B620FF test ecx, ecx

.text:00B62101 jz short loc_B62112

Here is the tricky part. [ECX +0] is the address of the v-table of GKModel class
.text:00B62103 mov eax, [ecx]

Now EDX stores the address of the v-table of GKModel class
.text:00B62105 mov edx, [eax]

Index 1 means the first virtual function in the v-table. Note, GKModel inherits from GKObject. Therefore, the first virtual function in the v-table is the destructor ~GKObject()
.text:00B62107push 1

Now call the destructor
.text:00B62109 call edx

Reset the GKModel* pointer to zero.
.text:00B6210B mov dword ptr [esi+0Ch], 0

This is perfect code logically showing no problem at all! And it turns out that the crash was caused by a corrupted memoy I artificially manipulated which screw up ANGApp’s initernal data!