1

TLDR:有人可以解释如何正确使用SymGetTypeInfo.

我的目标是获取局部变量的类型信息(无论Rip/Eip碰巧在哪里)。

根据文档,我需要使用填充适当值SymSetContext的结构来调用。IMAGEHLP_STACK_FRAME我在调用时使这部分工作SymEnumSymbols(将BaseOfDll参数设置0为文档在设置上下文时所说的),实际上我只获取局部变量。

但是

在枚举符号回调中,我尝试调用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失败并出现错误 1(“功能不正确”)。

好的,现在我正在排除故障以找出为什么会发生这种情况。我的第一个理论是这可能与设置上下文有关,所以我删除SymSetContext并再次枚举。这一次(我显然得到了所有符号),除了少数类型之外,我得到了同样的问题,特别是:我能够得到__scrt_current_native_startup_state (即__scrt_native_startup_state)的类型。

好吧,也许...问题是我在 Sym* 回调函数中调用 SymGetTypeInfo ?(虽然怀疑)。无论如何,我对理论进行了测试,并仅列举了我在全球范围内定义的符号:

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

再一次,不设置上下文,我枚举符号并记下TypeIndex每个符号的值,以便在枚举符号函数之外,我SymGetTypeInfo这样调用:

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

(process_pdb_baseSymModuleLoad64) 返回。

我遇到了同样的问题。

也许我完全误解了TypeIndex真正的东西是什么?(尽管对于具有相同类型的不同变量是一致的),或者它可能仅适用于用户定义的类型??

所以是的,我迷路了,累了,请帮助上网。

4

1 回答 1

1

好的,伙计们,我想我明白了,这一切都要感谢Oleg Starodumov 在 2004 年写的这篇精彩的文章!

我的一个理论并没有完全错误——我确实误解了调试帮助(实际上是整个 Win32 API!)库在使用“类型”一词时所指的内容。正如文章精彩地指出的那样:“对象的类型定义了对象所支持的属性集,以及对象与其他对象之间可能的关系集。”

所以实际上,这些SymGetTypeInfo函数只是用来查询任何符号的信息。现在确实有不同类别的符号,它们由枚举器类型封装,该SymTagEnum枚举器类型在您定义的IF 中DbgHelp.h 定义_NO_CVCONST_H#define注意如果您无权访问cvconst.h我的情况,则使用它)。

因为这篇文章太棒了,我不想为任何人破坏它,我将快速恢复我需要做的事情来解决我的问题,而不是试图解释查询 C/C++“类型”信息(不是 Win32“类型”) 变量。

我需要做的第一件事是获取代表局部变量符号的 C/C++“类型”的符号标记(它确实存储在 中TypeIndex)。接下来,我需要代码对每个不同的可能标签采取相应的行动。就我而言,因为这就是所谓的 a BaseType,所以我需要查询BaseType类型符号是什么。有了这个:

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

现在,每个基本类型都有一个与之关联的相应枚举常量。枚举看起来像这样:

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
};

你瞧,基本类型确实与我的局部变量的类型相对应!

注意 我在我的系统中找不到这个枚举(很可能是因为我没有调试器接口访问 SDK),所以为了得到它,我只是复制了TypeInfoStructs.h位于Oleg Starodumov 提供的另一个链接中的文件。

于 2021-02-12T13:45:16.973 回答