本帖最后由 冥界3大法王 于 2025-11-3 17:41 编辑
后两个 DbgGetLabelAt、DbgGetModuleAt 这对应的Delphi实现都解决了。。。
而这个 DbgGetStringAt (Delphi工程里是没有的)
看了实现的注释还挺复杂的。。。
这是一个用于获取寄存器标签信息的C++函数,让我逐行解释:
// 函数定义:获取寄存器标签信息,参数为寄存器枚举值
QString RegistersView::getRegisterLabel(REGISTER_NAME register_selected)
{
// 定义各种文本缓冲区
char label_text[MAX_LABEL_SIZE] = ""; // 标签文本缓冲区
char module_text[MAX_MODULE_SIZE] = ""; // 模块文本缓冲区
char string_text[MAX_STRING_SIZE] = ""; // 字符串文本缓冲区
char status_text[MAX_STRING_SIZE] = ""; // 状态文本缓冲区
// 获取寄存器数值并格式化为16进制字符串
QString valueText = QString("%1").arg((* ((duint*) registerValue(&mRegDumpStruct, register_selected))),
mRegisterPlaces[register_selected].valuesize, 16, QChar('0')).toUpper();
// 获取寄存器数值的副本
duint register_value = (* ((duint*) registerValue(&mRegDumpStruct, register_selected)));
QString newText = QString(""); // 初始化返回文本
// 检查寄存器值对应的内存位置是否有各种信息
bool hasString = DbgGetStringAt(register_value, string_text); // 是否有可读字符串
bool hasLabel = DbgGetLabelAt(register_value, SEG_DEFAULT, label_text); // 是否有标签
bool hasModule = DbgGetModuleAt(register_value, module_text); // 是否在模块中
// 检查是否是NTSTATUS状态码(仅对EAX/RAX寄存器且值在特定范围内)
bool hasStatusCode = register_selected == REGISTER_NAME::CAX &&
(register_value & ArchValue(0xF0000000, 0xFFFFFFFFF0000000)) == 0xC0000000;
// 如果是状态码,尝试格式化状态码描述
hasStatusCode = hasStatusCode && DbgFunctions()->StringFormatInline(
QString().sprintf("{ntstatus@%X}", register_value).toUtf8().constData(),
sizeof(status_text), status_text);
// 优先级1:如果有可读字符串且该寄存器允许显示字符串
if(hasString && !mONLYMODULEANDLABELDISPLAY.contains(register_selected))
{
newText = string_text;
}
// 优先级2:如果是NTSTATUS状态码
else if(hasStatusCode)
{
auto colon = strchr(status_text, ':'); // 查找冒号位置
if(colon)
*colon = '\0'; // 截断冒号后的描述,只保留状态码名称
newText = status_text;
}
// 优先级3:同时有模块名和标签
else if(hasLabel && hasModule)
{
newText = "<" + QString(module_text) + "." + QString(label_text) + ">";
}
// 优先级4:只有模块名
else if(hasModule)
{
newText = QString(module_text) + "." + valueText;
}
// 优先级5:只有标签
else if(hasLabel)
{
newText = "<" + QString(label_text) + ">";
}
// 优先级6:如果以上都没有,尝试显示为字符(仅对某些寄存器)
else if(!mONLYMODULEANDLABELDISPLAY.contains(register_selected))
{
// 检查是否可以显示为ASCII字符
if(register_value == (register_value & 0xFF))
{
QChar c = QChar((char)register_value);
if(c.isPrint()) // 如果是可打印字符
{
newText = QString("'%1'").arg((char)register_value);
}
}
// 检查是否可以显示为UNICODE字符
else if(register_value == (register_value & 0xFFF)) //UNICODE?
{
QChar c = QChar((wchar_t)register_value);
if(c.isPrint()) // 如果是可打印字符
{
newText = "L'" + QString(c) + "'";
}
}
}
return std::move(newText); // 返回结果文本
}
函数功能总结:
这个函数用于在调试器中显示寄存器的"智能"信息,按照以下优先级显示:
- 字符串内容(如果寄存器指向可读字符串)
- NTSTATUS状态码描述(仅对EAX/RAX)
- 模块名+标签组合
- 模块名+地址
- 标签名
- ASCII/Unicode字符表示(如果值是单个字符)
|