1

Say I have a simple class like the one below:

class Foo
{
public:
    Foo(){};
protected:
    int meth1( void ){return 0;};
public:
    int var1;
};

Compiled with MSVC and parsing the corresponding PDB via the DbgHelp API, I can iterate over the children and parse out the methods and variables fine, but I am unable to figure out how I determine the access specifier for a given child. My code looks something like this:

// The symbol tag for 'index' is a SymTagEnum::SymTagBaseClass

DWORD item_count;
if( !::SymGetTypeInfo( process, base_address, index, TI_GET_CHILDRENCOUNT, &item_count ) )
    break;

if( item_count > 0 )
{
    TI_FINDCHILDREN_PARAMS * item_indexs = new TI_FINDCHILDREN_PARAMS[item_count];

    item_indexs->Count = item_count;
    item_indexs->Start = 0;

    if( ::SymGetTypeInfo( process, base_address, index, TI_FINDCHILDREN, item_indexs ) )
    {
        for( DWORD i=0 ; i<item_count ; i++ )
        {
            DWORD item_tag;
            if( !::SymGetTypeInfo( process, base_address, item_indexs->ChildId[i], TI_GET_SYMTAG, &item_tag ) )
                break;

            DWORD item_type_index;
            if( !::SymGetTypeInfo( process, base_address, item_indexs->ChildId[i], TI_GET_TYPEID, &item_type_index ) )
                break;

            // XXX: How to discover the access specifier (public, private, protected) for
            // the class method/variable at 'item_type_index'?

            switch( item_tag )
            {
                case SymTagEnum::SymTagFunction:
                {
                    // parse out the class method at 'item_type_index'
                    break;
                }
                case SymTagEnum::SymTagData:
                {
                    // parse out the class variable at 'item_type_index'
                    break;
                }
                default:
                {
                    break;
                }
            }
        }
    }
}

Is it possible to determine the access specifiers (public, private, protected) for a classes children via the DbgHelp API, and if so, how?

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
QAZ
  • 4,870
  • 6
  • 36
  • 50

1 Answers1

1

Yes, that's technically possible. You'll retrieve the decorated (aka mangled) name for the function. In your case that will be ?meth1@Foo@@IAEHXZ. Decorated C++ names always start with a question mark. You can feed that to the UnDecorateSymbolName() function to convert it back to the C++ identifier name. Which will be:

protected: int __thiscall Foo::meth1(void)

Note how it includes the access specifier.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks, I'm familiar with UnDecorateSymbolName but don't know how to pull a decorated name from a symbol using the symbol index and the dbghelp API? – QAZ Nov 06 '13 at 20:20
  • Does that have anything at all to do with discovering the accessibility, the subject of the question? Clearly you'll need to be able to retrieve the function name first. – Hans Passant Nov 06 '13 at 20:25