惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
B
Blog RSS Feed
Martin Fowler
Martin Fowler
M
MIT News - Artificial intelligence
博客园 - 三生石上(FineUI控件)
博客园 - 【当耐特】
N
News | PayPal Newsroom
K
Kaspersky official blog
大猫的无限游戏
大猫的无限游戏
人人都是产品经理
人人都是产品经理
N
Netflix TechBlog - Medium
B
Blog
Recorded Future
Recorded Future
U
Unit 42
J
Java Code Geeks
Security Latest
Security Latest
H
Hackread – Cybersecurity News, Data Breaches, AI and More
V
Vulnerabilities – Threatpost
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Scott Helme
Scott Helme
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
T
Threatpost
Last Week in AI
Last Week in AI
Know Your Adversary
Know Your Adversary
Project Zero
Project Zero
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cloudbric
Cloudbric
AWS News Blog
AWS News Blog
NISL@THU
NISL@THU
有赞技术团队
有赞技术团队
博客园 - 叶小钗
N
News and Events Feed by Topic
V
V2EX
T
Troy Hunt's Blog
月光博客
月光博客
博客园 - Franky
P
Proofpoint News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
C
Cisco Blogs
The Cloudflare Blog
T
Tor Project blog
Google Online Security Blog
Google Online Security Blog

SumSec's Blog

AI Agent 工程的必然演进:CLI、Skills、Harne… 从安全角度谈Java反射机制--前章 · SUMSEC 从安全角度谈Java反射机制--终章 · SUMSEC 逆向学习fastjson反序列化始 · SUMSEC 2020年研究回顾总结 · SUMSEC Abstract syntax tree classes for … Analyzing data flow in Java · SUM… Annotations in Java · SUMSEC Basic query for Java code · SUMSEC BypassSuper使用介绍说明 · SUMSEC CodeQL Create OpenJdk/Jdk8 Databa… CodeQL library for Java · SUMSEC Overflow-prone comparisons in Jav… Types in Java · SUMSEC Working with source locations · S… Aliases · SUMSEC Expression · SUMSEC Formulas · SUMSEC Javadoc · SUMSEC Modules · SUMSEC Predicates · SUMSEC Queries · SUMSEC Type · SUMSEC Variables · SUMSEC 一道shiro反序列化题目引发的思考 · SUMSEC 修改ysoserial使其支持任意代码执行 · SUMSEC 自定义 ClassLoader 隔离运行不同版本jar包的方式 ·… 2020网鼎杯---Java文件上传wp · SUMSEC CNVD-2020-10487(CVE-2020-1938)tom… JDSRC安全课笔记 · SUMSEC Java反序列化链回显解决方案 · SUMSEC Skipped breakpoint because it hap… Windows Terminal 配置文件 · SUMSEC bypass 学习笔记之绕安全狗bypass safedog · … 一次意外的代码审计----JfinalCMS审计 · SUMSEC 一篇文章读懂Java代码审计之XXE · SUMSEC 从安全角度谈Java反射机制--序章 · SUMSEC 小楼昨夜又春风,你知ysoserial-Gadget-URLDNS… 春眠不觉晓,RCE知多少? · SUMSEC 漫谈Commons-Collections反序列化 · SUMSEC 漫谈Java反序列化 · SUMSEC 白头搔更短,SSTI惹人心! · SUMSEC 记一次面试题 · SUMSEC About Me 关于我 · SUMSEC Apache Flink任意Jar包上传导致远程代码执行 · SU… CVE-2019-1388 UAC提权复现 · SUMSEC CVE-2019-16097 || Harbor任意管理员注册漏洞… Python加密shellcode免杀 · SUMSEC Telegram机器人作为渗透测试框架 · SUMSEC VM虚拟机无法安装vmtools解决|本程序需要您将此虚拟机上安装… 谁能想到,电视遥控器竟成了 Vibe Coding 神器 · SU… 从手改 Skill 到自动进化:评测结果和执行轨迹如何让 Agen… 模型人人都能用,什么才是你能带走的?我的答案是一个可进化的SKIL… 模型人人都能用,什么才是你能带走的?我的答案是一个可进化的Skil… AI 时代 ShiroAttack2 5.x:修改了什么 · SU… 在 AGI 降临前,先给 AI 开一条”脑内弹幕”通道 · SUM… 一篇博文,三种时间:网页幻灯与 Remotion 动效的交付逻辑 … 🔍 别让大模型”想太多”:SKILL开发中的语义陷阱与抗幻觉设计 … 2022 年年度总结 · SUMSEC Java Swing To RCE 漏洞分析 · SUMSEC SpringBoot GatewayEL表达式漏洞分析 · SUM… Sensitive keys in codebases · SUM… 论如何优雅注入 Java 内存马 · SUMSEC SUMSEC 知识点 · SUMSEC VMWare Workspace ONE Access Auth … Spring Framework RCE CVE-2022-229… 相似度算法调研 · SUMSEC CVE-2022-33891 Apache Spark shell… 正则匹配配置不当 · SUMSEC Spring Data MongoDB SpEL CVE-2022… CodeQl Usage Tricks · SUMSEC Spring Boot RCE到内存马探索 · SUMSEC Shiro后渗透拓展面 · SUMSEC shiro反序列化漏洞攻击拓展面–修改key · SUMSEC GitHub Java CodeQL CTF · SUMSEC Hack-Tools 转化成Web · SUMSEC CodeQL与Shiro550碰撞 · SUMSEC CodeQL初见Shiro550 · SUMSEC CodeQL与AST之间联系 · SUMSEC Java加载动态链接库 · SUMSEC Log4j2 漏洞分析 · SUMSEC Interprocedural-Analysis 过程间分析 · … Data Analysis Foundation 数据分析基础 ·… Data Flow Analysis · SUMSEC Intermediate Representation 中间代表(… PII泄露–用CodeQL识别日志中的PII数据 · SUMSEC CodeQL workshop for Java: Unsafe … 前言 · SUMSEC 漏洞环境的搭建 · SUMSEC Fastjson回显 · SUMSEC Tomcat通用回显学习笔记 · SUMSEC 从Java反序列化漏洞题看CodeQL数据流 · SUMSEC 概述 · SUMSEC 记一次Log4j失败的Gadget挖掘记录 · SUMSEC Ysoserial改造记录 · SUMSEC JNDI注入 · SUMSEC shiro JRMP gadget · SUMSEC Fastjson MySQL gadget复现 · SUMSEC 2021年度总结 · SUMSEC
Navigating the call graph · SUMSEC
2026-07-17 · via SumSec's Blog

CodeQL has classes for identifying code that calls other code, and code that can be called from elsewhere. This allows you to find, for example, methods that are never used.

CodeQL有一些类用于识别调用其他代码的代码,以及可以从其他地方调用的代码。例如,这允许你找到从未使用过的方法。

Call graph classes

The CodeQL library for Java provides two abstract classes for representing a program’s call graph: Callable and Call. The former is simply the common superclass of Method and Constructor, the latter is a common superclass of MethodAccess, ClassInstanceExpression, ThisConstructorInvocationStmt and SuperConstructorInvocationStmt. Simply put, a Callable is something that can be invoked, and a Call is something that invokes a Callable.

Java的CodeQL库提供了两个抽象类来表示程序的调用图。Callable和Call。前者只是Method和Constructor的共同超类,后者是MethodAccess、ClassInstanceExpression、ThisConstructorInvocationStmt和SuperConstructorInvocationStmt的共同超类。简单的说,Callable就是可以被调用的东西,Call就是调用Callable的东西。

For example, in the following program all callables and calls have been annotated with comments:

例如,在下面的程序中,所有的可调用和调用都被注解了:

class Super {
    int x;

    // callable
    public Super() {
        this(23);       // call
    }

    // callable
    public Super(int x) {
        this.x = x;
    }

    // callable
    public int getX() {
        return x;
    }
}

    class Sub extends Super {
    // callable
    public Sub(int x) {
        super(x+19);    // call
    }

    // callable
    public int getX() {
        return x-19;
    }
}

class Client {
    // callable
    public static void main(String[] args) {
        Super s = new Sub(42);  // call
        s.getX();               // call
    }
}

Class Call provides two call graph navigation predicates:

Class Call提供了两个调用图导航谓词:

  • getCallee returns the Callable that this call (statically) resolves to; note that for a call to an instance (that is, non-static) method, the actual method invoked at runtime may be some other method that overrides this method.
  • getCallee返回这个调用(静态)所解析的Callable;注意,对于一个实例(即非静态)方法的调用,在运行时实际调用的方法可能是其他一些覆盖这个方法的方法。
  • getCaller returns the Callable of which this call is syntactically part.
  • getCaller返回这个调用在语法上是其一部分的Callable。

For instance, in our example getCallee of the second call in Client.main would return Super.getX. At runtime, though, this call would actually invoke Sub.getX.

例如,在我们的例子中,Client.main中第二个调用的getCallee将返回Super.getX。但在运行时,这个调用实际上会调用Sub.getX。

Class Callable defines a large number of member predicates; for our purposes, the two most important ones are:

类Callable定义了大量的成员谓词;对于我们的目的,最重要的两个谓词是。

  • calls(Callable target) succeeds if this callable contains a call whose callee is target.
  • calls(Callable target)如果这个callable包含一个call,其calllee是target,则成功。
  • polyCalls(Callable target) succeeds if this callable may call target at runtime; this is the case if it contains a call whose callee is either target or a method that target overrides.
  • polyCalls(Callable target)如果这个callable在运行时可以调用target,那么就会成功;如果它包含一个call,其calllee是target或target覆盖的方法,那么就会成功。

In our example, Client.main calls the constructor Sub(int) and the method Super.getX; additionally, it polyCalls method Sub.getX.

在我们的例子中,Client.main调用了构造函数Sub(int)和方法Super.getX;此外,它还polyCalls方法Sub.getX。

Example: Finding unused methods

We can use the Callable class to write a query that finds methods that are not called by any other method:

我们可以使用Callable类来写一个查询,找到没有被其他方法调用的方法:

import java

from Callable callee
where not exists(Callable caller | caller.polyCalls(callee))
select callee

See this in the query console on LGTM.com. This simple query typically returns a large number of results.

➤ 在LGTM.com的查询控制台中可以看到。这种简单的查询通常会返回大量的结果。

image-20210325154446690

image-20210325154511712

Note

We have to use polyCalls instead of calls here: we want to be reasonably sure that callee is not called, either directly or via overriding.

我们必须在这里使用 polyCalls 而不是调用:我们要合理地确定 callee 没有被调用,无论是直接调用还是通过覆盖调用。

Running this query on a typical Java project results in lots of hits in the Java standard library. This makes sense, since no single client program uses every method of the standard library. More generally, we may want to exclude methods and constructors from compiled libraries. We can use the predicate fromSource to check whether a compilation unit is a source file, and refine our query:

在一个典型的Java项目上运行这个查询的结果是,在Java标准库中会有很多点击。这是有道理的,因为没有一个客户程序会使用标准库的每一个方法。更一般的情况下,我们可能希望从编译库中排除方法和构造函数。我们可以使用fromSource谓词来检查一个编译单元是否是源文件,并完善我们的查询:

import java

from Callable callee
where not exists(Callable caller | caller.polyCalls(callee)) and
    callee.getCompilationUnit().fromSource()
select callee, "Not called."

See this in the query console on LGTM.com. This change reduces the number of results returned for most projects.

➤ 在LGTM.com的查询控制台中可以看到。这个变化减少了大多数项目返回的结果数量。

image-20210325164432951

image-20210325164448392

image-20210325164454547

We might also notice several unused methods with the somewhat strange name <clinit>: these are class initializers; while they are not explicitly called anywhere in the code, they are called implicitly whenever the surrounding class is loaded. Hence it makes sense to exclude them from our query. While we are at it, we can also exclude finalizers, which are similarly invoked implicitly:

我们还可能会注意到几个未使用的方法,它们的名称有些奇怪:这些方法是类初始化器;虽然它们在代码中的任何地方都没有被显式调用,但每当加载周围的类时,它们就会被隐式调用。因此,将它们从我们的查询中排除是有意义的。当我们在这里的时候,我们也可以排除最终化器,它们同样是隐式调用的:

import java

from Callable callee
where not exists(Callable caller | caller.polyCalls(callee)) and
    callee.getCompilationUnit().fromSource() and
    not callee.hasName("<clinit>") and not callee.hasName("finalize")
select callee, "Not called."

See this in the query console on LGTM.com. This also reduces the number of results returned by most projects.

➤ 在LGTM.com的查询控制台中可以看到。这也减少了大多数项目返回的结果数量。

image-20210325164333796

image-20210325164401002

image-20210325164415230

We may also want to exclude public methods from our query, since they may be external API entry points:

我们可能还想从查询中排除公共方法,因为它们可能是外部 API 入口点:

import java

from Callable callee
where not exists(Callable caller | caller.polyCalls(callee)) and
    callee.getCompilationUnit().fromSource() and
    not callee.hasName("<clinit>") and not callee.hasName("finalize") and
    not callee.isPublic()
select callee, "Not called."

See this in the query console on LGTM.com. This should have a more noticeable effect on the number of results returned.

➤ 在LGTM.com的查询控制台中可以看到。这对返回的结果数量应该有比较明显的影响。

image-20210325164953331

image-20210325165015867

image-20210325165026661

A further special case is non-public default constructors: in the singleton pattern, for example, a class is provided with private empty default constructor to prevent it from being instantiated. Since the very purpose of such constructors is their not being called, they should not be flagged up:

还有一种特殊情况是非公共的默认构造函数:例如,在单子模式中,一个类提供了私有的空默认构造函数,以防止它被实例化。由于这类构造函数的目的就是它们不被调用,所以不应该将它们标记起来:

import java

from Callable callee
where not exists(Callable caller | caller.polyCalls(callee)) and
    callee.getCompilationUnit().fromSource() and
    not callee.hasName("<clinit>") and not callee.hasName("finalize") and
    not callee.isPublic() and
    not callee.(Constructor).getNumberOfParameters() = 0
select callee, "Not called."

See this in the query console on LGTM.com. This change has a large effect on the results for some projects but little effect on the results for others. Use of this pattern varies widely between different projects.

➤ 在LGTM.com的查询控制台中可以看到。这种变化对某些项目的结果影响很大,但对其他项目的结果影响不大。这种模式的使用在不同的项目之间差异很大。

image-20210325200248875

image-20210325165440723

image-20210325165446958

Finally, on many Java projects there are methods that are invoked indirectly by reflection. So, while there are no calls invoking these methods, they are, in fact, used. It is in general very hard to identify such methods. A very common special case, however, is JUnit test methods, which are reflectively invoked by a test runner. The CodeQL library for Java has support for recognizing test classes of JUnit and other testing frameworks, which we can employ to filter out methods defined in such classes:

最后,在许多Java项目上,有一些方法是通过反射间接调用的。因此,虽然没有调用这些方法,但事实上,它们是被使用的。在一般情况下,很难识别这些方法。然而,一个非常常见的特殊情况是JUnit测试方法,这些方法是由测试运行器反射性调用的。Java的CodeQL库支持识别JUnit和其他测试框架的测试类,我们可以采用它来过滤掉这些类中定义的方法:

import java

from Callable callee
where not exists(Callable caller | caller.polyCalls(callee)) and
    callee.getCompilationUnit().fromSource() and
    not callee.hasName("<clinit>") and not callee.hasName("finalize") and
    not callee.isPublic() and
    not callee.(Constructor).getNumberOfParameters() = 0 and
    not callee.getDeclaringType() instanceof TestClass
select callee, "Not called."

See this in the query console on LGTM.com. This should give a further reduction in the number of results returned.

➤ 在LGTM.com的查询控制台中可以看到。这应该会进一步减少返回结果的数量。

image-20210325165535738

image-20210325165551041

image-20210325165616137