From 75f0ec79bd662085833461c267487d3ef5c6787a Mon Sep 17 00:00:00 2001 From: Michael Hohn Date: Mon, 17 Mar 2025 14:05:41 -0700 Subject: [PATCH] Add AST printed in dot format and converted to pdf --- ast.dot/cpp/print-ast.dot | 114 ++++++++++++++++++++++++++++++++++++++ ast.dot/cpp/print-ast.pdf | Bin 0 -> 43636 bytes readme-low-level.org | 24 ++++++++ solutions/ast.ql | 12 ++++ 4 files changed, 150 insertions(+) create mode 100644 ast.dot/cpp/print-ast.dot create mode 100644 ast.dot/cpp/print-ast.pdf create mode 100644 readme-low-level.org create mode 100644 solutions/ast.ql diff --git a/ast.dot/cpp/print-ast.dot b/ast.dot/cpp/print-ast.dot new file mode 100644 index 0000000..f0ad64b --- /dev/null +++ b/ast.dot/cpp/print-ast.dot @@ -0,0 +1,114 @@ +digraph { + compound=true; + 0[label="[IfStmt] if (...) ... "; ]; + 1[label="[VariableAccess] input_types"; ]; + 2[label="[FunctionCall] call to DYN_INPUT_TYPE"; ]; + 3[label="[Literal] 2"; ]; + 4[label="[CStyleCast] (unsigned int)..."; ]; + 5[label="[Literal] 1"; ]; + 6[label="[CStyleCast] (unsigned int)..."; ]; + 7[label="[EQExpr] ... == ..."; ]; + 8[label="[ExprStmt] ExprStmt"; ]; + 9[label="[FunctionCall] call to memcpy"; ]; + 10[label="[VariableAccess] input"; ]; + 11[label="[Literal] 1"; ]; + 12[label="[ArrayExpr] access to array"; ]; + 13[label="[ValueFieldAccess] ptr"; ]; + 14[label="[ValueFieldAccess] buf"; ]; + 15[label="[VariableAccess] input"; ]; + 16[label="[Literal] 0"; ]; + 17[label="[ArrayExpr] access to array"; ]; + 18[label="[ValueFieldAccess] val"; ]; + 19[label="[AddressOfExpr] & ..."; ]; + 20[label="[CStyleCast] (const void *)..."; ]; + 21[label="[SizeofExprOperator] sizeof()"; ]; + 22[label="[VariableAccess] input"; ]; + 23[label="[Literal] 0"; ]; + 24[label="[ArrayExpr] access to array"; ]; + 25[label="[ValueFieldAccess] val"; ]; + 26[label="[ParenthesisExpr] (...)"; ]; + 27[label="[ReturnStmt] return ..."; ]; + 28[label="[Literal] 0"; ]; + 29[label="[BlockStmt] { ... }"; ]; + 30[label="[ExprStmt] ExprStmt"; ]; + 31[label="[FunctionCall] call to memcpy"; ]; + 32[label="[VariableAccess] input"; ]; + 33[label="[Literal] 1"; ]; + 34[label="[ArrayExpr] access to array"; ]; + 35[label="[ValueFieldAccess] ptr"; ]; + 36[label="[ValueFieldAccess] buf"; ]; + 37[label="[VariableAccess] input"; ]; + 38[label="[Literal] 0"; ]; + 39[label="[ArrayExpr] access to array"; ]; + 40[label="[ValueFieldAccess] val"; ]; + 41[label="[AddressOfExpr] & ..."; ]; + 42[label="[CStyleCast] (const void *)..."; ]; + 43[label="[SizeofExprOperator] sizeof()"; ]; + 44[label="[VariableAccess] input"; ]; + 45[label="[Literal] 0"; ]; + 46[label="[ArrayExpr] access to array"; ]; + 47[label="[ValueFieldAccess] val"; ]; + 48[label="[ParenthesisExpr] (...)"; ]; + 49[label="[ReturnStmt] return ..."; ]; + 50[label="[Literal] 1"; ]; + 51[label="[BlockStmt] { ... }"; ]; + 52[label="[Parameter] input"; ]; + 53[label="[Parameter] input_types"; ]; + 54[]; + 55[label="[TopLevelFunction] int write_val_to_mem(dyn_input_t*, unsigned int)"; ]; + 0 -> 7[label="getCondition()"; ]; + 2 -> 3[label="getArgument(0)"; ]; + 7 -> 1[label="getLeftOperand()"; ]; + 8 -> 9[label="getExpr()"; ]; + 9 -> 14[label="getArgument(0)"; ]; + 12 -> 10[label="getArrayBase()"; ]; + 13 -> 12[label="getQualifier()"; ]; + 14 -> 13[label="getQualifier()"; ]; + 17 -> 15[label="getArrayBase()"; ]; + 18 -> 17[label="getQualifier()"; ]; + 19 -> 18[label="getOperand()"; ]; + 21 -> 25[label="getExprOperand()"; ]; + 24 -> 22[label="getArrayBase()"; ]; + 25 -> 24[label="getQualifier()"; ]; + 27 -> 28[label="getExpr()"; ]; + 29 -> 8[label="getStmt(0)"; ]; + 30 -> 31[label="getExpr()"; ]; + 31 -> 36[label="getArgument(0)"; ]; + 34 -> 32[label="getArrayBase()"; ]; + 35 -> 34[label="getQualifier()"; ]; + 36 -> 35[label="getQualifier()"; ]; + 39 -> 37[label="getArrayBase()"; ]; + 40 -> 39[label="getQualifier()"; ]; + 41 -> 40[label="getOperand()"; ]; + 43 -> 47[label="getExprOperand()"; ]; + 46 -> 44[label="getArrayBase()"; ]; + 47 -> 46[label="getQualifier()"; ]; + 49 -> 50[label="getExpr()"; ]; + 51 -> 0[label="getStmt(0)"; ]; + 55 -> 54[label=""; ]; + 54 -> 52[label="getParameter(0)"; ]; + 0 -> 29[label="getThen()"; ]; + 2 -> 5[label="getArgument(1)"; ]; + 7 -> 2[label="getRightOperand()"; ]; + 9 -> 19[label="getArgument(1)"; ]; + 12 -> 11[label="getArrayOffset()"; ]; + 17 -> 16[label="getArrayOffset()"; ]; + 21 -> 26[label="getExprOperand().getFullyConverted()"; ]; + 24 -> 23[label="getArrayOffset()"; ]; + 29 -> 27[label="getStmt(1)"; ]; + 31 -> 41[label="getArgument(1)"; ]; + 34 -> 33[label="getArrayOffset()"; ]; + 39 -> 38[label="getArrayOffset()"; ]; + 43 -> 48[label="getExprOperand().getFullyConverted()"; ]; + 46 -> 45[label="getArrayOffset()"; ]; + 51 -> 30[label="getStmt(1)"; ]; + 55 -> 51[label="getEntryPoint()"; ]; + 54 -> 53[label="getParameter(1)"; ]; + 2 -> 4[label="getArgument(0).getFullyConverted()"; ]; + 9 -> 21[label="getArgument(2)"; ]; + 31 -> 43[label="getArgument(2)"; ]; + 51 -> 49[label="getStmt(2)"; ]; + 2 -> 6[label="getArgument(1).getFullyConverted()"; ]; + 9 -> 20[label="getArgument(1).getFullyConverted()"; ]; + 31 -> 42[label="getArgument(1).getFullyConverted()"; ]; +} diff --git a/ast.dot/cpp/print-ast.pdf b/ast.dot/cpp/print-ast.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b507e49eed493e4c7d6a847600f16f09829e769a GIT binary patch literal 43636 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å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 literal 0 HcmV?d00001 diff --git a/readme-low-level.org b/readme-low-level.org new file mode 100644 index 0000000..01980cf --- /dev/null +++ b/readme-low-level.org @@ -0,0 +1,24 @@ +* Some low-level codeql + #+BEGIN_SRC sh + # Produce ast in dot format + codeql database analyze \ + --format=dot --output=ast.dot \ + -- cpp-dataflow-part1-database solutions/ast.ql + + # Convert dot to pdf + dot -Tpdf < ast.dot/cpp/print-ast.dot > ast.dot/cpp/print-ast.pdf + + # View the graph + open ast.dot/cpp/print-ast.pdf + + + # This comes from + unzip -v cpp-dataflow-part1-database/src.zip + # Archive: cpp-dataflow-part1-database/src.zip + # Length Method Size Cmpr Date Time CRC-32 Name + # -------- ------ ------- ---- ---------- ----- -------- ---- + # 3280 Defl:N 880 73% 03-17-2025 08:59 8057b2ea Users/hohn/local/codeql-workshop-dataflow-c/tests-common/test_part1.c + # -------- ------- --- ------- + # 3280 880 73% 1 file + #+END_SRC + diff --git a/solutions/ast.ql b/solutions/ast.ql new file mode 100644 index 0000000..d895d75 --- /dev/null +++ b/solutions/ast.ql @@ -0,0 +1,12 @@ +/** + * @id cpp/print-ast + * @kind graph + */ + +import cpp +import semmle.code.cpp.PrintAST + +// extend `PrintASTConfiguration` and override `shouldPrintFunction` to hold for only the functions +class PrintConfig extends PrintAstConfiguration { + override predicate shouldPrintFunction(Function func) { func.hasName("write_val_to_mem") } +}