Skip to content

Commit 18f70cd

Browse files
plafossebdash
authored andcommitted
[PseudoC] Fix handling of struct field accesses
* Accesses at offset zero were not handled. * The pointer arithmetic and casts that were generated were incorrect in some cases. Fixes #6825.
1 parent 2b3ce70 commit 18f70cd

File tree

1 file changed

+74
-68
lines changed

1 file changed

+74
-68
lines changed

lang/c/pseudoc.cpp

Lines changed: 74 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2569,91 +2569,97 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H
25692569
if (type && (type->GetClass() == NamedTypeReferenceClass))
25702570
type = GetFunction()->GetView()->GetTypeByRef(type->GetNamedTypeReference());
25712571

2572-
bool derefOffset = false;
2572+
// Try to resolve as a structure member access
25732573
if (type && (type->GetClass() == StructureTypeClass))
25742574
{
2575-
std::optional<size_t> memberIndexHint;
2576-
if (memberIndex != BN_INVALID_EXPR)
2577-
memberIndexHint = memberIndex;
2575+
auto memberIndexHint = memberIndex != BN_INVALID_EXPR ? std::make_optional(memberIndex) : std::nullopt;
25782576

25792577
bool outer = true;
2580-
if (type->GetStructure()->ResolveMemberOrBaseMember(GetFunction()->GetView(), offset, 0,
2581-
[&](NamedTypeReference*, Structure* s, size_t memberIndex, uint64_t structOffset,
2582-
uint64_t adjustedOffset, const StructureMember& member) {
2583-
BNSymbolDisplayResult symbolType;
2584-
if (srcExpr.operation == HLIL_CONST_PTR)
2585-
{
2586-
const auto constant = srcExpr.GetConstant<HLIL_CONST_PTR>();
2587-
symbolType = tokens.AppendPointerTextToken(
2588-
srcExpr, constant, settings, DisplaySymbolOnly, precedence);
2589-
}
2590-
else
2591-
{
2592-
GetExprTextInternal(srcExpr, tokens, settings, MemberAndFunctionOperatorPrecedence);
2593-
symbolType = OtherSymbolResult;
2594-
}
2595-
2596-
const auto displayDeref = symbolType != DataSymbolResult;
2597-
if (displayDeref && outer)
2598-
tokens.Append(OperationToken, "->");
2599-
else
2600-
tokens.Append(OperationToken, ".");
2601-
outer = false;
2602-
2603-
vector<string> nameList {member.name};
2604-
HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(
2605-
GetFunction()->GetView(), type, srcExpr, nameList);
2606-
2607-
tokens.Append(FieldNameToken, member.name, structOffset + member.offset, 0, 0,
2608-
BN_FULL_CONFIDENCE, nameList);
2609-
}),
2610-
memberIndexHint)
2578+
auto renderMember = [&](NamedTypeReference*, Structure* s, size_t memberIndex,
2579+
uint64_t structOffset, uint64_t adjustedOffset, const StructureMember& member) {
2580+
BNSymbolDisplayResult symbolType;
2581+
if (srcExpr.operation == HLIL_CONST_PTR)
2582+
{
2583+
const auto constant = srcExpr.GetConstant<HLIL_CONST_PTR>();
2584+
symbolType = tokens.AppendPointerTextToken(
2585+
srcExpr, constant, settings, DisplaySymbolOnly, precedence);
2586+
}
2587+
else
2588+
{
2589+
GetExprTextInternal(srcExpr, tokens, settings, MemberAndFunctionOperatorPrecedence);
2590+
symbolType = OtherSymbolResult;
2591+
}
2592+
2593+
const auto useArrow = (symbolType != DataSymbolResult) && outer;
2594+
tokens.Append(OperationToken, useArrow ? "->" : ".");
2595+
outer = false;
2596+
2597+
vector<string> nameList {member.name};
2598+
HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(
2599+
GetFunction()->GetView(), type, srcExpr, nameList);
2600+
2601+
tokens.Append(FieldNameToken, member.name, structOffset + member.offset, 0, 0,
2602+
BN_FULL_CONFIDENCE, nameList);
2603+
};
2604+
2605+
bool memberResolved = type->GetStructure()->ResolveMemberOrBaseMember(
2606+
GetFunction()->GetView(), offset, 0, renderMember, memberIndexHint);
2607+
2608+
if (memberResolved)
26112609
return;
26122610
}
2613-
else if (type && (type->GetClass() == StructureTypeClass))
2614-
{
2615-
derefOffset = true;
2616-
}
26172611

2618-
if (derefOffset || offset != 0)
2619-
{
2620-
bool parens = precedence > UnaryOperatorPrecedence;
2621-
if (parens)
2622-
tokens.AppendOpenParen();
2612+
// Member resolution failed or not a structure - render as pointer arithmetic
2613+
// Structure: *(type_cast)(char_cast pointer + offset)
26232614

2624-
tokens.Append(OperationToken, "*");
2625-
if (!settings || settings->IsOptionSet(ShowTypeCasts))
2626-
{
2627-
tokens.AppendOpenParen();
2628-
AppendSizeToken(!derefOffset ? srcExpr.size : instr.size, true, tokens);
2629-
tokens.Append(TextToken, "*");
2630-
tokens.AppendCloseParen();
2631-
}
2615+
bool needsOuterParens = precedence > UnaryOperatorPrecedence;
2616+
bool showsTypeCasts = !settings || settings->IsOptionSet(ShowTypeCasts);
2617+
bool needsTypeCast = instr.size > 1 && showsTypeCasts;
2618+
bool hasOffset = offset != 0;
2619+
2620+
if (needsOuterParens)
26322621
tokens.AppendOpenParen();
2633-
if (!settings || settings->IsOptionSet(ShowTypeCasts))
2622+
2623+
tokens.Append(OperationToken, "*");
2624+
2625+
if (needsTypeCast)
2626+
{
2627+
tokens.AppendOpenParen();
2628+
AppendSizeToken(instr.size, true, tokens);
2629+
tokens.Append(TextToken, "*");
2630+
tokens.AppendCloseParen();
2631+
}
2632+
2633+
if (hasOffset) {
2634+
tokens.AppendOpenParen();
2635+
if (showsTypeCasts)
26342636
{
26352637
tokens.AppendOpenParen();
2636-
tokens.Append(TypeNameToken, "char");
2638+
tokens.Append(KeywordToken, "char");
26372639
tokens.Append(TextToken, "*");
26382640
tokens.AppendCloseParen();
26392641
}
2640-
2641-
if (srcExpr.operation == HLIL_CONST_PTR)
2642-
{
2643-
const auto constant = srcExpr.GetConstant<HLIL_CONST_PTR>();
2644-
tokens.AppendPointerTextToken(srcExpr, constant, settings, DisplaySymbolOnly, precedence);
2645-
}
2646-
else
2647-
{
2648-
GetExprTextInternal(srcExpr, tokens, settings, AddOperatorPrecedence);
2649-
}
2650-
2642+
}
2643+
2644+
if (srcExpr.operation == HLIL_CONST_PTR)
2645+
{
2646+
const auto constant = srcExpr.GetConstant<HLIL_CONST_PTR>();
2647+
tokens.AppendPointerTextToken(srcExpr, constant, settings, DisplaySymbolOnly, precedence);
2648+
}
2649+
else
2650+
{
2651+
GetExprTextInternal(srcExpr, tokens, settings, AddOperatorPrecedence);
2652+
}
2653+
2654+
if (hasOffset)
2655+
{
26512656
tokens.Append(OperationToken, " + ");
26522657
tokens.AppendIntegerTextToken(instr, offset, instr.size);
2653-
tokens.AppendCloseParen();
2654-
if (parens)
2655-
tokens.AppendCloseParen();
2658+
tokens.AppendCloseParen(); // Close (ptr + offset)
26562659
}
2660+
2661+
if (needsOuterParens)
2662+
tokens.AppendCloseParen();
26572663

26582664
if (statement)
26592665
tokens.AppendSemicolon();

0 commit comments

Comments
 (0)