Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d69de0c

Browse files
committed
C++: Add a MaD model for 'CRegKey' and mark query calls as local flow sources.
1 parent 5aada39 commit d69de0c

4 files changed

Lines changed: 116 additions & 9 deletions

File tree

cpp/ql/lib/ext/CRegKey.model.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/cpp-all
4+
extensible: summaryModel
5+
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
6+
- ["", "CRegKey", True, "CRegKey", "(CRegKey&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"]
7+
- ["", "CRegKey", True, "CRegKey", "(HKEY)", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
8+
- ["", "CRegKey", True, "Attach", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
9+
- ["", "CRegKey", True, "QueryBinaryValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
10+
- ["", "CRegKey", True, "QueryDWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
11+
- ["", "CRegKey", True, "QueryMultiStringValue", "", "", "Argument[*0]", "Argument[**1]", "taint", "manual"]
12+
- ["", "CRegKey", True, "QueryQWORDValue", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
13+
- ["", "CRegKey", True, "QueryStringValue", "", "", "Argument[*0]", "Argument[**1]", "taint", "manual"]
14+
- ["", "CRegKey", True, "QueryValue", "(LPCTSTR,DWORD *,void *,ULONG *)", "", "Argument[*0]", "Argument[*2]", "taint", "manual"]
15+
- ["", "CRegKey", True, "QueryValue", "(DWORD&,LPCTSTR)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
16+
- ["", "CRegKey", True, "QueryValue", "(LPTSTR,LPCTSTR,DWORD *)", "", "Argument[*1]", "Argument[**0]", "taint", "manual"]
17+
- ["", "CRegKey", True, "QueryValue", "operator HKEY", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
18+
- ["", "CRegKey", True, "QueryValue", "operator=", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"]
19+
- ["", "CRegKey", True, "QueryValue", "operator=", "", "Argument[*0]", "Argument[-1]", "value", "manual"]

cpp/ql/lib/semmle/code/cpp/models/Models.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,4 @@ private import implementations.CPathT
5656
private import implementations.CAtlFile
5757
private import implementations.CAtlFileMapping
5858
private import implementations.CAtlTemporaryFile
59+
private import implementations.CRegKey
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
private import cpp
2+
private import semmle.code.cpp.models.interfaces.FlowSource
3+
private import semmle.code.cpp.ir.dataflow.FlowSteps
4+
private import semmle.code.cpp.dataflow.new.DataFlow
5+
6+
/** The `CRegKey` class from the Microsoft "Active Template Library". */
7+
class CRegKey extends Class {
8+
CRegKey() { this.hasGlobalName("CRegKey") }
9+
}
10+
11+
module CRegKey {
12+
/** The `m_hKey` member on a object of type `CRegKey`. */
13+
class MhKey extends Field {
14+
MhKey() {
15+
this.getDeclaringType() instanceof CRegKey and
16+
this.getName() = "m_hKey"
17+
}
18+
}
19+
20+
private class MhKeyPathTaintInheritingContent extends TaintInheritingContent,
21+
DataFlow::FieldContent
22+
{
23+
MhKeyPathTaintInheritingContent() { this.getField() instanceof MhKey }
24+
}
25+
26+
private class CRegKeyMemberFunction extends MemberFunction {
27+
string name;
28+
29+
CRegKeyMemberFunction() { this.getClassAndName(name) instanceof CRegKey }
30+
}
31+
32+
abstract private class CRegKeyFlowSource extends CRegKeyMemberFunction, LocalFlowSourceFunction {
33+
FunctionOutput output;
34+
35+
final override predicate hasLocalFlowSource(FunctionOutput output_, string description) {
36+
output_ = output and
37+
description = "registry string read by " + name
38+
}
39+
}
40+
41+
/** The `CRegKey::QueryBinaryValue` function from Win32. */
42+
class QueryBinaryValue extends CRegKeyFlowSource {
43+
QueryBinaryValue() { name = "QueryBinaryValue" and output.isParameterDeref(1) }
44+
}
45+
46+
/** The `CRegKey::QueryDWORDValue` function from Win32. */
47+
class QueryDwordValue extends CRegKeyFlowSource {
48+
QueryDwordValue() { name = "QueryDWORDValue" and output.isParameterDeref(1) }
49+
}
50+
51+
/** The `CRegKey::QueryGUIDValue` function from Win32. */
52+
class QueryGuidValue extends CRegKeyFlowSource {
53+
QueryGuidValue() { name = "QueryGUIDValue" and output.isParameterDeref(1) }
54+
}
55+
56+
/** The `CRegKey::QueryMultiStringValue` function from Win32. */
57+
class QueryMultiStringValue extends CRegKeyFlowSource {
58+
QueryMultiStringValue() { name = "QueryMultiStringValue" and output.isParameterDeref(1) }
59+
}
60+
61+
/** The `CRegKey::QueryQWORDValue` function from Win32. */
62+
class QueryQwordValue extends CRegKeyFlowSource {
63+
QueryQwordValue() { name = "QueryQWORDValue" and output.isParameterDeref(1) }
64+
}
65+
66+
/** The `CRegKey::QueryStringValue` function from Win32. */
67+
class QueryStringValue extends CRegKeyFlowSource {
68+
QueryStringValue() { name = "QueryStringValue" and output.isParameterDeref(1) }
69+
}
70+
71+
/** The `CRegKey::QueryValue` function from Win32. */
72+
class QueryValue extends CRegKeyFlowSource {
73+
QueryValue() {
74+
name = "QueryValue" and
75+
(
76+
this.getNumberOfParameters() = 4 and
77+
output.isParameterDeref(2)
78+
or
79+
this.getNumberOfParameters() = 2 and
80+
output.isParameterDeref(0)
81+
or
82+
this.getNumberOfParameters() = 3 and
83+
output.isParameterDeref(0)
84+
)
85+
}
86+
}
87+
}

cpp/ql/test/library-tests/dataflow/source-sink-tests/atl.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -364,26 +364,26 @@ void test_CRegKey() {
364364
CRegKey key;
365365
char data[1024];
366366
ULONG bytesRead;
367-
key.QueryBinaryValue("foo", data, &bytesRead); // $ MISSING: local_source
367+
key.QueryBinaryValue("foo", data, &bytesRead); // $ local_source
368368

369369
DWORD value;
370-
key.QueryDWORDValue("foo", value); // $ MISSING: local_source
370+
key.QueryDWORDValue("foo", value); // $ local_source
371371

372372
GUID guid;
373-
key.QueryGUIDValue("foo", guid); // $ MISSING: local_source
373+
key.QueryGUIDValue("foo", guid); // $ local_source
374374

375-
key.QueryMultiStringValue("foo", data, &bytesRead); // $ MISSING: local_source
375+
key.QueryMultiStringValue("foo", data, &bytesRead); // $ local_source
376376

377377
ULONGLONG qword;
378-
key.QueryQWORDValue("foo", qword); // $ MISSING: local_source
378+
key.QueryQWORDValue("foo", qword); // $ local_source
379379

380-
key.QueryStringValue("foo", data, &bytesRead); // $ MISSING: local_source
380+
key.QueryStringValue("foo", data, &bytesRead); // $ local_source
381381

382-
key.QueryValue(data, "foo", &bytesRead); // $ MISSING: local_source
382+
key.QueryValue(data, "foo", &bytesRead); // $ local_source
383383

384384
DWORD type;
385-
key.QueryValue("foo", &type, data, &bytesRead); // $ MISSING: local_source
385+
key.QueryValue("foo", &type, data, &bytesRead); // $ local_source
386386

387387
DWORD value2;
388-
key.QueryValue(value2, "foo"); // $ MISSING: local_source
388+
key.QueryValue(value2, "foo"); // $ local_source
389389
}

0 commit comments

Comments
 (0)