Skip to content

Commit be78ae6

Browse files
committed
Fix incorrect dereferencing in HLIL_STRUCT_FIELD rendering, and fix ignoring of signed hints in casts
1 parent 90c80d9 commit be78ae6

File tree

4 files changed

+232
-249
lines changed

4 files changed

+232
-249
lines changed

lang/c/pseudoc.cpp

Lines changed: 108 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ PseudoCFunction::FieldDisplayType PseudoCFunction::GetFieldDisplayType(
423423
return FieldDisplayOffset;
424424
}
425425
else if (deref || offset != 0)
426-
return FieldDisplayMemberOffset;
426+
return FieldDisplayOffset;
427427
else
428428
return FieldDisplayNone;
429429
}
@@ -545,11 +545,94 @@ void PseudoCFunction::AppendDefaultSplitExpr(const BinaryNinja::HighLevelILInstr
545545
}
546546

547547

548-
void PseudoCFunction::AppendFieldTextTokens(const HighLevelILInstruction& var, uint64_t offset,
549-
size_t memberIndex, size_t size, HighLevelILTokenEmitter& tokens, bool deref, bool displayDeref)
548+
void PseudoCFunction::AppendFieldTextTokens(const HighLevelILInstruction& instr, HighLevelILTokenEmitter& tokens,
549+
DisassemblySettings* settings, std::optional<bool> signedHint, bool addrOf)
550550
{
551-
const auto type = GetFieldType(var, deref);
552-
const auto fieldDisplayType = GetFieldDisplayType(type, offset, memberIndex, deref);
551+
const auto srcExpr = instr.GetSourceExpr<HLIL_STRUCT_FIELD>();
552+
const auto fieldOffset = instr.GetOffset<HLIL_STRUCT_FIELD>();
553+
const auto memberIndex = instr.GetMemberIndex<HLIL_STRUCT_FIELD>();
554+
555+
const auto type = GetFieldType(srcExpr, false);
556+
const auto fieldDisplayType = GetFieldDisplayType(type, fieldOffset, memberIndex, false);
557+
if (fieldDisplayType == FieldDisplayOffset)
558+
{
559+
if (!addrOf)
560+
tokens.Append(OperationToken, "*");
561+
if (!settings || settings->IsOptionSet(ShowTypeCasts))
562+
{
563+
tokens.AppendOpenParen();
564+
AppendSizeToken(!instr.size ? srcExpr.size : instr.size, signedHint.value_or(false), tokens);
565+
tokens.Append(TextToken, "*");
566+
tokens.AppendCloseParen();
567+
}
568+
tokens.AppendOpenParen();
569+
if (!settings || settings->IsOptionSet(ShowTypeCasts))
570+
{
571+
tokens.AppendOpenParen();
572+
tokens.Append(TypeNameToken, "char");
573+
tokens.Append(TextToken, "*");
574+
tokens.AppendCloseParen();
575+
}
576+
tokens.Append(OperationToken, "&");
577+
GetExprTextInternal(srcExpr, tokens, settings, UnaryOperatorPrecedence);
578+
579+
tokens.Append(OperationToken, " + ");
580+
tokens.AppendIntegerTextToken(instr, fieldOffset, instr.size);
581+
tokens.AppendCloseParen();
582+
583+
char offsetStr[64];
584+
snprintf(offsetStr, sizeof(offsetStr), "0x%" PRIx64, fieldOffset);
585+
586+
vector<string> nameList {offsetStr};
587+
HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(GetFunction()->GetView(), type, srcExpr, nameList);
588+
}
589+
else
590+
{
591+
BNOperatorPrecedence precedence = UnaryOperatorPrecedence;
592+
if ((!settings || settings->IsOptionSet(ShowTypeCasts)) && srcExpr.operation == HLIL_ARRAY_INDEX)
593+
{
594+
auto arrayIndexExpr = srcExpr.GetSourceExpr<HLIL_ARRAY_INDEX>();
595+
if (arrayIndexExpr.operation == HLIL_VAR
596+
&& arrayIndexExpr.GetType()->GetChildType()->GetWidth() < instr.size)
597+
{
598+
if (!addrOf)
599+
tokens.Append(TextToken, "*");
600+
tokens.AppendOpenParen();
601+
AppendSizeToken(instr.size, signedHint.value_or(false), tokens);
602+
tokens.Append(TextToken, "*");
603+
tokens.AppendCloseParen();
604+
tokens.Append(OperationToken, "&");
605+
}
606+
else if (addrOf)
607+
{
608+
tokens.Append(OperationToken, "&");
609+
}
610+
}
611+
else if ((!settings || settings->IsOptionSet(ShowTypeCasts)) && srcExpr.operation == HLIL_VAR)
612+
{
613+
if (srcExpr.GetType().GetValue() && srcExpr.GetType()->GetClass() != StructureTypeClass
614+
&& srcExpr.size > instr.size)
615+
{
616+
if (addrOf)
617+
tokens.Append(OperationToken, "&");
618+
tokens.AppendOpenParen();
619+
AppendSizeToken(instr.size, signedHint.value_or(false), tokens);
620+
tokens.AppendCloseParen();
621+
precedence = MemberAndFunctionOperatorPrecedence;
622+
}
623+
else if (addrOf)
624+
{
625+
tokens.Append(OperationToken, "&");
626+
}
627+
}
628+
else if (addrOf)
629+
{
630+
tokens.Append(OperationToken, "&");
631+
}
632+
633+
GetExprTextInternal(srcExpr, tokens, settings, precedence);
634+
}
635+
553636
switch (fieldDisplayType)
554637
{
555638
case FieldDisplayName:
@@ -558,18 +641,15 @@ void PseudoCFunction::AppendFieldTextTokens(const HighLevelILInstruction& var, u
558641
if (memberIndex != BN_INVALID_EXPR)
559642
memberIndexHint = memberIndex;
560643

561-
if (type->GetStructure()->ResolveMemberOrBaseMember(GetFunction()->GetView(), offset, 0,
644+
if (type->GetStructure()->ResolveMemberOrBaseMember(
645+
GetFunction()->GetView(), fieldOffset, 0,
562646
[&](NamedTypeReference*, Structure* s, size_t memberIndex, uint64_t structOffset,
563647
uint64_t adjustedOffset, const StructureMember& member) {
564-
if (deref && displayDeref)
565-
tokens.Append(OperationToken, "->");
566-
else
567-
tokens.Append(OperationToken, ".");
568-
deref = false;
648+
tokens.Append(OperationToken, ".");
569649

570650
vector<string> nameList {member.name};
571651
HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(
572-
GetFunction()->GetView(), type, var, nameList);
652+
GetFunction()->GetView(), type, srcExpr, nameList);
573653

574654
tokens.Append(FieldNameToken, member.name, structOffset + member.offset, 0, 0,
575655
BN_FULL_CONFIDENCE, nameList);
@@ -578,18 +658,16 @@ void PseudoCFunction::AppendFieldTextTokens(const HighLevelILInstruction& var, u
578658
return;
579659

580660
// Part of structure but no defined field, use __offset syntax
581-
if (deref && displayDeref)
582-
tokens.Append(OperationToken, "->");
583-
else
584-
tokens.Append(OperationToken, ".");
661+
tokens.Append(OperationToken, ".");
585662
char offsetStr[64];
586-
snprintf(
587-
offsetStr, sizeof(offsetStr), "__offset(0x%" PRIx64 ")%s", offset, Type::GetSizeSuffix(size).c_str());
663+
snprintf(offsetStr, sizeof(offsetStr), "__offset(0x%" PRIx64 ")%s", fieldOffset,
664+
Type::GetSizeSuffix(instr.size).c_str());
588665

589666
vector<string> nameList {offsetStr};
590-
HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(GetFunction()->GetView(), type, var, nameList);
667+
HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(
668+
GetFunction()->GetView(), type, srcExpr, nameList);
591669

592-
tokens.Append(StructOffsetToken, offsetStr, offset, size, 0, BN_FULL_CONFIDENCE, nameList);
670+
tokens.Append(StructOffsetToken, offsetStr, fieldOffset, instr.size, 0, BN_FULL_CONFIDENCE, nameList);
593671
return;
594672
}
595673

@@ -599,14 +677,6 @@ void PseudoCFunction::AppendFieldTextTokens(const HighLevelILInstruction& var, u
599677
return;
600678
}
601679

602-
case FieldDisplayMemberOffset:
603-
{
604-
tokens.AppendOpenBracket();
605-
tokens.AppendIntegerTextToken(var, offset, size);
606-
tokens.AppendCloseBracket();
607-
return;
608-
}
609-
610680
default: break;
611681
}
612682
}
@@ -1568,96 +1638,7 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H
15681638

15691639
case HLIL_STRUCT_FIELD:
15701640
[&]() {
1571-
const auto srcExpr = instr.GetSourceExpr<HLIL_STRUCT_FIELD>();
1572-
const auto fieldOffset = instr.GetOffset<HLIL_STRUCT_FIELD>();
1573-
const auto memberIndex = instr.GetMemberIndex<HLIL_STRUCT_FIELD>();
1574-
1575-
const auto type = GetFieldType(srcExpr, false);
1576-
const auto fieldDisplayType = GetFieldDisplayType(type, fieldOffset, memberIndex, false);
1577-
if (fieldDisplayType == FieldDisplayOffset)
1578-
{
1579-
tokens.Append(OperationToken, "*");
1580-
if (!settings || settings->IsOptionSet(ShowTypeCasts))
1581-
{
1582-
tokens.AppendOpenParen();
1583-
AppendSizeToken(!instr.size ? srcExpr.size : instr.size, false, tokens);
1584-
tokens.Append(TextToken, "*");
1585-
tokens.AppendCloseParen();
1586-
}
1587-
tokens.AppendOpenParen();
1588-
if (!settings || settings->IsOptionSet(ShowTypeCasts))
1589-
{
1590-
tokens.AppendOpenParen();
1591-
tokens.Append(TypeNameToken, "char");
1592-
tokens.Append(TextToken, "*");
1593-
tokens.AppendCloseParen();
1594-
}
1595-
GetExprTextInternal(srcExpr, tokens, settings, MemberAndFunctionOperatorPrecedence);
1596-
1597-
tokens.Append(OperationToken, " + ");
1598-
tokens.AppendIntegerTextToken(instr, fieldOffset, instr.size);
1599-
tokens.AppendCloseParen();
1600-
1601-
char offsetStr[64];
1602-
snprintf(offsetStr, sizeof(offsetStr), "0x%" PRIx64, fieldOffset);
1603-
1604-
vector<string> nameList { offsetStr };
1605-
HighLevelILTokenEmitter::AddNamesForOuterStructureMembers(
1606-
GetFunction()->GetView(), type, srcExpr, nameList);
1607-
}
1608-
else if (fieldDisplayType == FieldDisplayMemberOffset)
1609-
{
1610-
tokens.Append(OperationToken, "*");
1611-
if (!settings || settings->IsOptionSet(ShowTypeCasts))
1612-
{
1613-
tokens.AppendOpenParen();
1614-
AppendSizeToken(!instr.size ? srcExpr.size : instr.size, false, tokens);
1615-
tokens.Append(TextToken, "*");
1616-
tokens.AppendCloseParen();
1617-
tokens.AppendOpenParen();
1618-
tokens.AppendOpenParen();
1619-
tokens.Append(TypeNameToken, "char");
1620-
tokens.Append(TextToken, "*");
1621-
tokens.AppendCloseParen();
1622-
}
1623-
GetExprTextInternal(srcExpr, tokens, settings, MemberAndFunctionOperatorPrecedence);
1624-
if (!settings || settings->IsOptionSet(ShowTypeCasts))
1625-
{
1626-
tokens.AppendCloseParen();
1627-
}
1628-
/* rest is rendered in AppendFieldTextTokens */
1629-
}
1630-
else
1631-
{
1632-
if ((!settings || settings->IsOptionSet(ShowTypeCasts)) && srcExpr.operation == HLIL_ARRAY_INDEX)
1633-
{
1634-
auto arrayIndexExpr = srcExpr.GetSourceExpr<HLIL_ARRAY_INDEX>();
1635-
if (arrayIndexExpr.operation == HLIL_VAR &&
1636-
arrayIndexExpr.GetType()->GetChildType()->GetWidth() < instr.size)
1637-
{
1638-
tokens.Append(TextToken, "*");
1639-
tokens.AppendOpenParen();
1640-
AppendSizeToken(instr.size, false, tokens);
1641-
tokens.Append(TextToken, "*");
1642-
tokens.AppendCloseParen();
1643-
tokens.Append(OperationToken, "&");
1644-
}
1645-
}
1646-
else if ((!settings || settings->IsOptionSet(ShowTypeCasts)) && srcExpr.operation == HLIL_VAR)
1647-
{
1648-
if (srcExpr.GetType().GetValue() && srcExpr.GetType()->GetClass() != StructureTypeClass
1649-
&& srcExpr.size > instr.size)
1650-
{
1651-
tokens.AppendOpenParen();
1652-
AppendSizeToken(instr.size, false, tokens);
1653-
tokens.AppendCloseParen();
1654-
}
1655-
}
1656-
1657-
GetExprTextInternal(srcExpr, tokens, settings, MemberAndFunctionOperatorPrecedence);
1658-
}
1659-
1660-
AppendFieldTextTokens(srcExpr, fieldOffset, memberIndex, instr.size, tokens, false);
1641+
AppendFieldTextTokens(instr, tokens, settings, signedHint, false);
16611642
if (statement)
16621643
tokens.AppendSemicolon();
16631644
}();
@@ -1804,8 +1785,15 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H
18041785
bool parens = precedence > UnaryOperatorPrecedence;
18051786
if (parens)
18061787
tokens.AppendOpenParen();
1807-
tokens.Append(OperationToken, "&");
1808-
GetExprTextInternal(srcExpr, tokens, settings, UnaryOperatorPrecedence);
1788+
if (srcExpr.operation == HLIL_STRUCT_FIELD)
1789+
{
1790+
AppendFieldTextTokens(srcExpr, tokens, settings, signedHint, true);
1791+
}
1792+
else
1793+
{
1794+
tokens.Append(OperationToken, "&");
1795+
GetExprTextInternal(srcExpr, tokens, settings, UnaryOperatorPrecedence);
1796+
}
18091797
if (parens)
18101798
tokens.AppendCloseParen();
18111799
if (statement)

lang/c/pseudoc.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ class PseudoCFunction: public BinaryNinja::LanguageRepresentationFunction
1212
{
1313
FieldDisplayName,
1414
FieldDisplayOffset,
15-
FieldDisplayMemberOffset,
1615
FieldDisplayNone
1716
};
1817

@@ -52,8 +51,9 @@ class PseudoCFunction: public BinaryNinja::LanguageRepresentationFunction
5251
BinaryNinja::HighLevelILTokenEmitter& tokens, BinaryNinja::DisassemblySettings* settings, bool sizeToken = true);
5352
void AppendTwoOperandFunctionWithCarry(const std::string& function, const BinaryNinja::HighLevelILInstruction& instr,
5453
BinaryNinja::HighLevelILTokenEmitter& tokens, BinaryNinja::DisassemblySettings* settings);
55-
void AppendFieldTextTokens(const BinaryNinja::HighLevelILInstruction& var, uint64_t offset, size_t memberIndex, size_t size,
56-
BinaryNinja::HighLevelILTokenEmitter& tokens, bool deref, bool displayDeref = true);
54+
void AppendFieldTextTokens(const BinaryNinja::HighLevelILInstruction& instr,
55+
BinaryNinja::HighLevelILTokenEmitter& tokens, BinaryNinja::DisassemblySettings* settings,
56+
std::optional<bool> signedHint, bool addrOf);
5757
void AppendDefaultSplitExpr(const BinaryNinja::HighLevelILInstruction& instr, BinaryNinja::HighLevelILTokenEmitter& tokens,
5858
BinaryNinja::DisassemblySettings* settings, BNOperatorPrecedence precedence);
5959
void GetExprTextInternal(const BinaryNinja::HighLevelILInstruction& instr,

0 commit comments

Comments
 (0)