简体   繁体   English

无法让 SymGetTypeInfo 工作(错误 1,函数不正确)

[英]Cannot get SymGetTypeInfo to work (error 1, Incorrect function)

TLDR : Could someone explain how to correctly use the SymGetTypeInfo . TLDR :有人可以解释如何正确使用SymGetTypeInfo

My goal is to get the type information for local variables (wherever Rip / Eip happens to be).我的目标是获取局部变量的类型信息(无论Rip / Eip碰巧在哪里)。

According to the documentation, I need to call the SymSetContext with the IMAGEHLP_STACK_FRAME structure filled with appropriate values.根据文档,我需要使用填充了适当值的IMAGEHLP_STACK_FRAME结构来调用SymSetContext I got this part working as when I call SymEnumSymbols (setting the BaseOfDll parameter to 0 as the doc says to do when setting context), I do in fact only get the local variables.我在调用SymEnumSymbols时使这部分工作(将BaseOfDll参数设置为0 ,正如文档在设置上下文时所说的那样),实际上我只获取局部变量。

HOWEVER :但是

When inside the enumerate symbols callback, I try to call SymGetTypeInfo , something like this:在枚举符号回调中,我尝试调用SymGetTypeInfo ,如下所示:

static BOOL s_enum_symbols_callback(
    PSYMBOL_INFO pSymInfo,
    ULONG SymbolSize,
    PVOID UserContext) {
    // ...

    HANDLE hProcess = /*Defined elsewhere*/;
    wchar_t *buffer = (wchar_t *)allocate_symname_memory();

    SymGetTypeInfo(hProcess, pSymInfo->ModBase, pSymInfo->TypeIndex, TI_GET_SYMNAME, &buffer);
}

SymGetTypeInfo fails with error 1 ("Incorrect function"). SymGetTypeInfo失败并出现错误 1(“函数不正确”)。

Ok so now I am troubleshooting to figure out why this might happen.好的,现在我正在排除故障以找出为什么会发生这种情况。 My first theory is that this may have something to do with setting the context, so I remove the SymSetContext and enumerate again.我的第一个理论是这可能与设置上下文有关,因此我删除了SymSetContext并再次枚举。 This time (I obviously get all the symbols), and I get the same problem except for a few types, notably: I am able to get the type of __scrt_current_native_startup_state (which is __scrt_native_startup_state ).这一次(我显然得到了所有符号),除了少数类型外,我遇到了同样的问题,特别是:我能够获得__scrt_current_native_startup_state的类型(即__scrt_native_startup_state )。

Ok so maybe... the problem is that I am calling SymGetTypeInfo inside a Sym* callback function??好吧,也许...问题是我在 Sym* 回调 function 中调用 SymGetTypeInfo ? (doubt it though). (虽然怀疑)。 Anyway, I put the theory to the test, and enumerate just the symbols which I have defined globally:无论如何,我对理论进行了测试,并仅列举了我在全球范围内定义的符号:

wchar_t global_variable = 12;
int global_variable0 = 12;
float global_variable1 = 12.0f;
int global_variable2 = 12;

Once again, not setting the context, I enumerate the symbols and note the TypeIndex value for each so that once outside of the enumerate symbols function, I call SymGetTypeInfo like this:再一次,不设置上下文,我枚举符号并记下每个符号的TypeIndex值,以便在枚举符号 function 之外,我像这样调用SymGetTypeInfo

SymGetTypeInfo(hProcess, process_pdb_base, type_index, TI_GET_SYMNAME, &buffer);

( process_pdb_base is returned from SymModuleLoad64 ). process_pdb_baseSymModuleLoad64返回)。

And I get the SAME problem.我遇到了同样的问题。

Maybe I am completely misunderstanding what the TypeIndex really is?也许我完全误解了TypeIndex是什么? (although it is consistent for different variables with the same type), or maybe it's only for user-defined types?? (尽管对于具有相同类型的不同变量是一致的),或者它可能仅适用于用户定义的类型??

So yeah I am lost and tired, please help internet.所以是的,我迷路了,累了,请帮助上网。

Alright guys, I think I figured it out and it's all thanks to this marvelous article written in 2004, by Oleg Starodumov!好的,伙计们,我想我明白了,这一切都要感谢 Oleg Starodumov 在 2004 年写的这篇精彩的文章

And one of my theories wasn't completely wrong - I did indeed misunderstand what the Debug Help (well actually, the entire Win32 API,) library refers to.我的一个理论并没有完全错误——我确实误解了调试帮助(实际上,整个 Win32 API)库所指的内容。 when using the word "type": As the article wonderfully puts it, "The type of an object defines the set of properties supported by the object. and the set of possible relationships between the object and other objects."当使用“类型”一词时:正如文章所说,“object 的类型定义了 object 支持的属性集。以及 object 和其他对象之间的可能关系集。”

So really, the SymGetTypeInfo functions, is just used to query information about any symbol.所以说真的, SymGetTypeInfo函数只是用来查询任何符号的信息。 Now there are indeed different categories of symbols, which are encapsulated by the SymTagEnum enumerator type which is defined in DbgHelp.h IF you have _NO_CVCONST_H defined with #define ( NOTE : You use this if you don't have access to cvconst.h which was my case).现在确实有不同类别的符号,它们由在 DbgHelp.h 中定义的SymTagEnum枚举器类型封装,如果您使用#define定义了DbgHelp.h注意:如果您无权访问_NO_CVCONST_H ,您可以cvconst.h它是我的情况)。

Because this article is so great and I don't want to spoil it for anyone, I will quickly resume what I needed to do to fix my issue, instead of trying to explain querying the C/C++ "type" information (not Win32 "type") of a variable.因为这篇文章太棒了,我不想为任何人破坏它,我将快速恢复我需要做的事情来解决我的问题,而不是试图解释查询 C/C++“类型”信息(不是 Win32“类型”) 变量。

The first thing I needed to do, was get the tag of the symbol which represented the C/C++ "type" of the local variable symbol (which is indeed stored in TypeIndex ).我需要做的第一件事是获取代表局部变量符号的 C/C++“类型”的符号标记(它确实存储在TypeIndex中)。 Next, I needed the code to act accordingly for each different possible tag.接下来,我需要代码对每个不同的可能标签采取相应的行动。 In my case, because this was what was called a BaseType , I needed to query what BaseType the type symbol was.就我而言,因为这就是所谓的BaseType ,所以我需要查询类型符号的BaseType是什么。 With this:有了这个:

SymGetTypeInfo(hProcess, pSymInfo->ModBase, pSymInfo->TypeIndex, TI_GET_BASETYPE, &type);

Now, each base type has a corresponding enum constant associated with it.现在,每个基本类型都有一个与之关联的相应枚举常量。 The enum looks like this:枚举看起来像这样:

enum BasicType
{
    btNoType = 0,
    btVoid = 1,
    btChar = 2,
    btWChar = 3,
    btInt = 6,
    btUInt = 7,
    btFloat = 8,
    btBCD = 9,
    btBool = 10,
    btLong = 13,
    btULong = 14,
    btCurrency = 25,
    btDate = 26,
    btVariant = 27,
    btComplex = 28,
    btBit = 29,
    btBSTR = 30,
    btHresult = 31
};

And lo and behold, the base type did in fact correspond with the types of my local variables!你瞧,基本类型确实与我的局部变量的类型相对应!

NOTE I couldn't find this enum in my system (most likely because I didn't have the Debugger Interface Access SDK), so to get it, I simply copied the TypeInfoStructs.h file located in another link provided by Oleg Starodumov.注意我在我的系统中找不到这个枚举(很可能是因为我没有调试器接口访问 SDK),所以为了得到它,我只需复制位于 Oleg Starodumov 提供的另一个链接中的TypeInfoStructs.h文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM