MCPcopy Index your code
hub / github.com/Guardsquare/proguard-core

github.com/Guardsquare/proguard-core @v9.3.2

Chat with this repo
repository ↗ · DeepWiki ↗ · release v9.3.2 ↗ · + Follow
11,766 symbols 33,725 edges 1,462 files 3,717 documented · 32% 1 cross-repo links
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

ProGuardCORE

A library to parse, modify and analyze Java class files.

Quick StartFeaturesProjectsContributingLicense

ProGuardCORE is a free library to read, analyze, modify, and write Java class files. It is the core of the well-known shrinker, optimizer, and obfuscator ProGuard, the ProGuard Assembler and Disassembler, and the Kotlin Metadata Printer.

Typical applications:

  • Read and write class files, including any Kotlin metadata.
  • Search for instruction patterns.
  • Create byte code instrumentation tools.
  • Analyze code with abstract evaluation.
  • Build static code analysis tools.
  • Optimize and obfuscate, like ProGuard itself.
  • ... and so much more!

ProGuard core comes with a short manual and pretty nice API documentation.

❓ Getting Help

Please use the issue tracker to report actual bugs 🐛, crashes, etc.

🚀 Quick Start

ProGuardCORE requires Java 1.8 or higher. You can download it as a pre-built artifact from:

Just add it to your project dependencies, e.g. Gradle:

dependencies {
    compile 'com.guardsquare:proguard-core:9.3.2'
}

or Maven:

<dependency>
    <groupId>com.guardsquare</groupId>
    <artifactId>proguard-core</artifactId>
    <version>9.3.2</version>
</dependency>

Building Locally

You can of course also clone and build this repository manually. Using Gradle, just execute the assemble task in the project root:

gradle clean assemble

✨ Features

The repository contains some sample code in the examples directory. Together with the complete set of manual pages they extensively cover the usage of the library and its features in more detail:

👉👉👉    Manual Pages    👈 👈 👈

Below we'll highlight just a few of them in order to better showcase the capabilities.

Creating classes programmatically (manual)

Using the fluent API, it becomes very easy to programmatically create classes from scratch. The data structures directly correspond to the bytecode specifications and ProGuardCORE can even preverify the code for you.

You can create classes, with fields, methods and sequences of instructions. The following concise code creates the iconic HelloWorld class:

ProgramClass programClass =
    new ClassBuilder(
        VersionConstants.CLASS_VERSION_1_8,
        AccessConstants.PUBLIC,
        "HelloWorld",
        ClassConstants.NAME_JAVA_LANG_OBJECT)
        .addMethod(
            AccessConstants.PUBLIC | AccessConstants.STATIC,
            "main",
            "([Ljava/lang/String;)V",
            50,
            code -> code
                .getstatic("java/lang/System", "out", "Ljava/io/PrintStream;")
                .ldc("Hello, world!")
                .invokevirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V")
                .return_())
        .getProgramClass();

Replacing instruction sequences (manual)

ProGuardCORE has an excellent instruction pattern matching engine, which can also replace matched bytecode instruction sequences.

For example, the snippet below defines an instruction sequence, including a wildcard, and replaces it with an equivalent instruction sequence, in all code attributes of all methods of all classes in a class pool.

Instruction[][] replacements =
{
    ____.putstatic(X)
        .getstatic(X).__(),
    ____.dup()
        .putstatic(X).__()
};
...
programClassPool.classesAccept(
    new AllMethodVisitor(
    new AllAttributeVisitor(
    new PeepholeEditor(branchTargetFinder, codeAttributeEditor,
    new InstructionSequenceReplacer(constants, replacements, branchTargetFinder,
                                    codeAttributeEditor)))));

Kotlin Metadata (manual)

The library makes it easy to read, write and modify the Kotlin metadata that is attached to Java classes. The following example prints all the names of Kotlin functions in the metadata attached to the Java class Foo:

programClassPool.classesAccept(
   new ClassNameFilter("Foo",
   new ReferencedKotlinMetadataVisitor(
   new AllFunctionsVisitor(
       (clazz, container, function) -> System.out.println(function.name)))));

Abstract Evaluation (manual)

ProGuardCORE provides a number of ways to analyze code. One of the most powerful techniques is abstract evaluation (closely related to symbolic execution). It executes the code, but instead of computing with concrete values it can compute with abstract values.

Consider the following getAnswer method:

private static int getAnswer(int a, int b)
{
    return 2 * a + b;
}

The table represents the bytecode instructions at their offsets, and the resulting evolving stacks and local variables. Each value slot has a numerical value and its origin (an instruction offset), presented as origin:value.

Instruction Stack v0 v1
[0] iconst_2 [0:2] P0:i0 P1:i1
[1] iload_0 v0 [0:2][1:i0] P0:i0 P1:i1
[2] imul [2:(2*i0)] P0:i0 P1:i1
[3] iload_1 v1 [2:(2*i0)] [3:i1] P0:i0 P1:i1
[4] iadd [4:((2*i0)+i1)] P0:i0 P1:i1
[5] ireturn P0:i0 P1:i1

At every point ProGuardCORE provides access to the symbolic expressions, or if possible and requested, the concrete results.

⚙️ Projects

Some of the projects using ProGuardCORE:

If you've created your own, make sure to reach out through github _ at _ guardsquare.com and we'll add it to the list!

🤝 Contributing

Contributions, issues and feature requests are welcome. Feel free to check the issues page and the contributing guide if you would like to contribute.

📝 License

Copyright (c) 2002-2022 Guardsquare NV. ProGuardCORE is released under the Apache 2 license.

Extension points exported contracts — how you extend this code

Transformer (Interface)
TODO DOC @author Panxiaobo @version $Rev$ [32 implementers]
android/src/main/java/proguard/dexfile/ir/ts/Transformer.java
KotlinModuleVisitor (Interface)
A visitor for KotlinModule. @author James Hamilton [12 implementers]
base/src/main/java/proguard/resources/kotlinmodule/visitor/KotlinModuleVisitor.java
DexAnnotationAble (Interface)
用于访问注解 @author Panxiaobo @version $Rev$ [37 implementers]
android/src/main/java/proguard/dexfile/reader/visitors/DexAnnotationAble.java
ResourceFileVisitor (Interface)
This interface specifies the methods for a visitor of ResourceFile instances. @author Johan Leys [14 implementers]
base/src/main/java/proguard/resources/file/visitor/ResourceFileVisitor.java
OnUseCallBack (Interface)
(no doc) [6 implementers]
android/src/main/java/proguard/dexfile/ir/ts/Cfg.java
KotlinAnnotatable (Interface)
Represents a Kotlin metadata entity that can contain annotations: - types - type parameters - type aliases Other [22 implementers]
base/src/main/java/proguard/classfile/kotlin/KotlinAnnotatable.java
OnAssignCallBack (Interface)
(no doc) [6 implementers]
android/src/main/java/proguard/dexfile/ir/ts/Cfg.java
CallableReferenceInfo (Interface)
Information about callable references. @author James Hamilton [8 implementers]
base/src/main/java/proguard/classfile/kotlin/reflect/CallableReferenceInfo.java

Core symbols most depended-on inside this repo

equals
called by 733
base/src/main/java/proguard/analysis/cpa/interfaces/AbstractState.java
getClass
called by 523
base/src/main/java/proguard/classfile/ClassPool.java
getName
called by 500
base/src/main/java/proguard/classfile/kotlin/reflect/CallableReferenceInfo.java
add
called by 494
base/src/main/java/proguard/analysis/cpa/interfaces/Waitlist.java
println
called by 373
base/src/main/java/proguard/io/DataEntryWriter.java
get
called by 351
base/src/main/java/proguard/analysis/cpa/bam/BamCache.java
fromSource
called by 290
base/src/testFixtures/kotlin/proguard/testutils/ClassPoolBuilder.kt
getName
called by 267
base/src/main/java/proguard/classfile/Clazz.java

Shape

Method 9,968
Class 1,539
Interface 152
Function 87
Enum 20

Languages

Java95%
Kotlin5%

Modules by API surface

base/src/main/java/proguard/classfile/editor/CompactCodeAttributeComposer.java252 symbols
base/src/main/java/proguard/classfile/editor/InstructionSequenceBuilder.java247 symbols
base/src/main/java/proguard/classfile/visitor/ClassPrinter.java115 symbols
base/src/main/java/proguard/classfile/io/ProgramClassWriter.java111 symbols
base/src/main/java/proguard/classfile/util/ClassReferenceInitializer.java110 symbols
base/src/main/java/proguard/classfile/io/kotlin/KotlinMetadataWriter.java110 symbols
base/src/main/java/proguard/classfile/editor/CodeAttributeEditor.java100 symbols
base/src/main/java/proguard/classfile/io/ProgramClassReader.java99 symbols
base/src/main/java/proguard/classfile/editor/ConstantPoolRemapper.java83 symbols
base/src/main/java/proguard/classfile/kotlin/KotlinAnnotationArgument.java82 symbols
base/src/main/java/proguard/classfile/editor/ConstantPoolShrinker.java78 symbols
base/src/main/java/proguard/classfile/util/ClassUtil.java77 symbols

Used by 1 indexed graphs manifest dependencies, hub-wide

For agents

$ claude mcp add proguard-core \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact