的 QL 建模)
静态分析SAST应用安全漏洞扫描代码质量【免费下载链接】codeqlCodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security项目地址https://gitcode.com/gh_mirrors/co/codeql点击查看免费下载CodeQL 的 C/C 查询库cpp/ql/lib在 4.2.0 版本中引入了一项值得关注的新特性函数声明上显式标注的调用约定如__cdecl、__stdcall、__fastcall等如今会以声明说明符specifier的形式被建模并进入 CodeQL 数据库。同时QL 库新增了CallingConventionSpecifier类让安全研究人员和查询作者可以直接对调用约定进行检索与过滤。本文以 4.2.0 变更说明 为主体结合 Specifier.qll 的实现与 库测试用例深入剖析这一建模方式并给出可直接运行的查询示例。什么是调用约定为什么值得建模调用约定calling convention规定了函数调用时参数的传递顺序、栈的维护责任、寄存器使用规则以及名称修饰name mangling方式。Windows 平台上常见的调用约定包括__cdeclC/C 默认调用约定参数从右向左压栈由调用方清理栈__stdcall参数从右向左压栈由被调用方清理栈Win32 API 广泛使用__fastcall前两个参数优先通过寄存器传递以减少栈操作__thiscall用于非静态成员函数this指针通过寄存器x86 上为 ECX传递__vectorcall允许更多参数通过寄存器传递是__fastcall的扩展__clrcall用于 .NET 托管代码的调用约定。在 CodeQL 4.2.0 之前这些关键字虽然出现在函数声明中但并未被纳入说明符specifier体系因此查询很难直接、统一地定位“使用了某种调用约定的函数”。4.2.0 的变更解决了这一痛点显式指定的调用约定现在以 specifier 形式进入数据库并可通过统一的 QL 类进行访问。变更核心两个层面的新增4.2.0 变更说明 记录了以下两点函数声明上显式指定的调用约定__cdecl、__stdcall、__fastcall等现在被表示为这些声明的说明符specifiers。新增了扩展Specifier类的CallingConventionSpecifier类用于表示显式指定的调用约定。对应的实现位于 cpp/ql/lib/semmle/code/cpp/Specifier.qll/** * A C/C calling convention specifier: cdecl, fastcall, stdcall, thiscall, * vectorcall, or clrcall. */ class CallingConventionSpecifier extends Specifier { CallingConventionSpecifier() { this.hasName([cdecl, fastcall, stdcall, thiscall, vectorcall, clrcall]) } override string getAPrimaryQlClass() { result CallingConventionSpecifier } }这段实现有两点值得注意识别范围构造器通过hasName匹配六种约定cdecl、fastcall、stdcall、thiscall、vectorcall、clrcall。注意 QL 中的名字是去掉双下划线前缀后的形式即cdecl而非__cdecl这与Specifier.getName()的行为一致——Specifier的getName()由specifiers(underlyingElement(this), result)谓词从数据库中取出说明符名称见 Specifier.qll。继承体系CallingConventionSpecifier直接继承自Specifier而非StorageClassSpecifier或FunctionSpecifier那样的子类。这意味着调用约定是一个独立的说明符维度与存储类static、extern等、函数说明符inline、virtual等互不干扰。Specifier类本身建模了friend、auto、register、static、extern、mutable、inline、virtual、explicit等关键字见 Specifier.qll调用约定成为该家族的新成员。此外CallingConventionSpecifier重写了getAPrimaryQlClass()返回CallingConventionSpecifier使其在 AST 查看器等工具中以独立的类型标识展示。说明符体系新类在整个 Specifier 家族中的位置为便于理解新类所处的位置这里列出 Specifier.qll 中完整的说明符类层次QL 类识别的关键字说明Specifierfriend,auto,register,static,extern,mutable,inline,virtual,explicit所有说明符的基类提供getName()/hasName()FunctionSpecifierinline,virtual,explicit函数说明符StorageClassSpecifierauto,register,static,extern,mutable存储类说明符AccessSpecifierpublic,protected,private访问控制说明符含accessInDirectDerived推导规则CallingConventionSpecifiercdecl,fastcall,stdcall,thiscall,vectorcall,clrcall4.2.0 新增调用约定说明符Attribute及子类GnuAttribute、StdAttribute、Declspec、MicrosoftAttribute、AlignAs、FormatAttribute属性语法__attribute__、__declspec、[[...]]等属性建模与 specifier 并行从源码结构看CallingConventionSpecifier与Attribute家族__declspec等是互补的__declspec语法下的调用约定如 MSVC 的__declspec(...)仍走属性通道而__cdecl/__stdcall这类关键字形式的调用约定由新类统一建模。库测试用例验证建模行为仓库自带的库测试 cpp/ql/test/library-tests/calling-convention/calling-convention.ql 完整展示了新 API 的用法import cpp from FunctionDeclarationEntry func, CallingConventionSpecifier ccs where ccs.hasName(func.getASpecifier()) select func, func.getASpecifier()这个查询遍历所有函数声明条目FunctionDeclarationEntry通过func.getASpecifier()取得声明上的说明符并筛选出其中属于CallingConventionSpecifier的项。它同时印证了新的调用约定说明符可以通过FunctionDeclarationEntry.getASpecifier()正常取到——即说明符与声明之间建立了标准的关联关系。对应的测试输入 cpp/ql/test/library-tests/calling-convention/test.cpp 覆盖了全部六种约定并特别用--microsoft提取选项模拟 MSVC 方言__thiscall、__vectorcall等是 MSVC 扩展// semmle-extractor-options: --microsoft struct call_conventions { void __thiscall thiscall_method() {} }; void __cdecl func_cdecl() {} void __stdcall func_stdcall() {} void __fastcall func_fastcall() {} void __vectorcall func_vectorcall() {} int __cdecl func_overload() {} int __stdcall func_overload(int x) {}测试期望输出 calling-convention.expected 逐条验证了每个声明的调用约定名称| test.cpp:4:21:4:35 | definition of thiscall_method | thiscall | | test.cpp:7:14:7:23 | definition of func_cdecl | cdecl | | test.cpp:9:16:9:27 | definition of func_stdcall | stdcall | | test.cpp:11:17:11:29 | definition of func_fastcall | fastcall | | test.cpp:13:20:13:34 | definition of func_vectorcall | vectorcall | | test.cpp:15:13:15:25 | definition of func_overload | cdecl | | test.cpp:16:15:16:27 | definition of func_overload | stdcall |这个测试还验证了一个容易被忽略的细节同一函数名的重载可以携带不同调用约定func_overload的__cdecl与__stdcall版本被分别识别说明调用约定说明符是逐声明per-declaration建模的不会因函数名相同而混淆。实战查询示例基于上述 API可以写出多种实用的查询。1. 查找使用特定调用约定的所有函数例如查找所有使用__stdcall的函数Win32 回调、导出函数等常使用它import cpp from Function f, CallingConventionSpecifier ccs where ccs.hasName(stdcall) and ccs f.getASpecifier() select f, This function uses the __stdcall calling convention.2. 统计各调用约定的使用分布import cpp from CallingConventionSpecifier ccs select ccs.getName(), count(Function f | f.getASpecifier() ccs)3. 将调用约定与存储类组合筛选由于CallingConventionSpecifier是Specifier的子类它可以与其他说明符同时出现在同一声明上。例如查找同时带extern存储类和cdecl调用约定的函数import cpp from Function f where f.getASpecifier().hasName(extern) and f.getASpecifier().(CallingConventionSpecifier).hasName(cdecl) select f注意函数声明上的调用约定需通过getASpecifier()访问若需要处理调用点call site层面的约定信息可以结合Call与目标函数的关系自行扩展谓词逻辑。4. 在安全查询中作为过滤条件调用约定信息在安全分析中也有实用价值例如筛选通过回调指针调用的__stdcall导出函数或将调用约定作为污点分析路径的附加约束import cpp import semmle.code.cpp.dataflow.TaintTracking // 示例仅关注 __stdcall 函数上的数据流 from DataFlow::Node source, DataFlow::Node sink where taintFlow(source, sink) and source.asExpr().getEnclosingFunction().getASpecifier() .(CallingConventionSpecifier).hasName(stdcall) select source, sink使用前提与限制仅限显式指定该建模只针对源码中显式写出的调用约定关键字。未显式声明、由编译器默认决定的调用约定如默认的__cdecl不会凭空产生CallingConventionSpecifier条目。名称归一化QL 中匹配的名字是去掉__前缀后的形式cdecl、stdcall等书写查询时不要误加前缀。方言相关__thiscall、__vectorcall、__clrcall等是 MSVC 扩展测试用例通过--microsoft提取选项模拟在 GCC/Clang 等方言下这些关键字通常不可用实际匹配结果取决于待分析代码的编译环境。变更生效范围本变更记录于cpp/ql/lib/change-notes/released/4.2.0.md并同步收录在 cpp/ql/lib/CHANGELOG.md 中。使用该 API 需要对应的 CodeQL C/C 查询库版本不低于 4.2.0。小结CodeQL C/C 库 4.2.0 通过将调用约定关键字建模为说明符并引入CallingConventionSpecifier类补齐了Specifier家族在函数声明建模上的一个盲区。配合FunctionDeclarationEntry.getASpecifier()查询作者现在可以精确地按cdecl、stdcall、fastcall、thiscall、vectorcall、clrcall六种约定检索函数声明进而服务于 API 兼容性审计、平台相关代码分析、回调函数类型检查等实际场景。本文涉及的 变更说明、类实现、查询示例 与 测试数据 均可在当前仓库中直接查阅与复跑验证。赞分享静态分析SAST应用安全漏洞扫描代码质量【免费下载链接】codeqlCodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security项目地址https://gitcode.com/gh_mirrors/co/codeql点击查看免费下载相关推荐CodeQL C/C 1.18 分析能力升级新查询、查询改进与 QL 库变更深度解析CodeQL C/C 1.18 分析能力升级新查询、查询改进与 QL 库变更深度解析 本文对应 CodeQL 仓库 change notes/1.18/a静态分析SAST应用安全漏洞扫描代码质量CodeQL C 分析器 1.21 版本更新详解C 8 特性提取与 QL 库建模CodeQL C 分析器 1.21 版本更新详解C 8 特性提取与 QL 库建模 导读 本文基于 CodeQL 仓库 change notes/1.21/an静态分析SAST应用安全漏洞扫描代码质量CodeQL C/C 0.13.0 深度解析Models-as-Data 数据流建模、ZMQ 与 getc 模型库更新CodeQL C/C 0.13.0 深度解析Models as Data 数据流建模、ZMQ 与 getc 模型库更新 本指南以 CodeQL 仓库中 C静态分析SAST应用安全漏洞扫描代码质量上一篇Must Read Resources for Java Developers10个核心领域的学习路线图下一篇3行代码搞定搜索引擎ZincSearch×Python极速集成指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考