我是CodeQL的新手,已经开始学习C/C++程序的数据流查询.以下是我想分析的一个C程序的摘录:

int main(int argc, char * argv[])
{
    unsigned short size, x, y;
    int r1, r2;
    x = atoi(argv[1]);// one dim of the data
    y = atoi(argv[2]);//other dim of the data
    size = x*y; //total size of the data
    r1 = MyVuln(size*sizeof(char));

    r2 = MyVuln(x*sizeof(char));
...
// some code
...

return 0
}

在上面的例子中,我想要捕获使用size作为参数调用MyVuln函数的情况.size被定义为AssignExpr的结果,使得其Rvalue是乘法的结果.以下是我编写的COdeQL查询:

/*
@kind path-problem
*/

import cpp
import semmle.code.cpp.dataflow.new.DataFlow
//import DataFlow::PathGraph

from Function myvuln, FunctionCall fc, AssignExpr ab 
where
myvuln.hasGlobalName("MyVuln")
and fc.getTarget() = myvuln
and ab.getLValue().getType().getUnspecifiedType() instanceof IntegralType
and ab.getRValue() instanceof MulExpr
and exists (DataFlow::Node src, DataFlow::Node sink| 
src.asExpr() = ab.getLValue()
and sink.asExpr() = fc.getArgument(0)
and DataFlow::localFlow(src, sink)
)
select fc, "MyVuln with Arithmetic arg at " + fc.getLocation().toString()

查询不返回任何结果(我将CodeQl与VS Code一起使用).我还判断了一个较小的部分查询是否可以检测到对应于size清晰度的表达式,并且它正在工作.我还判断了查询是否找到了对MyVuln的调用,并且它正在工作.只有当我开始编写数据流路径查询时,我才会得到任何结果.这种类型的查询似乎非常直接,但我没有得到任何线索,我在哪里出错了,或者我在这个查询中遗漏了什么.一个帮助就是高度的感激. 谢谢

推荐答案

因此,基于@Marcono1234的建议,以下是针对我在上面问题中提到的问题的查询.

/*
@kind path-problem
*/

import cpp
import semmle.code.cpp.dataflow.new.DataFlow
import semmle.code.cpp.dataflow.new.TaintTracking
//import DataFlow::PathGraph

from Function myvuln, FunctionCall fc, AssignExpr ab, Expr p, DataFlow::Node src, DataFlow::Node sink
where
// getting the call that I am interested in as sink
myvuln.hasGlobalName("MyVuln")
and fc.getTarget() = myvuln
// getting the "interesting" parameter that will flow into the parameter of MyVuln
and ab.getLValue().getType().getUnspecifiedType() instanceof IntegralType
and ab.getRValue() instanceof MulExpr
and src.asExpr() = ab.getRValue() // this was problematic as in my earlier query, I was extracting LValue. But it turns out that I need to select the expression that will compute the value that will flow into the parameter of MyVuln. thus the RValue expression
and sink.asExpr() = fc.getArgument(0)
and TaintTracking::localTaint(src, sink)

select fc, sink.toString(), "MyVul with Arithmetic operation at " + fc.getLocation().toString()

在学习CodeQL的同时,我也想了解做这件事的各种方式.因此,通过使用`getAChild*()从表达式size*sizeof(char)中提取sizevar,我探索了与dataflow相同的问题.这将需要在以下两个位置更改上述查询:

and sink.asExpr() = fc.getArgument(0).getAChild*()
//and TaintTracking::localTaint(src, sink)
and DataFlow::localFlow(src, sink)

C++相关问答推荐

由于未签名int导致的运行时错误"

修改pGM使用指针填充2-D数组但不起作用

如何避免重新分配指针数组时,我们从一开始就不知道确切的大小

为什么下面的递归基本情况在C中不起作用?

使用额外的公共参数自定义printf

在传统操作系统上可以在虚拟0x0写入吗?

Rust FFI--如何用给出返回引用的迭代器包装C风格的迭代器?

非常大的数组的大小

使用scanf在C中读取和存储文件中的值

是什么让numpy.sum比优化的(自动矢量化的)C循环更快?

在Apple Silicon上编译x86的Fortran/C程序

从TCP连接启动UDP(C套接字)

MacOS下C++的无阻塞键盘阅读

C语言中MPI发送接收字符串时出现的分段错误

CS50判断灯泡运动的问题,判断时多出一个灯泡,但不在终端上

是否有单独的缓冲区用于读写库调用?

C:面筋蛋白';为什么不刷新窗口?

浮点正零何时不全为零?

令人困惑的返回和 scanf 问题相关

在 C 中传递参数时出现整数溢出