Skip to content

Commit 31dd0e8

Browse files
committed
Add JVM IR translation support and test model
Introduces JVM instruction, type, method, and parameter translation to the IR, including new tags and classes for JVM elements. Updates core IR files to handle JVM instructions and variables, and adds a test model for Java vulnerable calls. Also updates workspace and qlpack configuration to support new data extensions.
1 parent d5a8da2 commit 31dd0e8

12 files changed

Lines changed: 615 additions & 7 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
stats
1+
<dbstats><typesizes /><stats /></dbstats>

binary/ql/lib/semmle/code/binary/ast/instructions.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ private import Headers
44
private import Sections
55
private import codeql.util.Unit
66

7-
private class TElement = @x86_instruction or @operand or @il_instruction or @method or @il_parameter or @type;
7+
private class TElement = @x86_instruction or @operand or @il_instruction or @method or @il_parameter or @type or @jvm_instruction or @jvm_parameter;
88

99
class Element extends TElement {
1010
final string toString() { none() }
@@ -266,3 +266,4 @@ class ExportedEntryInstruction extends X86Instruction {
266266
}
267267

268268
import internal.CilInstructions
269+
import internal.JvmInstructions

binary/ql/lib/semmle/code/binary/ast/ir/internal/Instruction0/InstructionTag.qll

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,24 @@ newtype TInstructionTag =
6060
CilStoreFieldAddressTag() or
6161
CilStoreFieldStoreTag() or
6262
CilLoadFieldAddressTag() or
63-
CilLoadFieldLoadTag()
63+
CilLoadFieldLoadTag() or
64+
// JVM instruction tags
65+
JvmCallTag() or
66+
JvmCallTargetTag() or
67+
JvmReturnTag() or
68+
JvmLoadLocalTag() or
69+
JvmStoreLocalTag() or
70+
JvmBranchCJumpTag() or
71+
JvmGotoJumpTag() or
72+
JvmArithOpTag() or
73+
JvmFieldAddressTag() or
74+
JvmFieldLoadTag() or
75+
JvmFieldStoreTag() or
76+
JvmNewInitTag() or
77+
JvmConstTag() or
78+
JvmDupCopyTag() or
79+
JvmPopTag() or
80+
JvmNopTag()
6481

6582
class InstructionTag extends TInstructionTag {
6683
final string toString() {
@@ -224,6 +241,55 @@ class InstructionTag extends TInstructionTag {
224241
or
225242
this = CilLoadFieldLoadTag() and
226243
result = "CilLoadFieldLoad"
244+
or
245+
// JVM instruction tags
246+
this = JvmCallTag() and
247+
result = "JvmCall"
248+
or
249+
this = JvmCallTargetTag() and
250+
result = "JvmCallTarget"
251+
or
252+
this = JvmReturnTag() and
253+
result = "JvmReturn"
254+
or
255+
this = JvmLoadLocalTag() and
256+
result = "JvmLoadLocal"
257+
or
258+
this = JvmStoreLocalTag() and
259+
result = "JvmStoreLocal"
260+
or
261+
this = JvmBranchCJumpTag() and
262+
result = "JvmBranchCJump"
263+
or
264+
this = JvmGotoJumpTag() and
265+
result = "JvmGotoJump"
266+
or
267+
this = JvmArithOpTag() and
268+
result = "JvmArithOp"
269+
or
270+
this = JvmFieldAddressTag() and
271+
result = "JvmFieldAddress"
272+
or
273+
this = JvmFieldLoadTag() and
274+
result = "JvmFieldLoad"
275+
or
276+
this = JvmFieldStoreTag() and
277+
result = "JvmFieldStore"
278+
or
279+
this = JvmNewInitTag() and
280+
result = "JvmNewInit"
281+
or
282+
this = JvmConstTag() and
283+
result = "JvmConst"
284+
or
285+
this = JvmDupCopyTag() and
286+
result = "JvmDupCopy"
287+
or
288+
this = JvmPopTag() and
289+
result = "JvmPop"
290+
or
291+
this = JvmNopTag() and
292+
result = "JvmNop"
227293
}
228294
}
229295

binary/ql/lib/semmle/code/binary/ast/ir/internal/Instruction0/TempVariableTag.qll

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,17 @@ newtype TTempVariableTag =
3535
CilDupVarTag() or
3636
CilStoreFieldAddressVarTag() or
3737
CilLoadFieldAddressVarTag() or
38-
CilLoadFieldLoadVarTag()
38+
CilLoadFieldLoadVarTag() or
39+
// JVM temp variable tags
40+
JvmCallTargetVarTag() or
41+
JvmCallResultVarTag() or
42+
JvmLoadLocalResultVarTag() or
43+
JvmConstVarTag() or
44+
JvmDupVarTag() or
45+
JvmArithResultVarTag() or
46+
JvmNewObjVarTag() or
47+
JvmFieldAddressVarTag() or
48+
JvmFieldLoadVarTag()
3949

4050
class TempVariableTag extends TTempVariableTag {
4151
string toString() {
@@ -149,5 +159,33 @@ class TempVariableTag extends TTempVariableTag {
149159
or
150160
this = CilLoadFieldLoadVarTag() and
151161
result = "ldfld"
162+
or
163+
// JVM temp variable tags
164+
this = JvmCallTargetVarTag() and
165+
result = "jvm_call_target"
166+
or
167+
this = JvmCallResultVarTag() and
168+
result = "jvm_call_ret"
169+
or
170+
this = JvmLoadLocalResultVarTag() and
171+
result = "jvm_ldloc"
172+
or
173+
this = JvmConstVarTag() and
174+
result = "jvm_const"
175+
or
176+
this = JvmDupVarTag() and
177+
result = "jvm_dup"
178+
or
179+
this = JvmArithResultVarTag() and
180+
result = "jvm_arith"
181+
or
182+
this = JvmNewObjVarTag() and
183+
result = "jvm_new"
184+
or
185+
this = JvmFieldAddressVarTag() and
186+
result = "jvm_fldaddr"
187+
or
188+
this = JvmFieldLoadVarTag() and
189+
result = "jvm_ldfld"
152190
}
153191
}

binary/ql/lib/semmle/code/binary/ast/ir/internal/Instruction0/TranslatedElement.qll

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,26 @@ private predicate shouldTranslateCilParameter(Raw::CilParameter p) { any() }
4646

4747
private predicate shouldTranslatedCilType(Raw::CilType t) { any() }
4848

49+
/**
50+
* Holds if the JVM instruction `instr` should be translated into IR.
51+
*/
52+
private predicate shouldTranslateJvmInstr(Raw::JvmInstruction instr) { any() }
53+
54+
/**
55+
* Holds if the JVM method `m` should be translated into IR.
56+
*/
57+
private predicate shouldTranslateJvmMethod(Raw::JvmMethod m) { any() }
58+
59+
/**
60+
* Holds if the JVM parameter `p` should be translated into IR.
61+
*/
62+
private predicate shouldTranslateJvmParameter(Raw::JvmParameter p) { any() }
63+
64+
/**
65+
* Holds if the JVM type `t` should be translated into IR.
66+
*/
67+
private predicate shouldTranslateJvmType(Raw::JvmType t) { any() }
68+
4969
/**
5070
* The "base type" for all translated elements.
5171
*
@@ -136,7 +156,50 @@ newtype TTranslatedElement =
136156
TTranslatedNewObject(Raw::CilNewobj newObj) { shouldTranslateCilInstr(newObj) } or
137157
TTranslatedDup(Raw::CilDup dup) { shouldTranslateCilInstr(dup) } or
138158
TTranslatedCilStoreField(Raw::CilStfld store) { shouldTranslateCilInstr(store) } or
139-
TTranslatedCilLoadField(Raw::CilLdfld load) { shouldTranslateCilInstr(load) }
159+
TTranslatedCilLoadField(Raw::CilLdfld load) { shouldTranslateCilInstr(load) } or
160+
// JVM translated elements
161+
TTranslatedJvmMethod(Raw::JvmMethod m) { shouldTranslateJvmMethod(m) } or
162+
TTranslatedJvmType(Raw::JvmType t) { shouldTranslateJvmType(t) } or
163+
TTranslatedJvmParameter(Raw::JvmParameter p) { shouldTranslateJvmParameter(p) } or
164+
TTranslatedJvmInvoke(Raw::JvmInvoke invoke) { shouldTranslateJvmInstr(invoke) } or
165+
TTranslatedJvmReturn(Raw::JvmReturn ret) { shouldTranslateJvmInstr(ret) } or
166+
TTranslatedJvmLoadLocal(Raw::JvmLoadLocal load) { shouldTranslateJvmInstr(load) } or
167+
TTranslatedJvmStoreLocal(Raw::JvmStoreLocal store) { shouldTranslateJvmInstr(store) } or
168+
TTranslatedJvmBranch(Raw::JvmBranch branch) { shouldTranslateJvmInstr(branch) } or
169+
TTranslatedJvmGoto(Raw::JvmGoto goto) { shouldTranslateJvmInstr(goto) } or
170+
TTranslatedJvmArithmetic(Raw::JvmInstruction arith) {
171+
shouldTranslateJvmInstr(arith) and
172+
(
173+
arith instanceof Raw::JvmIadd or arith instanceof Raw::JvmIsub or
174+
arith instanceof Raw::JvmImul or arith instanceof Raw::JvmIdiv or
175+
arith instanceof Raw::JvmLadd or arith instanceof Raw::JvmLsub or
176+
arith instanceof Raw::JvmLmul or arith instanceof Raw::JvmLdiv or
177+
arith instanceof Raw::JvmFadd or arith instanceof Raw::JvmFsub or
178+
arith instanceof Raw::JvmFmul or arith instanceof Raw::JvmFdiv or
179+
arith instanceof Raw::JvmDadd or arith instanceof Raw::JvmDsub or
180+
arith instanceof Raw::JvmDmul or arith instanceof Raw::JvmDdiv
181+
)
182+
} or
183+
TTranslatedJvmFieldAccess(Raw::JvmFieldAccess field) { shouldTranslateJvmInstr(field) } or
184+
TTranslatedJvmNew(Raw::JvmNew newObj) { shouldTranslateJvmInstr(newObj) } or
185+
TTranslatedJvmDup(Raw::JvmDup dup) { shouldTranslateJvmInstr(dup) } or
186+
TTranslatedJvmPop(Raw::JvmPop pop) { shouldTranslateJvmInstr(pop) } or
187+
TTranslatedJvmNop(Raw::JvmNop nop) { shouldTranslateJvmInstr(nop) } or
188+
TTranslatedJvmLoadConstant(Raw::JvmInstruction ldc) {
189+
shouldTranslateJvmInstr(ldc) and
190+
(
191+
ldc instanceof Raw::JvmLdc or ldc instanceof Raw::JvmLdcW or
192+
ldc instanceof Raw::JvmLdc2W or ldc instanceof Raw::JvmBipush or
193+
ldc instanceof Raw::JvmSipush or ldc instanceof Raw::JvmIconstM1 or
194+
ldc instanceof Raw::JvmIconst0 or ldc instanceof Raw::JvmIconst1 or
195+
ldc instanceof Raw::JvmIconst2 or ldc instanceof Raw::JvmIconst3 or
196+
ldc instanceof Raw::JvmIconst4 or ldc instanceof Raw::JvmIconst5 or
197+
ldc instanceof Raw::JvmLconst0 or ldc instanceof Raw::JvmLconst1 or
198+
ldc instanceof Raw::JvmFconst0 or ldc instanceof Raw::JvmFconst1 or
199+
ldc instanceof Raw::JvmFconst2 or ldc instanceof Raw::JvmDconst0 or
200+
ldc instanceof Raw::JvmDconst1 or ldc instanceof Raw::JvmAconstNull
201+
)
202+
}
140203

141204
TranslatedElement getTranslatedElement(Raw::Element raw) {
142205
result.getRawElement() = raw and
@@ -153,6 +216,11 @@ TranslatedCilInstruction getTranslatedCilInstruction(Raw::CilInstruction raw) {
153216
result.producesResult()
154217
}
155218

219+
TranslatedJvmInstruction getTranslatedJvmInstruction(Raw::JvmInstruction raw) {
220+
result.getRawElement() = raw and
221+
result.producesResult()
222+
}
223+
156224
abstract class TranslatedElement extends TTranslatedElement {
157225
/**
158226
* Holds if this translated element generated an instruction with opcode `opcode` that stores

binary/ql/lib/semmle/code/binary/ast/ir/internal/Instruction0/TranslatedFunction.qll

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,108 @@ class TranslatedCilMethod extends TranslatedFunction, TTranslatedCilMethod {
230230
none() // I don't think we need to do anything here?
231231
}
232232
}
233+
234+
// ============================================================================
235+
// JVM Translated Elements
236+
// ============================================================================
237+
238+
class TranslatedJvmParameter extends TranslatedElement, TTranslatedJvmParameter {
239+
Raw::JvmParameter p;
240+
241+
TranslatedJvmParameter() { this = TTranslatedJvmParameter(p) }
242+
243+
override Raw::Element getRawElement() { result = p }
244+
245+
final override Location getLocation() { result = p.getLocation() }
246+
247+
override Variable getResultVariable() { none() }
248+
249+
override TranslatedFunction getEnclosingFunction() {
250+
result = getTranslatedFunction(p.getMethod())
251+
}
252+
253+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Option<Variable>::Option v) {
254+
opcode instanceof Opcode::Init and
255+
tag = SingleTag() and
256+
v.asSome() = this.getLocalVariable(JvmParameterVarTag(p.getSlotIndex()))
257+
}
258+
259+
override predicate hasLocalVariable(LocalVariableTag tag) {
260+
tag = JvmParameterVarTag(p.getSlotIndex())
261+
}
262+
263+
override string getDumpId() { result = p.getName() }
264+
265+
override string toString() { result = "Translation of " + p.getName() }
266+
267+
override Variable getVariableOperand(InstructionTag tag, OperandTag operandTag) { none() }
268+
269+
override predicate producesResult() { any() }
270+
271+
final override Instruction getSuccessor(InstructionTag tag, SuccessorType succType) {
272+
tag = SingleTag() and
273+
result = this.getEnclosingFunction().getChildSuccessor(this, succType)
274+
}
275+
276+
final override Instruction getChildSuccessor(TranslatedElement child, SuccessorType succType) {
277+
none()
278+
}
279+
280+
Instruction getEntry() { result = this.getInstruction(SingleTag()) }
281+
}
282+
283+
private TranslatedJvmParameter getTranslatedJvmParameter(Raw::JvmParameter p) {
284+
result.getRawElement() = p and
285+
result.producesResult()
286+
}
287+
288+
class TranslatedJvmMethod extends TranslatedFunction, TTranslatedJvmMethod {
289+
Raw::JvmMethod method;
290+
291+
TranslatedJvmMethod() { this = TTranslatedJvmMethod(method) }
292+
293+
override Raw::Element getRawElement() { result = method }
294+
295+
final override Location getLocation() { result = method.getLocation() }
296+
297+
override predicate hasBodyInstruction(
298+
Opcode opcode, InstructionTag tag, Option<Variable>::Option v
299+
) {
300+
none()
301+
}
302+
303+
override Instruction getBodySuccessor(InstructionTag tag, SuccessorType succType) { none() }
304+
305+
private TranslatedJvmParameter getParameter(int index) {
306+
result = getTranslatedJvmParameter(method.getParameter(index))
307+
}
308+
309+
override Instruction getChildSuccessor(TranslatedElement child, SuccessorType succType) {
310+
exists(int index |
311+
child = this.getParameter(index) and
312+
succType instanceof DirectSuccessor
313+
|
314+
result = this.getParameter(index + 1).getEntry()
315+
or
316+
not exists(this.getParameter(index + 1)) and
317+
result = getTranslatedJvmInstruction(method.getInstruction(0)).getEntry()
318+
)
319+
}
320+
321+
override string getName() { result = method.getName() }
322+
323+
override predicate isProgramEntryPoint() { none() }
324+
325+
override predicate isPublic() { any() } // TODO: Extract access modifiers
326+
327+
override Instruction getBodyEntry() {
328+
result = this.getParameter(0).getEntry()
329+
or
330+
not exists(this.getParameter(0)) and
331+
result = getTranslatedJvmInstruction(method.getInstruction(0)).getEntry()
332+
}
333+
334+
final override predicate hasOrdering(LocalVariableTag tag, int ordering) {
335+
tag = JvmParameterVarTag(ordering)
336+
}
337+
}

0 commit comments

Comments
 (0)