-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy path3023-fix-stack-alignment-prevents-stack-analysis-pro.patch
More file actions
152 lines (148 loc) · 5.44 KB
/
Copy path3023-fix-stack-alignment-prevents-stack-analysis-pro.patch
File metadata and controls
152 lines (148 loc) · 5.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Anciety <anciety@starcross.cn>
Date: Sat, 15 May 2021 22:29:29 +0800
Subject: [PATCH] 3023: fix stack alignment prevents stack analysis problem in
decompiler
---
.../src/decompile/cpp/coreaction.cc | 1 +
.../src/decompile/cpp/ruleaction.cc | 89 +++++++++++++++++++
.../src/decompile/cpp/ruleaction.hh | 14 +++
3 files changed, 104 insertions(+)
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc
index 26b3908ed6..52dd39e377 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc
@@ -5957,6 +5957,7 @@ void ActionDatabase::universalAction(Architecture *conf)
actprop->addRule( new RuleXorCollapse("analysis") );
actprop->addRule( new RuleAddMultCollapse("analysis") );
actprop->addRule( new RuleCollapseConstants("analysis") );
+ actprop->addRule( new RuleStackAlignFix("analysis") );
actprop->addRule( new RuleTransformCpool("analysis") );
actprop->addRule( new RulePropagateCopy("analysis") );
actprop->addRule( new RuleZextEliminate("analysis") );
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
index 6d1a8053f2..49fb966239 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
@@ -4062,6 +4062,95 @@ int4 RuleXorCollapse::applyOp(PcodeOp *op,Funcdata &data)
return 1;
}
+/// \class RuleStackAlignFix
+/// \brief Fix stack align statement to avoid wrong stack analysis
+///
+/// When facing possibly dynamic stack, compiler sometimes emits stack
+/// alignment that looks like "and rsp, -0x1000" (as in x86).
+/// This would stop the constant propagation on SP thus preventing
+/// analyzing on stack variables.
+/// One example under x86 is:
+///
+/// ...
+/// mov rbp, rsp (<-- initial rsp)
+/// and rsp, -0x1000 ; stack alignment
+/// sub rsp, 0x1000 ; frame size
+/// lea r12, [rsp + 8] ; use of stack variable
+/// ...
+///
+/// Now, the use of stack variable cannot be recognized as the and
+/// prevents the further rsp analysis.
+/// This rule will fix this situation by applying:
+///
+/// (rsp + OFFSET) & MASK
+/// ==> (RSP & MASK) + (OFFSET & MASK)
+/// ==> RSP + (OFFSET & MASK)
+///
+/// This may not be constantly true as the stack frame should be
+/// a range anyway (like in above example, range from SIZE~SIZE+0x1000).
+/// And we are fixing it to be SIZE. However, this should be fine in
+/// most cases.
+void RuleStackAlignFix::getOpList(vector<uint4> &oplist) const
+
+{
+ oplist.push_back(CPUI_INT_AND);
+}
+
+bool RuleStackAlignFix::inSpacebase(Architecture *glb, Varnode *vn)
+
+{
+ if (vn->isSpacebase()) return true;
+ // If varnode itself is not spacebase, it should be at least \e input
+ // to be possibly spacebase + constant.
+ if (!vn->isInput()) return false;
+
+ if (vn->getSpace()->getType() != IPTR_SPACEBASE) return false;
+
+ return true;
+}
+
+int4 RuleStackAlignFix::applyOp(PcodeOp *op, Funcdata &data)
+
+{
+ Architecture *glb = data.getArch();
+ bool validForm = false;
+ int slot; // the slot of the constant
+
+ // Two varnodes should be one constant and one (spacebase + constant)
+ for (slot = 0; slot < 2; ++slot) {
+ if (op->getIn(slot)->isConstant() && inSpacebase(glb, op->getIn(1 - slot))) {
+ validForm = true;
+ break;
+ }
+ }
+
+ if (!validForm) return 0;
+
+ // Transform the (SP + C0) & C1 into SP = SP + C2 where C2 is the result of C0 & C1
+
+ Varnode *c0 = op->getIn(slot);
+ PcodeOp *defOp = op->getIn(1 - slot)->getDef();
+ if (defOp && defOp->numInput() > 1) {
+ Varnode *c1 = defOp->getIn(1);
+ if (c1->isConstant()) {
+ Varnode *base_vn = defOp->getIn(0);
+
+ uintb val = op->getOpcode()->evaluateBinary(
+ c0->getSize(),
+ c0->getSize(),
+ c0->getOffset(),
+ c1->getOffset()
+ );
+ Varnode *new_vn = data.newConstant(op->getIn(slot)->getSize(), val);
+ data.opSetOpcode(op, CPUI_INT_ADD);
+ data.opSetInput(op, base_vn, 0);
+ data.opSetInput(op, new_vn, 1);
+ return 1;
+ }
+ }
+ return 0;
+}
+
/// \class RuleAddMultCollapse
/// \brief Collapse constants in an additive or multiplicative expression
///
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.hh
index 783759418d..c1b9b12a22 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.hh
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.hh
@@ -770,6 +770,20 @@ public:
virtual void getOpList(vector<uint4> &oplist) const;
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
};
+
+class RuleStackAlignFix: public Rule {
+public:
+ RuleStackAlignFix(const string &g) : Rule(g, 0, "stackalignfix") {} ///< Constructor
+ virtual Rule *clone(const ActionGroupList &grouplist) const {
+ if (!grouplist.contains(getGroup())) return (Rule *) 0;
+ return new RuleStackAlignFix(getGroup());
+ }
+ virtual void getOpList(vector<uint4> &oplist) const;
+ virtual int4 applyOp(PcodeOp *op, Funcdata &data);
+private:
+ static bool inSpacebase(Architecture *glb, Varnode *vn);
+};
+
class RuleAddMultCollapse : public Rule {
public:
RuleAddMultCollapse(const string &g) : Rule(g, 0, "addmultcollapse") {} ///< Constructor
--
2.45.1