Skip to content

Commit c5ff713

Browse files
plafossebdash
authored andcommitted
[PseudoC] Fix handling of struct field accesses
* Accesses at offset zero were not handled. * The pointer arithmetic that was generated was incorrect for pointers with types other than `uint8_t` / `char` Fixes #6825.
1 parent 55d3bda commit c5ff713

File tree

1 file changed

+77
-72
lines changed

1 file changed

+77
-72
lines changed

lang/c/pseudoc.cpp

Lines changed: 77 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2569,91 +2569,96 @@ 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))
2611+
2612+
// Member resolution failed or not a structure - render as pointer arithmetic
2613+
// Structure: *(type_cast)(char_cast pointer + offset)
2614+
2615+
bool needsOuterParens = precedence > UnaryOperatorPrecedence;
2616+
bool needsTypeCast = instr.size != 1 && (!settings || settings->IsOptionSet(ShowTypeCasts));
2617+
bool hasOffset = offset != 0;
2618+
2619+
if (needsOuterParens)
2620+
tokens.AppendOpenParen();
2621+
2622+
tokens.Append(OperationToken, "*");
2623+
2624+
if (needsTypeCast)
26142625
{
2615-
derefOffset = true;
2626+
tokens.AppendOpenParen();
2627+
AppendSizeToken(instr.size, true, tokens);
2628+
tokens.Append(TextToken, "*");
2629+
tokens.AppendCloseParen();
26162630
}
2617-
2618-
if (derefOffset || offset != 0)
2631+
2632+
if (hasOffset)
26192633
{
2620-
bool parens = precedence > UnaryOperatorPrecedence;
2621-
if (parens)
2622-
tokens.AppendOpenParen();
2623-
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-
}
26322634
tokens.AppendOpenParen();
2633-
if (!settings || settings->IsOptionSet(ShowTypeCasts))
2634-
{
2635-
tokens.AppendOpenParen();
2636-
tokens.Append(TypeNameToken, "char");
2637-
tokens.Append(TextToken, "*");
2638-
tokens.AppendCloseParen();
2639-
}
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-
2635+
2636+
// Cast to char* for byte arithmetic
2637+
tokens.AppendOpenParen();
2638+
tokens.Append(KeywordToken, "char");
2639+
tokens.Append(TextToken, "*");
2640+
tokens.AppendCloseParen();
2641+
}
2642+
2643+
if (srcExpr.operation == HLIL_CONST_PTR)
2644+
{
2645+
const auto constant = srcExpr.GetConstant<HLIL_CONST_PTR>();
2646+
tokens.AppendPointerTextToken(srcExpr, constant, settings, DisplaySymbolOnly, precedence);
2647+
}
2648+
else
2649+
{
2650+
GetExprTextInternal(srcExpr, tokens, settings, AddOperatorPrecedence);
2651+
}
2652+
2653+
if (hasOffset)
2654+
{
26512655
tokens.Append(OperationToken, " + ");
26522656
tokens.AppendIntegerTextToken(instr, offset, instr.size);
2653-
tokens.AppendCloseParen();
2654-
if (parens)
2655-
tokens.AppendCloseParen();
2657+
tokens.AppendCloseParen(); // Close (ptr + offset)
26562658
}
2659+
2660+
if (needsOuterParens)
2661+
tokens.AppendCloseParen();
26572662

26582663
if (statement)
26592664
tokens.AppendSemicolon();

0 commit comments

Comments
 (0)