Optimizing our Frida setup¶
When instrumenting applications it is not only important to optimize our instrumentation code for edge cases, but also optimizing the library that we are injecting in our target application.
Frida provides in its
config.mk file certain features that might not be needed in our agent, and this would help reduce the memory footprint of the injected agent. Among the features that can be disabled are:
- V8 Runtime
- Frida connectivity (TLS and ICE, OpenSSL)
- Frida Objective-C bridge
- Swift Bridge
- Java Bridge
To understand what percentege represents each of the components the following graph illustrates it:
Note: The representation of each component is done as of 03/10/2022 and might change in future releases, use this graph as a rough estimate only.
After seeing what can be easily disabled, it is time to decide what functionality is needed or not in our application. For example, when instrumenting Android applications the Swift and Objective-C runtime are not needed at all. If we have no use for V8 functionality, it is better to simply strip it from our agent and get a lighter version. On the other hand, when instrumenting applications in iOS the Java bridge is likely not needed.
For desktop applications outside of MacOS where the Obj-C brige is useful, all the functionality can be removed unless you want to instrument binaries using the V8 runtime. These optimizations vary on a per-case basis and should be considered in the later stages of instrumentation development.
As a result of these optimizations, when compiling an agent with no V8 runtime and no bridges the result are as follows:
optimized: 9.5M frida-agent.so
non-optimized: 24M frida-agent.so
9.5M vs 24M, this is roughly a 61% decrease in the size of the agent (and that's not counting other libraries such as frida-gadget). The biggest decrease of size in the agent is due to disabling the V8 runtime whereas the other features do not have such a big impact (but every byte counts).
The following table shows suggested settings for different target Operative Systems:
* in disabled means that you should enable if your use case requires it.
For a more detailed overview of Frida's memory footprint I recommend readying through frida.re/docs/footprint/.
Building an optimized Frida agent¶
In case that you are interested in building a custom agent by yourself, you can do so by cloning the Frida repository:
git clone --recurse-submodules https://github.com/frida/frida
Once you clone this repository, you will find a file named
config.mk inside with the following settings (among others):
FRIDA_V8 ?= enabled FRIDA_CONNECTIVITY ?= enabled FRIDA_DATABASE ?= enabled FRIDA_JAVA_BRIDGE ?= auto FRIDA_OBJC_BRIDGE ?= auto FRIDA_SWIFT_BRIDGE ?= auto
These are the default settings. It is possible to disable specific features by setting the
enabled flag to
disabled. For example, this would disable the Frida V8 Runtime:
FRIDA_V8 ?= disabled FRIDA_CONNECTIVITY ?= enabled FRIDA_DATABASE ?= enabled FRIDA_JAVA_BRIDGE ?= auto FRIDA_OBJC_BRIDGE ?= auto FRIDA_SWIFT_BRIDGE ?= auto