Skip to content

Commit 62b17a4

Browse files
committed
Binary: Add a final IR layer where we can add user-facing predicates on top of the final IR.
1 parent 104465f commit 62b17a4

1 file changed

Lines changed: 299 additions & 34 deletions

File tree

  • binary/ql/lib/semmle/code/binary/ast/ir
Lines changed: 299 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,328 @@
1-
import internal.Instruction2.Instruction2::Instruction2
2-
// import internal.Instruction1.Instruction1::Instruction1
3-
// import internal.Instruction0.Instruction0::Instruction0
41
import semmle.code.binary.ast.Location
52
import codeql.controlflow.SuccessorType
3+
private import semmle.code.binary.ast.ir.internal.Opcode
4+
private import semmle.code.binary.ast.ir.internal.Tags
65
private import codeql.controlflow.BasicBlock as BB
76

8-
final private class BasicBlockAlias = BasicBlock;
7+
private module FinalInstruction {
8+
private import internal.Instruction2.Instruction2::Instruction2 as Instruction
99

10-
final private class ControlFlowNodeAlias = ControlFlowNode;
10+
class Function instanceof Instruction::Function {
11+
string getName() { result = super.getName() }
1112

12-
module BinaryCfg implements BB::CfgSig<Location> {
13-
class ControlFlowNode = ControlFlowNodeAlias;
13+
string toString() { result = super.toString() }
1414

15-
class BasicBlock extends BasicBlockAlias {
16-
ControlFlowNode getNode(int i) { result = super.getNode(i) }
15+
FunEntryInstruction getEntryInstruction() { result = super.getEntryInstruction() }
1716

18-
ControlFlowNode getLastNode() { result = super.getLastNode() }
17+
BasicBlock getEntryBlock() { result = super.getEntryBlock() }
1918

20-
int length() { result = strictcount(super.getNode(_)) }
19+
Location getLocation() { result = super.getLocation() }
2120

22-
BasicBlock getASuccessor() { result = super.getASuccessor() }
21+
predicate isProgramEntryPoint() { super.isProgramEntryPoint() }
22+
}
23+
24+
class Operand instanceof Instruction::Operand {
25+
string toString() { result = super.toString() }
26+
27+
Instruction getUse() { result = super.getUse() }
28+
29+
Variable getVariable() { result = super.getVariable() }
30+
31+
Function getEnclosingFunction() { result = super.getEnclosingFunction() }
32+
33+
OperandTag getOperandTag() { result = super.getOperandTag() }
34+
35+
Location getLocation() { result = super.getLocation() }
36+
}
37+
38+
class StoreValueOperand extends Operand instanceof Instruction::StoreValueOperand { }
39+
40+
class StoreAddressOperand extends Operand instanceof Instruction::StoreAddressOperand { }
41+
42+
class UnaryOperand extends Operand instanceof Instruction::UnaryOperand { }
43+
44+
class LoadAddressOperand extends Operand instanceof Instruction::LoadAddressOperand { }
45+
46+
class ConditionOperand extends Operand instanceof Instruction::ConditionOperand { }
47+
48+
class ConditionJumpTargetOperand extends Operand instanceof Instruction::ConditionJumpTargetOperand
49+
{ }
50+
51+
class JumpTargetOperand extends Operand instanceof Instruction::JumpTargetOperand { }
52+
53+
class LeftOperand extends Operand instanceof Instruction::LeftOperand { }
54+
55+
class RightOperand extends Operand instanceof Instruction::RightOperand { }
56+
57+
class CallTargetOperand extends Operand instanceof Instruction::CallTargetOperand { }
58+
59+
class InstructionTag instanceof Instruction::InstructionTag {
60+
string toString() { result = super.toString() }
61+
}
62+
63+
class OperandTag instanceof Instruction::OperandTag {
64+
int getIndex() { result = super.getIndex() }
65+
66+
OperandTag getSuccessorTag() { result = super.getSuccessorTag() }
67+
68+
OperandTag getPredecessorTag() { result = super.getPredecessorTag() }
69+
70+
string toString() { result = super.toString() }
71+
}
72+
73+
class LeftTag extends OperandTag instanceof Instruction::LeftTag { }
74+
75+
class RightTag extends OperandTag instanceof Instruction::RightTag { }
76+
77+
class UnaryTag extends OperandTag instanceof Instruction::UnaryTag { }
78+
79+
class StoreValueTag extends OperandTag instanceof Instruction::StoreValueTag { }
80+
81+
class LoadAddressTag extends OperandTag instanceof Instruction::LoadAddressTag { }
82+
83+
class StoreAddressTag extends OperandTag instanceof Instruction::StoreAddressTag { }
84+
85+
class CallTargetTag extends OperandTag instanceof Instruction::CallTargetTag { }
86+
87+
class CondTag extends OperandTag instanceof Instruction::CondTag { }
88+
89+
class CondJumpTargetTag extends OperandTag instanceof Instruction::CondJumpTargetTag { }
90+
91+
class JumpTargetTag extends OperandTag instanceof Instruction::JumpTargetTag { }
92+
93+
class TempVariableTag instanceof Instruction::TempVariableTag {
94+
string toString() { result = super.toString() }
95+
}
96+
97+
class Variable instanceof Instruction::Variable {
98+
string toString() { result = super.toString() }
99+
100+
Location getLocation() { result = super.getLocation() }
101+
102+
Operand getAnAccess() { result = super.getAnAccess() }
103+
}
104+
105+
class TempVariable extends Variable instanceof Instruction::TempVariable { }
106+
107+
class LocalVariable extends Variable instanceof Instruction::LocalVariable {
108+
Function getEnclosingFunction() { result = super.getEnclosingFunction() }
109+
110+
predicate isStackAllocated() { super.isStackAllocated() }
111+
}
112+
113+
class StackPointer extends LocalVariable instanceof Instruction::StackPointer { }
114+
115+
class FramePointer extends LocalVariable instanceof Instruction::FramePointer { }
116+
117+
module BinaryCfg implements BB::CfgSig<Location> {
118+
class BasicBlock instanceof Instruction::BasicBlock {
119+
ControlFlowNode getNode(int index) { result = super.getNode(index) }
120+
121+
ControlFlowNode getANode() { result = super.getANode() }
122+
123+
ControlFlowNode getFirstNode() { result = super.getFirstNode() }
124+
125+
ControlFlowNode getLastNode() { result = super.getLastNode() }
126+
127+
int length() { result = super.length() }
128+
129+
BasicBlock getASuccessor() { result = super.getASuccessor() }
130+
131+
BasicBlock getASuccessor(SuccessorType t) { result = super.getASuccessor(t) }
132+
133+
BasicBlock getAPredecessor() { result = super.getAPredecessor() }
134+
135+
int getNumberOfInstructions() { result = super.getNumberOfInstructions() }
136+
137+
string toString() { result = super.toString() }
138+
139+
string getDumpString() { result = super.getDumpString() }
140+
141+
Location getLocation() { result = super.getLocation() }
142+
143+
Function getEnclosingFunction() { result = super.getEnclosingFunction() }
144+
145+
predicate isFunctionEntryBasicBlock() { super.isFunctionEntryBasicBlock() }
146+
147+
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
148+
149+
predicate dominates(BasicBlock bb) { super.dominates(bb) }
150+
151+
BasicBlock getImmediateDominator() { result = super.getImmediateDominator() }
23152

24-
BasicBlock getASuccessor(SuccessorType t) { exists(t) and result = super.getASuccessor() }
153+
predicate inDominanceFrontier(BasicBlock df) { super.inDominanceFrontier(df) }
25154

26-
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
155+
predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) }
27156

28-
predicate dominates(BasicBlock bb) { super.dominates(bb) }
157+
predicate postDominates(BasicBlock bb) { super.postDominates(bb) }
29158

30-
BasicBlock getImmediateDominator() { result = super.getImmediateDominator() }
159+
predicate edgeDominates(BasicBlock dominated, SuccessorType s) {
160+
exists(BasicBlock succ |
161+
succ = this.getASuccessor(s) and dominatingEdge(this, succ) and succ.dominates(dominated)
162+
)
163+
}
164+
}
165+
166+
class EntryBasicBlock extends BasicBlock {
167+
EntryBasicBlock() { this.isFunctionEntryBasicBlock() }
168+
}
169+
170+
additional class ConditionBasicBlock extends BasicBlock {
171+
ConditionBasicBlock() { this.getLastNode().asInstruction() instanceof CJumpInstruction }
172+
}
173+
174+
pragma[nomagic]
175+
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) {
176+
bb1.getASuccessor() = bb2 and
177+
bb1 = bb2.getImmediateDominator() and
178+
forall(BasicBlock pred | pred = bb2.getAPredecessor() and pred != bb1 | bb2.dominates(pred))
179+
}
180+
181+
class ControlFlowNode instanceof Instruction::ControlFlowNode {
182+
Instruction asInstruction() { result = super.asInstruction() }
183+
184+
Operand asOperand() { result = super.asOperand() }
185+
186+
Function getEnclosingFunction() { result = super.getEnclosingFunction() }
187+
188+
Location getLocation() { result = super.getLocation() }
189+
190+
string toString() { result = super.toString() }
191+
}
192+
}
193+
194+
class BasicBlock = BinaryCfg::BasicBlock;
195+
196+
class EntryBasicBlock = BinaryCfg::EntryBasicBlock;
197+
198+
class ConditionBasicBlock = BinaryCfg::ConditionBasicBlock;
199+
200+
class ControlFlowNode = BinaryCfg::ControlFlowNode;
201+
202+
class Instruction instanceof Instruction::Instruction {
203+
string toString() { result = super.toString() }
204+
205+
Opcode getOpcode() { result = super.getOpcode() }
206+
207+
Operand getOperand(OperandTag operandTag) { result = super.getOperand(operandTag) }
208+
209+
Operand getAnOperand() { result = super.getAnOperand() }
210+
211+
string getImmediateValue() { result = super.getImmediateValue() }
212+
213+
Instruction getSuccessor(SuccessorType succType) { result = super.getSuccessor(succType) }
214+
215+
Instruction getASuccessor() { result = super.getASuccessor() }
216+
217+
Instruction getAPredecessor() { result = super.getAPredecessor() }
218+
219+
Location getLocation() { result = super.getLocation() }
220+
221+
Variable getResultVariable() { result = super.getResultVariable() }
222+
223+
Function getEnclosingFunction() { result = super.getEnclosingFunction() }
224+
225+
BasicBlock getBasicBlock() { result = super.getBasicBlock() }
226+
227+
InstructionTag getInstructionTag() { result = super.getInstructionTag() }
228+
229+
Operand getFirstOperand() { result = super.getFirstOperand() }
230+
}
231+
232+
class RetInstruction extends Instruction instanceof Instruction::RetInstruction { }
233+
234+
class RetValueInstruction extends Instruction instanceof Instruction::RetValueInstruction {
235+
UnaryOperand getReturnValueOperand() { result = super.getReturnValueOperand() }
236+
}
31237

32-
predicate inDominanceFrontier(BasicBlock df) { super.inDominanceFrontier(df) }
238+
class BinaryInstruction extends Instruction instanceof Instruction::BinaryInstruction {
239+
LeftOperand getLeftOperand() { result = super.getLeftOperand() }
33240

34-
predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) }
241+
RightOperand getRightOperand() { result = super.getRightOperand() }
242+
}
243+
244+
class InitInstruction extends Instruction instanceof Instruction::InitInstruction { }
35245

36-
predicate postDominates(BasicBlock bb) { super.postDominates(bb) }
246+
class ExternalRefInstruction extends Instruction instanceof Instruction::ExternalRefInstruction {
247+
string getExternalName() { result = super.getExternalName() }
37248

38-
predicate edgeDominates(BasicBlock dominated, SuccessorType s) {
39-
exists(BasicBlock succ |
40-
succ = this.getASuccessor(s) and dominatingEdge(this, succ) and succ.dominates(dominated)
249+
cached
250+
predicate hasFullyQualifiedName(string namespace, string className, string methodName) {
251+
exists(string s, string r |
252+
this.getExternalName() = s and
253+
r = "(.+)\\.([^.]+)\\.(\\.?[^.]+)" and
254+
namespace = s.regexpCapture(r, 1) and
255+
className = s.regexpCapture(r, 2) and
256+
methodName = s.regexpCapture(r, 3)
41257
)
42258
}
43259
}
44260

45-
class EntryBasicBlock extends BasicBlock {
46-
EntryBasicBlock() { this.isFunctionEntryBasicBlock() }
261+
class SubInstruction extends BinaryInstruction instanceof Instruction::SubInstruction { }
262+
263+
class AddInstruction extends BinaryInstruction instanceof Instruction::AddInstruction { }
264+
265+
class ShlInstruction extends BinaryInstruction instanceof Instruction::ShlInstruction { }
266+
267+
class ShrInstruction extends BinaryInstruction instanceof Instruction::ShrInstruction { }
268+
269+
class RolInstruction extends BinaryInstruction instanceof Instruction::RolInstruction { }
270+
271+
class RorInstruction extends BinaryInstruction instanceof Instruction::RorInstruction { }
272+
273+
class OrInstruction extends BinaryInstruction instanceof Instruction::OrInstruction { }
274+
275+
class AndInstruction extends BinaryInstruction instanceof Instruction::AndInstruction { }
276+
277+
class XorInstruction extends BinaryInstruction instanceof Instruction::XorInstruction { }
278+
279+
class FunEntryInstruction extends Instruction instanceof Instruction::FunEntryInstruction { }
280+
281+
class CJumpInstruction extends Instruction instanceof Instruction::CJumpInstruction {
282+
ConditionKind getKind() { result = super.getKind() }
283+
284+
ConditionOperand getConditionOperand() { result = super.getConditionOperand() }
285+
286+
ConditionJumpTargetOperand getJumpTargetOperand() { result = super.getJumpTargetOperand() }
287+
}
288+
289+
class JumpInstruction extends Instruction instanceof Instruction::JumpInstruction {
290+
JumpTargetOperand getJumpTargetOperand() { result = super.getJumpTargetOperand() }
47291
}
48292

49-
additional class ConditionBasicBlock extends BasicBlock {
50-
ConditionBasicBlock() { this.getLastNode().asInstruction() instanceof CJumpInstruction }
293+
class InstrRefInstruction extends Instruction instanceof Instruction::InstrRefInstruction {
294+
Instruction getReferencedInstruction() { result = super.getReferencedInstruction() }
51295
}
52296

53-
pragma[nomagic]
54-
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) {
55-
bb1.getASuccessor() = bb2 and
56-
bb1 = bb2.getImmediateDominator() and
57-
forall(BasicBlock pred | pred = bb2.getAPredecessor() and pred != bb1 | bb2.dominates(pred))
297+
class CopyInstruction extends Instruction instanceof Instruction::CopyInstruction {
298+
UnaryOperand getOperand() { result = super.getOperand() }
299+
}
300+
301+
class CallInstruction extends Instruction instanceof Instruction::CallInstruction {
302+
CallTargetOperand getTargetOperand() { result = super.getTargetOperand() }
303+
304+
/**
305+
* Gets the static target of this function call, if it is known (and the
306+
* function exists in the database).
307+
*/
308+
Function getStaticTarget() { result = super.getStaticTarget() }
58309
}
59-
}
60310

61-
class EntryBasicBlock = BinaryCfg::EntryBasicBlock;
311+
class LoadInstruction extends Instruction instanceof Instruction::LoadInstruction {
312+
LoadAddressOperand getOperand() { result = super.getOperand() }
313+
}
314+
315+
class StoreInstruction extends Instruction instanceof Instruction::StoreInstruction {
316+
StoreValueOperand getValueOperand() { result = super.getValueOperand() }
317+
318+
StoreAddressOperand getAddressOperand() { result = super.getAddressOperand() }
319+
}
320+
321+
class ConstInstruction extends Instruction instanceof Instruction::ConstInstruction {
322+
int getValue() { result = super.getValue() }
323+
324+
string getStringValue() { result = super.getStringValue() }
325+
}
326+
}
62327

63-
class ConditionBasicBlock = BinaryCfg::ConditionBasicBlock;
328+
import FinalInstruction

0 commit comments

Comments
 (0)