REhints/HexRaysCodeXplorer

View on GitHub
src/HexRaysCodeXplorer/MSVCObjectFormatParser.h

Summary

Maintainability
Test Coverage
/*    Copyright (c) 2013-2015
REhints <info@rehints.com>
All rights reserved.

==============================================================================

This file is part of HexRaysCodeXplorer

HexRaysCodeXplorer is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

==============================================================================
*/

#pragma once 
#include "IObjectFormatParser.h"
#include "Common.h"

//////////////////////////////////////////////////////////////////////////
//
// Based on some impressions and code from ClassInformer plugin
// http://sourceforge.net/projects/classinformer/
//
//////////////////////////////////////////////////////////////////////////


namespace vftable
{
    // vftable info container
    struct vtinfo
    {
        ea_t start, end;
        asize_t methodCount;
        qstring type_info;
    };

    bool getTableInfo(ea_t ea, vtinfo &info);

    // Returns TRUE if mangled name indicates a vftable
    inline bool isValid(LPCSTR name) { return(*((PDWORD)name) == 0x375F3F3F /*"??_7"*/); }
}


namespace RTTI
{
#pragma pack(push, 1)

    // std::type_info class representation
    struct type_info
    {
        ea_t vfptr;           // type_info class vftable
        ea_t _M_data;      // NULL until loaded at runtime
        char _M_d_name[1]; // Mangled name (prefix: .?AV=classes, .?AU=structs)

        static bool isValid(ea_t typeInfo);
        static bool isTypeName(ea_t name);
        static bool getName(ea_t typeInfo, qstring& outName);

    };
    const UINT MIN_TYPE_INFO_SIZE = (offsetof(type_info, _M_d_name) + sizeof(".?AVx"));
    typedef type_info _TypeDescriptor;
    typedef type_info _RTTITypeDescriptor;

    // Base class "Pointer to Member Data"
    struct PMD
    {
        int mdisp;    // 00 Member displacement
        int pdisp;  // 04 Vftable displacement
        int vdisp;  // 08 Displacement inside vftable
    };

    // Describes all base classes together with information to derived class access dynamically
    // attributes flags
    const UINT BCD_NOTVISIBLE = 0x01;
    const UINT BCD_AMBIGUOUS = 0x02;
    const UINT BCD_PRIVORPROTINCOMPOBJ = 0x04;
    const UINT BCD_PRIVORPROTBASE = 0x08;
    const UINT BCD_VBOFCONTOBJ = 0x10;
    const UINT BCD_NONPOLYMORPHIC = 0x20;
    const UINT BCD_HASPCHD = 0x40;

    struct _RTTIBaseClassDescriptor
    {
#ifndef __EA64__
        ea_t typeDescriptor;        // 00 Type descriptor of the class
#else
        UINT typeDescriptor;        // 00 Type descriptor of the class  *X64 int32 offset
#endif
        UINT numContainedBases;        // 04 Number of nested classes following in the Base Class Array
        PMD  pmd;                    // 08 Pointer-to-member displacement info
        UINT attributes;            // 14 Flags
                                    // 18 When attributes & BCD_HASPCHD
                                    //_RTTIClassHierarchyDescriptor *classDescriptor; *X64 int32 offset

        static bool isValid(ea_t bcd, ea_t colBase64 = 0);

    };

    // "Class Hierarchy Descriptor" describes the inheritance hierarchy of a class; shared by all COLs for the class
    // attributes flags
    const UINT CHD_MULTINH = 0x01;    // Multiple inheritance
    const UINT CHD_VIRTINH = 0x02;    // Virtual inheritance
    const UINT CHD_AMBIGUOUS = 0x04;    // Ambiguous inheritance

    struct _RTTIClassHierarchyDescriptor
    {
        UINT signature;            // 00 Zero until loaded
        UINT attributes;        // 04 Flags
        UINT numBaseClasses;    // 08 Number of classes in the following 'baseClassArray'
#ifndef __EA64__
        ea_t baseClassArray;    // 0C _RTTIBaseClassArray*
#else
        UINT baseClassArray;    // 0C *X64 int32 offset to _RTTIBaseClassArray*
#endif

        static bool isValid(ea_t chd, ea_t colBase64 = 0);

    };

    // "Complete Object Locator" location of the complete object from a specific vftable pointer
    struct _RTTICompleteObjectLocator
    {
        UINT signature;                // 00 32bit zero, 64bit one, until loaded
        UINT offset;                // 04 Offset of this vftable in the complete class
        UINT cdOffset;                // 08 Constructor displacement offset

#ifndef __EA64__
        ea_t typeDescriptor;        // 0C (type_info *) of the complete class
        ea_t classDescriptor;       // 10 (_RTTIClassHierarchyDescriptor *) Describes inheritance hierarchy
#else
        UINT typeDescriptor;        // 0C (type_info *) of the complete class  *X64 int32 offset
        UINT classDescriptor;       // 10 (_RTTIClassHierarchyDescriptor *) Describes inheritance hierarchy  *X64 int32 offset
        UINT objectBase;            // 14 Object base offset (base = ptr col - objectBase)
#endif


        static bool isValid(ea_t col);
        static bool isValid2(ea_t col);

    };
#pragma pack(pop)

    const WORD IS_TOP_LEVEL = 0x8000;

    void freeWorkingData();

    bool processVftable(ea_t vft, ea_t col, vftable::vtinfo &vi);
}


extern void fixEa(ea_t ea);
extern void fixDword(ea_t eaAddress);
extern void fixFunction(ea_t eaFunc);
extern void idaapi setUnknown(ea_t ea, asize_t size);
extern bool getVerifyEa(ea_t ea, ea_t &rValue);
extern BOOL hasAnteriorComment(ea_t ea);
extern void killAnteriorComments(ea_t ea);

extern bool getPlainTypeName(const qstring& mangled, qstring& outStr);

extern BOOL optionOverwriteComments, optionPlaceStructs;

class MSVCObjectFormatParser :
    public IObjectFormatParser
{
public:
    virtual ~MSVCObjectFormatParser();

    virtual void get_rtti_info();
    virtual void clear_info();
};