0

I am trying to locate a specific function in a .pdb file. Originally I compiled a simple "hello, world" program, and analyzed the name of the functions using the IDiaSymbol::get_name method, but I couldn't locate my function.

After this, I tried including a __declspec(naked) void myFunction(void){} function in my helloworld.pdb file, in order to use the IDiaSymbol::get_isNaked method to locate my function, however, when I did this, nothing at all was printed - entailing there are no naked functions in my code.

//After initialization, creating instance, etc
IDiaEnumSymbols* pUnknown = NULL;
        if (pTable->QueryInterface(__uuidof(IDiaEnumSymbols), (void**) &pUnknown) == S_OK) {
            printf("Supports Symbol module\n");
            CComPtr<IDiaSymbol> pSymbol;
            int counter = 0;
            for (LONG i = 0; i < blongTableCount; i++)
            {
                if (pUnknown->Item(i, &pSymbol) != S_OK) {
                    fprintf(stderr, "Error: pUnknown->Item");
                }

                
                BOOL isFunction;
                if (pSymbol->get_function(&isFunction) == S_OK) {
                    if (isFunction == TRUE) {
                        counter += 1;
                        printf("Number of functions: %d", counter);

                        //With the following I could not find my functions
                        BSTR symName;
                        if (pSymbol->get_name(&symName) == S_OK) {
                            printf("Name of symbol: %S\n", symName);
                        }
                        
                        //Check for naked functions - I included a declspec(naked) function for testing.
                        BOOL pFlag;
                        if (pSymbol->get_isNaked(&pFlag) == S_OK) {
                            printf("This is a naked function");
                        }
                    }
                }

                pSymbol = NULL;

            }
        }

EDIT: Included my simple .pdb program below (was a "hello world program", now contains a simple __declspec(naked) function):

#include <iostream>

__declspec(naked) void myFunction(void) {
    
    __asm {
        ret
    }

}

int main()
{
    myFunction();
    return 0;
}

What I expected from parsing the symbol table: The same results you would get when parsing an ELF file on *NIX - a symbol table containing the actual names I wrote for my function, so something like ".text myFunction"

What is actually printed out: Many Winapi functions and other assembler created functions, probably due to optimizing out of my function.

Example:

Name of symbol: main
Name of symbol: __acrt_thread_attach
Name of symbol: _RTC_NumErrors
Name of symbol: ReadNoFence64
Name of symbol: __setusermatherr
Name of symbol: _RTC_SetErrorFuncW
Name of symbol: IsProcessorFeaturePresent
Name of symbol: GetLastError
Name of symbol: __acrt_initialize

  • *"I tried including a template"* - I don't understand this. Are you talking about a C++ function template? – IInspectable Jan 19 '22 at 13:08
  • Sorry, by template I meant a dummy function, without any contents. – functionhunter Jan 19 '22 at 13:09
  • Please provide a [mce] (including the code you compiled into object code or a PE image). Also be specific about the expected behavior and observed behavior. [Ask] provides helpful guidance. – IInspectable Jan 19 '22 at 13:12
  • Keep in mind that unlike *NIX (where symbols are public by default), Microsoft's toolchain opted for the saner solution: All symbols are **private** by default. Depending on what artifact you compiled, `myFunction` may have been optimized out. – IInspectable Jan 19 '22 at 13:16
  • I have edited my code to include a minimal reproducible example. I guess then I must find a way to turn off compiler optimizations, and a way of making symbols public on Windows. It's funny that the compiler went to the length of completely removing my "naked" attribute (it probably created a prologue and an epliogue, ignoring my instruction) - you'd think it wouldn't optimize that much without being instructed to. – functionhunter Jan 19 '22 at 13:59
  • The compiler did no such thing. The compiler merely inlined the function call. It was the linker that removed the symbol, as no one is using it. The linker can make that call due to the symbol being private. You can prevent this by exporting the symbol, i.e. `__declspec(dllexport)`. – IInspectable Jan 19 '22 at 14:12

0 Answers0