Lab 12
In this last lab sessions you will be practicing profiling, decompiling and obfuscation.
For the exercises in this last lab session, you will be working with
the PrimeChecker
project, available on GitLab.
Profiling
- Profiling is a reliable way of finding out which part of your code is responsible for factual resource consumption.
- In the context of this course we're mostly interested in sampling based techniques to measure which methods consume most CPU cycles.
Flame graphs with IntelliJ
- Flame graphs are a visual representation of CPU time, based on periodically polled call stacks.
- For better interpretability the stacks are sorted and tinted, resulting in a flame-like structure.
- IntelliJ has a built-in profiler, which automatically produces flame graphs from collected call stack samples.
Your turn
- Before anything can be profiled, we need a program that runs a bit longer than just a handful of method calls.
- Revisit the tests of the previously used
PrimeChecker
project and add a new test, that counts how many Prime Numbers exist below10000
. It should find1229
: - Instead of running the code with maven, use the
green triange
left of the test. Do not use a simple click, but a right-click, followed byProfile with IntelliJ profiler...
- The test will execute as usual, but intelliJ will show a popup: "Profiler data is ready" and an "Open" option.
- Before you continue, write down the test execution time, i.e. how many milliseconds it took to execute the test.
- Click on "Open". A flame graph will appear. Inspect the flame graph and identify which of your method calls (boxes in orange) consumes most resources.
- Navigate back to your production code. Several lines now showcase a flame symbol on the side.
- Inspect which lines are considered most consuming. You should find a single line that is responsible for the vast majority of CPU consumption.
- Where possible, try to optimize your code, by improving / removing time-consuming lines.
- Execute your code again: Compare the test duration to the one measured before. Validate there is a significant speedup.
Code decompiling
In class, you've seen an example of how to use the CFR
(Class File Reader) tool.
Class File Reader
- The CFR can be applied on any java bytecode. The easiest way to obtain sample bytecode to work with is by decompiling your own code.
- The CFR is free for download on the developer's website
Your turn
See if you can decompile one of your own Halma classes !
- Use
mvn clean package
to produce ajar
file. - Extract the contents of your
jar
file and find theclass
file for any non-trivial class, e.g. yourController
implementation. - Use CFR to decompile the
class
and reconstruct the.java
source code file. - Side by side compare your original source-code with the source code produced by the decompiler.
Use a visual comparison tool
icdiff
is a neat command line tool to quickly spot deltas between two files.
(Bonus: If you like recursion, try to decompile the decompiler with the decompiler!)
Code Obfuscation
Obfuscators are tools to mitigate the risk of code decompilation for unwanted or unauthorized code inspection.
ProGuard
- ProGuard is a free tool to replace (amongst others) all occurrences of variable names, by similar sounding, our visually similar identifiers.
- This way, once a software release is obfuscated, it can be hardly interpreted or reverse-engineered by a human.
- ProGuard is free to download on the project GitHub site.
Your Turn
- Obfuscate your own halma jar with ProGuard. A couple of things to keep in mind:
- You need a configuration file (see course material for a sample). Make sure to point to the correct launcher class (if the main method is obfuscated, your code cannot be executed any more).
- The ProGuard directly operates on a jar file. Make sure your initial halma jar file is operational.
- Try to decompile your jar.
- Extract the jar and find the class files.
- Decompile some class files with CFR.
- Compare the obfuscated code to the original source code.
- Verify your obfuscated jar file: it must be still operational.
- (Bonus: Add ProGuard to your
gitlab.ci
configuration, so thejar
file offered by GitLab'spages
job is always protected against de-compilation.)