summaryrefslogtreecommitdiff
path: root/lang/c/pseudoc.cpp
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2025-11-03 20:08:15 -0500
committerRusty Wagner <rusty.wagner@gmail.com>2025-11-04 11:54:48 -0500
commitbe78ae60cb0e718227c1391b6fa46543656020cc (patch)
tree42fb24b9a29f753edc03d8a1e8479d9d2347ded6 /lang/c/pseudoc.cpp
parent90c80d946095dcd95119bbf5e79f6993640fb8f4 (diff)
Fix incorrect dereferencing in HLIL_STRUCT_FIELD rendering, and fix ignoring of signed hints in casts
Diffstat (limited to 'lang/c/pseudoc.cpp')
-rw-r--r--lang/c/pseudoc.cpp228
1 files changed, 108 insertions, 120 deletions
diff --git a/lang/c/pseudoc.cpp b/lang/c/pseudoc.cpp
index 8d806d79..a657fb71 100644
--- a/lang/c/pseudoc.cpp
+++ b/lang/c/pseudoc.cpp
@@ -423,7 +423,7 @@ PseudoCFunction::FieldDisplayType PseudoCFunction::GetFieldDisplayType(
return FieldDisplayOffset;
}
else if (deref || offset != 0)
- return FieldDisplayMemberOffset;
+ return FieldDisplayOffset;
else
return FieldDisplayNone;
}
@@ -545,11 +545,94 @@ void PseudoCFunction::AppendDefaultSplitExpr(const BinaryNinja::HighLevelILInstr
}
-void PseudoCFunction::AppendFieldTextTokens(const HighLevelILInstruction& var, uint64_t offset,
- size_t memberIndex, size_t size, HighLevelILTokenEmitter& tokens, bool deref, bool displayDeref)
+void PseudoCFunction::AppendFieldTextTokens(const HighLevelILInstruction& instr, HighLevelILTokenEmitter& tokens,
+ DisassemblySettings* settings, std::optional<bool> signedHint, bool addrOf)
{
- const auto type = GetFieldType(var, deref);
- const auto fieldDisplayType = GetFieldDisplayType(type, offset, memberIndex, deref);
+ const auto srcExpr = instr.GetSourceExpr<HLIL_STRUCT_FIELD>();
+ const auto fieldOffset = instr.GetOffset<HLIL_STRUCT_FIELD>();
+ const auto memberIndex = instr.GetMemberIndex<HLIL_STRUCT_FIELD>();
+
+ const auto type = GetFieldType(srcExpr, false);
+ const auto fieldDisplayType = GetFieldDisplayType(type, fieldOffset, memberIndex, false);
+ if (fieldDisplayType == FieldDisplayOffset)
+ {
+ if (!addrOf)
+ tokens.Append(OperationToken, "*");
+ if (!settings || settings->IsOptionSet(ShowTypeCasts))
+ {
+ tokens.AppendOpenParen();
+ AppendSizeToken(!instr.size ? srcExpr.size : instr.size, signedHint.value_or(false), tokens);
+ tokens.Append(TextToken, "*");
+ tokens.AppendCloseParen();
+ }
+ tokens.AppendOpenParen();
+ if (!settings || settings->IsOptionSet(ShowTypeCasts))
+ {
+ tokens.AppendOpenParen();
+ tokens.Append(TypeNameToken, "char");
+ tokens.Append(TextToken, "*");
+ tokens.AppendCloseParen();
+ }
+ tokens.Append(OperationToken, "&");
+ GetExprTextInternal(srcExpr, tokens, settings, UnaryOperatorPrecedence);
+
+ tokens.Append(OperationToken, " + ");
+ tokens.AppendIntegerTextToken(instr, fieldOffset, instr.size);
+ tokens.AppendCloseParen();
+
+ char offsetStr[64];
+ snprintf(offsetStr, sizeof(offsetStr), "0x%" PRIx64, fieldOffset);
+
+ vector<string> nameList {offsetStr};
+ HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(GetFunction()->GetView(), type, srcExpr, nameList);
+ }
+ else
+ {
+ BNOperatorPrecedence precedence = UnaryOperatorPrecedence;
+ if ((!settings || settings->IsOptionSet(ShowTypeCasts)) && srcExpr.operation == HLIL_ARRAY_INDEX)
+ {
+ auto arrayIndexExpr = srcExpr.GetSourceExpr<HLIL_ARRAY_INDEX>();
+ if (arrayIndexExpr.operation == HLIL_VAR
+ && arrayIndexExpr.GetType()->GetChildType()->GetWidth() < instr.size)
+ {
+ if (!addrOf)
+ tokens.Append(TextToken, "*");
+ tokens.AppendOpenParen();
+ AppendSizeToken(instr.size, signedHint.value_or(false), tokens);
+ tokens.Append(TextToken, "*");
+ tokens.AppendCloseParen();
+ tokens.Append(OperationToken, "&");
+ }
+ else if (addrOf)
+ {
+ tokens.Append(OperationToken, "&");
+ }
+ }
+ else if ((!settings || settings->IsOptionSet(ShowTypeCasts)) && srcExpr.operation == HLIL_VAR)
+ {
+ if (srcExpr.GetType().GetValue() && srcExpr.GetType()->GetClass() != StructureTypeClass
+ && srcExpr.size > instr.size)
+ {
+ if (addrOf)
+ tokens.Append(OperationToken, "&");
+ tokens.AppendOpenParen();
+ AppendSizeToken(instr.size, signedHint.value_or(false), tokens);
+ tokens.AppendCloseParen();
+ precedence = MemberAndFunctionOperatorPrecedence;
+ }
+ else if (addrOf)
+ {
+ tokens.Append(OperationToken, "&");
+ }
+ }
+ else if (addrOf)
+ {
+ tokens.Append(OperationToken, "&");
+ }
+
+ GetExprTextInternal(srcExpr, tokens, settings, precedence);
+ }
+
switch (fieldDisplayType)
{
case FieldDisplayName:
@@ -558,18 +641,15 @@ void PseudoCFunction::AppendFieldTextTokens(const HighLevelILInstruction& var, u
if (memberIndex != BN_INVALID_EXPR)
memberIndexHint = memberIndex;
- if (type->GetStructure()->ResolveMemberOrBaseMember(GetFunction()->GetView(), offset, 0,
+ if (type->GetStructure()->ResolveMemberOrBaseMember(
+ GetFunction()->GetView(), fieldOffset, 0,
[&](NamedTypeReference*, Structure* s, size_t memberIndex, uint64_t structOffset,
uint64_t adjustedOffset, const StructureMember& member) {
- if (deref && displayDeref)
- tokens.Append(OperationToken, "->");
- else
- tokens.Append(OperationToken, ".");
- deref = false;
+ tokens.Append(OperationToken, ".");
vector<string> nameList {member.name};
HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(
- GetFunction()->GetView(), type, var, nameList);
+ GetFunction()->GetView(), type, srcExpr, nameList);
tokens.Append(FieldNameToken, member.name, structOffset + member.offset, 0, 0,
BN_FULL_CONFIDENCE, nameList);
@@ -578,18 +658,16 @@ void PseudoCFunction::AppendFieldTextTokens(const HighLevelILInstruction& var, u
return;
// Part of structure but no defined field, use __offset syntax
- if (deref && displayDeref)
- tokens.Append(OperationToken, "->");
- else
- tokens.Append(OperationToken, ".");
+ tokens.Append(OperationToken, ".");
char offsetStr[64];
- snprintf(
- offsetStr, sizeof(offsetStr), "__offset(0x%" PRIx64 ")%s", offset, Type::GetSizeSuffix(size).c_str());
+ snprintf(offsetStr, sizeof(offsetStr), "__offset(0x%" PRIx64 ")%s", fieldOffset,
+ Type::GetSizeSuffix(instr.size).c_str());
vector<string> nameList {offsetStr};
- HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(GetFunction()->GetView(), type, var, nameList);
+ HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(
+ GetFunction()->GetView(), type, srcExpr, nameList);
- tokens.Append(StructOffsetToken, offsetStr, offset, size, 0, BN_FULL_CONFIDENCE, nameList);
+ tokens.Append(StructOffsetToken, offsetStr, fieldOffset, instr.size, 0, BN_FULL_CONFIDENCE, nameList);
return;
}
@@ -599,14 +677,6 @@ void PseudoCFunction::AppendFieldTextTokens(const HighLevelILInstruction& var, u
return;
}
- case FieldDisplayMemberOffset:
- {
- tokens.AppendOpenBracket();
- tokens.AppendIntegerTextToken(var, offset, size);
- tokens.AppendCloseBracket();
- return;
- }
-
default: break;
}
}
@@ -1568,96 +1638,7 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H
case HLIL_STRUCT_FIELD:
[&]() {
- const auto srcExpr = instr.GetSourceExpr<HLIL_STRUCT_FIELD>();
- const auto fieldOffset = instr.GetOffset<HLIL_STRUCT_FIELD>();
- const auto memberIndex = instr.GetMemberIndex<HLIL_STRUCT_FIELD>();
-
- const auto type = GetFieldType(srcExpr, false);
- const auto fieldDisplayType = GetFieldDisplayType(type, fieldOffset, memberIndex, false);
- if (fieldDisplayType == FieldDisplayOffset)
- {
- tokens.Append(OperationToken, "*");
- if (!settings || settings->IsOptionSet(ShowTypeCasts))
- {
- tokens.AppendOpenParen();
- AppendSizeToken(!instr.size ? srcExpr.size : instr.size, false, tokens);
- tokens.Append(TextToken, "*");
- tokens.AppendCloseParen();
- }
- tokens.AppendOpenParen();
- if (!settings || settings->IsOptionSet(ShowTypeCasts))
- {
- tokens.AppendOpenParen();
- tokens.Append(TypeNameToken, "char");
- tokens.Append(TextToken, "*");
- tokens.AppendCloseParen();
- }
- GetExprTextInternal(srcExpr, tokens, settings, MemberAndFunctionOperatorPrecedence);
-
- tokens.Append(OperationToken, " + ");
- tokens.AppendIntegerTextToken(instr, fieldOffset, instr.size);
- tokens.AppendCloseParen();
-
- char offsetStr[64];
- snprintf(offsetStr, sizeof(offsetStr), "0x%" PRIx64, fieldOffset);
-
- vector<string> nameList { offsetStr };
- HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(
- GetFunction()->GetView(), type, srcExpr, nameList);
- }
- else if (fieldDisplayType == FieldDisplayMemberOffset)
- {
- tokens.Append(OperationToken, "*");
- if (!settings || settings->IsOptionSet(ShowTypeCasts))
- {
- tokens.AppendOpenParen();
- AppendSizeToken(!instr.size ? srcExpr.size : instr.size, false, tokens);
- tokens.Append(TextToken, "*");
- tokens.AppendCloseParen();
- tokens.AppendOpenParen();
- tokens.AppendOpenParen();
- tokens.Append(TypeNameToken, "char");
- tokens.Append(TextToken, "*");
- tokens.AppendCloseParen();
- }
- GetExprTextInternal(srcExpr, tokens, settings, MemberAndFunctionOperatorPrecedence);
- if (!settings || settings->IsOptionSet(ShowTypeCasts))
- {
- tokens.AppendCloseParen();
- }
- /* rest is rendered in AppendFieldTextTokens */
- }
- else
- {
- if ((!settings || settings->IsOptionSet(ShowTypeCasts)) && srcExpr.operation == HLIL_ARRAY_INDEX)
- {
- auto arrayIndexExpr = srcExpr.GetSourceExpr<HLIL_ARRAY_INDEX>();
- if (arrayIndexExpr.operation == HLIL_VAR &&
- arrayIndexExpr.GetType()->GetChildType()->GetWidth() < instr.size)
- {
- tokens.Append(TextToken, "*");
- tokens.AppendOpenParen();
- AppendSizeToken(instr.size, false, tokens);
- tokens.Append(TextToken, "*");
- tokens.AppendCloseParen();
- tokens.Append(OperationToken, "&");
- }
- }
- else if ((!settings || settings->IsOptionSet(ShowTypeCasts)) && srcExpr.operation == HLIL_VAR)
- {
- if (srcExpr.GetType().GetValue() && srcExpr.GetType()->GetClass() != StructureTypeClass
- && srcExpr.size > instr.size)
- {
- tokens.AppendOpenParen();
- AppendSizeToken(instr.size, false, tokens);
- tokens.AppendCloseParen();
- }
- }
-
- GetExprTextInternal(srcExpr, tokens, settings, MemberAndFunctionOperatorPrecedence);
- }
-
- AppendFieldTextTokens(srcExpr, fieldOffset, memberIndex, instr.size, tokens, false);
+ AppendFieldTextTokens(instr, tokens, settings, signedHint, false);
if (statement)
tokens.AppendSemicolon();
}();
@@ -1804,8 +1785,15 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H
bool parens = precedence > UnaryOperatorPrecedence;
if (parens)
tokens.AppendOpenParen();
- tokens.Append(OperationToken, "&");
- GetExprTextInternal(srcExpr, tokens, settings, UnaryOperatorPrecedence);
+ if (srcExpr.operation == HLIL_STRUCT_FIELD)
+ {
+ AppendFieldTextTokens(srcExpr, tokens, settings, signedHint, true);
+ }
+ else
+ {
+ tokens.Append(OperationToken, "&");
+ GetExprTextInternal(srcExpr, tokens, settings, UnaryOperatorPrecedence);
+ }
if (parens)
tokens.AppendCloseParen();
if (statement)